1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifndef V8_CRANKSHAFT_X87_LITHIUM_CODEGEN_X87_H_ 6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define V8_CRANKSHAFT_X87_LITHIUM_CODEGEN_X87_H_ 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include <map> 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/scopes.h" 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/base/logging.h" 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/lithium-codegen.h" 13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/x87/lithium-gap-resolver-x87.h" 14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/crankshaft/x87/lithium-x87.h" 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/deoptimizer.h" 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/safepoint-table.h" 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/utils.h" 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Forward declarations. 23b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LDeferredCode; 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LGapNode; 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass SafepointGenerator; 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LCodeGen: public LCodeGenBase { 28b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 29b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info) 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : LCodeGenBase(chunk, assembler, info), 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch jump_table_(4, info->zone()), 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch scope_(info->scope()), 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch deferred_(8, info->zone()), 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch dynamic_frame_alignment_(false), 35b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch support_aligned_spilled_doubles_(false), 36b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch frame_is_built_(false), 37b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch x87_stack_(assembler), 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch safepoints_(info->zone()), 39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch resolver_(this), 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch expected_safepoint_kind_(Safepoint::kSimple) { 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PopulateDeoptimizationLiteralsWithInlinedFunctions(); 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int LookupDestination(int block_id) const { 45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return chunk()->LookupDestination(block_id); 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsNextEmittedBlock(int block_id) const { 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return LookupDestination(block_id) == GetNextEmittedBlock(); 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool NeedsEagerFrame() const { 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return GetStackSlotCount() > 0 || 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info()->is_non_deferred_calling() || 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !info()->IsStub() || 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch info()->requires_frame(); 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 58b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool NeedsDeferredFrame() const { 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return !NeedsEagerFrame() && info()->is_deferred_calling(); 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Support for converting LOperands to assembler types. 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand ToOperand(LOperand* op) const; 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register ToRegister(LOperand* op) const; 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X87Register ToX87Register(LOperand* op) const; 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsInteger32(LConstantOperand* op) const; 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool IsSmi(LConstantOperand* op) const; 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Immediate ToImmediate(LOperand* op, const Representation& r) const { 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Immediate(ToRepresentation(LConstantOperand::cast(op), r)); 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch double ToDouble(LConstantOperand* op) const; 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Support for non-sse2 (x87) floating point stack handling. 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // These functions maintain the mapping of physical stack registers to our 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // virtual registers between instructions. 77b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum X87OperandType { kX87DoubleOperand, kX87FloatOperand, kX87IntOperand }; 78b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 79b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void X87Mov(X87Register reg, Operand src, 80b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X87OperandType operand = kX87DoubleOperand); 81b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void X87Mov(Operand src, X87Register reg, 82b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X87OperandType operand = kX87DoubleOperand); 83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void X87Mov(X87Register reg, X87Register src, 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X87OperandType operand = kX87DoubleOperand); 85b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 86b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void X87PrepareBinaryOp( 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X87Register left, X87Register right, X87Register result); 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void X87LoadForUsage(X87Register reg); 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void X87LoadForUsage(X87Register reg1, X87Register reg2); 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void X87PrepareToWrite(X87Register reg) { x87_stack_.PrepareToWrite(reg); } 92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void X87CommitWrite(X87Register reg) { x87_stack_.CommitWrite(reg); } 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void X87Fxch(X87Register reg, int other_slot = 0) { 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch x87_stack_.Fxch(reg, other_slot); 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void X87Free(X87Register reg) { 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch x87_stack_.Free(reg); 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool X87StackEmpty() { 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return x87_stack_.depth() == 0; 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<Object> ToHandle(LConstantOperand* op) const; 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The operand denoting the second word (the one with a higher address) of 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // a double stack slot. 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand HighOperand(LOperand* op); 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Try to generate code for the entire chunk, but it may fail if the 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // chunk contains constructs we cannot handle. Returns true if the 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // code generation attempt succeeded. 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool GenerateCode(); 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Finish the code by setting stack height, safepoint, and bailout 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // information on it. 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void FinishCode(Handle<Code> code); 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Deferred code support. 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoDeferredNumberTagD(LNumberTagD* instr); 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 }; 125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoDeferredNumberTagIU(LInstruction* instr, 126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOperand* value, 127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOperand* temp, 128b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch IntegerSignedness signedness); 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoDeferredTaggedToI(LTaggedToI* instr, Label* done); 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr); 132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoDeferredStackCheck(LStackCheck* instr); 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DoDeferredMaybeGrowElements(LMaybeGrowElements* instr); 134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr); 135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoDeferredStringCharFromCode(LStringCharFromCode* instr); 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoDeferredAllocate(LAllocate* instr); 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoDeferredInstanceMigration(LCheckMaps* instr, Register object); 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr, 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register object, 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register index); 141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Parallel move support. 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoParallelMove(LParallelMove* move); 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoGap(LGap* instr); 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emit frame translation commands for an environment. 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void WriteTranslation(LEnvironment* environment, Translation* translation); 148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EnsureRelocSpaceForDeoptimization(); 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Declare methods that deal with the individual node types. 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DECLARE_DO(type) void Do##type(L##type* node); 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO) 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#undef DECLARE_DO 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LanguageMode language_mode() const { return info()->language_mode(); } 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* scope() const { return scope_; } 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EmitClassOfTest(Label* if_true, 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* if_false, 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Handle<String> class_name, 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register input, 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register temporary, 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register temporary2); 167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int GetStackSlotCount() const { return chunk()->spill_slot_count(); } 169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); } 171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Code generation passes. Returns true if code generation should 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // continue. 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void GenerateBodyInstructionPre(LInstruction* instr) override; 175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void GenerateBodyInstructionPost(LInstruction* instr) override; 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool GeneratePrologue(); 177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool GenerateDeferredCode(); 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool GenerateJumpTable(); 179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool GenerateSafepointTable(); 180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Generates the custom OSR entrypoint and sets the osr_pc_offset. 182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void GenerateOsrPrologue(); 183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch enum SafepointMode { 185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RECORD_SIMPLE_SAFEPOINT, 186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS 187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CallCode(Handle<Code> code, 190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode mode, 191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LInstruction* instr); 192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CallCodeGeneric(Handle<Code> code, 194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RelocInfo::Mode mode, 195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LInstruction* instr, 196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SafepointMode safepoint_mode); 197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CallRuntime(const Runtime::Function* fun, int argc, LInstruction* instr, 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SaveFPRegsMode save_doubles = kDontSaveFPRegs); 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CallRuntime(Runtime::FunctionId id, 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argc, 203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LInstruction* instr) { 204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const Runtime::Function* function = Runtime::FunctionForId(id); 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CallRuntime(function, argc, instr); 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void CallRuntime(Runtime::FunctionId id, LInstruction* instr) { 209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const Runtime::Function* function = Runtime::FunctionForId(id); 210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CallRuntime(function, function->nargs, instr); 211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CallRuntimeFromDeferred(Runtime::FunctionId id, 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int argc, 215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LInstruction* instr, 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOperand* context); 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void LoadContextFromDeferred(LOperand* context); 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Generate a direct call to a known function. Expects the function 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to be in edi. 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CallKnownFunction(Handle<JSFunction> function, 223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int formal_parameter_count, int arity, 224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LInstruction* instr); 225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 226b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordSafepointWithLazyDeopt(LInstruction* instr, 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SafepointMode safepoint_mode); 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RegisterEnvironmentForDeoptimization(LEnvironment* environment, 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Safepoint::DeoptMode mode); 231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DeoptimizeIf(Condition cc, LInstruction* instr, 232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Deoptimizer::DeoptReason deopt_reason, 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Deoptimizer::BailoutType bailout_type); 234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void DeoptimizeIf(Condition cc, LInstruction* instr, 235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Deoptimizer::DeoptReason deopt_reason); 236b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool DeoptEveryNTimes() { 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return FLAG_deopt_every_n_times != 0 && !info()->IsStub(); 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void AddToTranslation(LEnvironment* environment, 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Translation* translation, 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOperand* op, 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_tagged, 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_uint32, 246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int* object_index_pointer, 247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int* dematerialized_index_pointer); 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register ToRegister(int index) const; 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X87Register ToX87Register(int index) const; 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t ToRepresentation(LConstantOperand* op, const Representation& r) const; 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int32_t ToInteger32(LConstantOperand* op) const; 253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ExternalReference ToExternalReference(LConstantOperand* op) const; 254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand BuildFastArrayOperand(LOperand* elements_pointer, 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOperand* key, 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Representation key_representation, 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ElementsKind elements_kind, 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch uint32_t base_offset); 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Operand BuildSeqStringOperand(Register string, 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LOperand* index, 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch String::Encoding encoding); 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EmitIntegerMathAbs(LMathAbs* instr); 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Support for recording safepoint and position information. 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordSafepoint(LPointerMap* pointers, 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Safepoint::Kind kind, 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int arguments, 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Safepoint::DeoptMode mode); 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode); 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordSafepoint(Safepoint::DeoptMode mode); 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void RecordSafepointWithRegisters(LPointerMap* pointers, 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int arguments, 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Safepoint::DeoptMode mode); 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RecordAndWritePosition(int position) override; 279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch static Condition TokenToCondition(Token::Value op, bool is_unsigned); 281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EmitGoto(int block); 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // EmitBranch expects to be the last instruction of a block. 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template<class InstrType> 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EmitBranch(InstrType instr, Condition cc); 286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch template <class InstrType> 287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EmitTrueBranch(InstrType instr, Condition cc); 288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch template <class InstrType> 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EmitFalseBranch(InstrType instr, Condition cc); 290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EmitNumberUntagDNoSSE2(LNumberUntagD* instr, Register input, 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register temp, X87Register res_reg, 292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch NumberUntagDMode mode); 293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emits optimized code for typeof x == "y". Modifies input register. 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Returns the condition on which a final split to 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // true and false label should be made, to optimize fallthrough. 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition EmitTypeofIs(LTypeofIsAndBranch* instr, Register input); 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emits optimized code for %_IsString(x). Preserves input register. 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Returns the condition on which a final split to 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // true and false label should be made, to optimize fallthrough. 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Condition EmitIsString(Register input, 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register temp1, 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* is_not_string, 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SmiCheck check_needed); 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emits optimized code to deep-copy the contents of statically known 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // object graphs (e.g. object literal boilerplate). 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EmitDeepCopy(Handle<JSObject> object, 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register result, 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Register source, 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int* offset, 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocationSiteMode mode); 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EnsureSpaceForLazyDeopt(int space_needed) override; 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoLoadKeyedExternalArray(LLoadKeyed* instr); 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr); 318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoLoadKeyedFixedArray(LLoadKeyed* instr); 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoStoreKeyedExternalArray(LStoreKeyed* instr); 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr); 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void DoStoreKeyedFixedArray(LStoreKeyed* instr); 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch template <class T> 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EmitVectorLoadICRegisters(T* instr); 325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch template <class T> 326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void EmitVectorStoreICRegisters(T* instr); 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EmitReturn(LReturn* instr, bool dynamic_frame_alignment); 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Emits code for pushing either a tagged constant, a (non-double) 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // register, or a stack slot operand. 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EmitPushTaggedOperand(LOperand* operand); 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void X87Fld(Operand src, X87OperandType opts); 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void EmitFlushX87ForDeopt(); 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void FlushX87StackIfNecessary(LInstruction* instr) { 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch x87_stack_.FlushIfNecessary(instr, this); 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class LGapResolver; 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef _MSC_VER 343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // On windows, you may not access the stack more than one page below 344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the most recently mapped page. To make the allocated area randomly 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // accessible, we write an arbitrary value to each page in range 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // esp + offset - page_size .. esp in turn. 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void MakeSureStackPagesMapped(int offset); 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<Deoptimizer::JumpTableEntry> jump_table_; 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Scope* const scope_; 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ZoneList<LDeferredCode*> deferred_; 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool dynamic_frame_alignment_; 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool support_aligned_spilled_doubles_; 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool frame_is_built_; 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class X87Stack : public ZoneObject { 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit X87Stack(MacroAssembler* masm) 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : stack_depth_(0), is_mutable_(true), masm_(masm) { } 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit X87Stack(const X87Stack& other) 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : stack_depth_(other.stack_depth_), is_mutable_(false), masm_(masm()) { 363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < stack_depth_; i++) { 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stack_[i] = other.stack_[i]; 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool operator==(const X87Stack& other) const { 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (stack_depth_ != other.stack_depth_) return false; 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < stack_depth_; i++) { 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!stack_[i].is(other.stack_[i])) return false; 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X87Stack& operator=(const X87Stack& other) { 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stack_depth_ = other.stack_depth_; 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < stack_depth_; i++) { 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stack_[i] = other.stack_[i]; 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return *this; 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool Contains(X87Register reg); 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Fxch(X87Register reg, int other_slot = 0); 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Free(X87Register reg); 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void PrepareToWrite(X87Register reg); 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void CommitWrite(X87Register reg); 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void FlushIfNecessary(LInstruction* instr, LCodeGen* cgen); 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void LeavingBlock(int current_block_id, LGoto* goto_instr, LCodeGen* cgen); 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int depth() const { return stack_depth_; } 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int GetLayout(); 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int st(X87Register reg) { return st2idx(ArrayIndex(reg)); } 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void pop() { 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_mutable_); 393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch USE(is_mutable_); 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stack_depth_--; 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void push(X87Register reg) { 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(is_mutable_); 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(stack_depth_ < X87Register::kMaxNumAllocatableRegisters); 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stack_[stack_depth_] = reg; 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch stack_depth_++; 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MacroAssembler* masm() const { return masm_; } 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Isolate* isolate() const { return masm_->isolate(); } 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int ArrayIndex(X87Register reg); 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int st2idx(int pos); 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X87Register stack_[X87Register::kMaxNumAllocatableRegisters]; 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int stack_depth_; 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_mutable_; 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MacroAssembler* masm_; 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X87Stack x87_stack_; 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // block_id -> X87Stack*; 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch typedef std::map<int, X87Stack*> X87StackMap; 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch X87StackMap x87_stack_map_; 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Builder that keeps track of safepoints in the code. The table 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // itself is emitted at the end of the generated code. 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SafepointTableBuilder safepoints_; 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compiler from a set of parallel moves to a sequential list of moves. 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LGapResolver resolver_; 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Safepoint::Kind expected_safepoint_kind_; 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class PushSafepointRegistersScope final BASE_EMBEDDED { 430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit PushSafepointRegistersScope(LCodeGen* codegen) 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : codegen_(codegen) { 433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kSimple); 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch codegen_->masm_->PushSafepointRegisters(); 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch codegen_->expected_safepoint_kind_ = Safepoint::kWithRegisters; 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(codegen_->info()->is_calling()); 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ~PushSafepointRegistersScope() { 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters); 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch codegen_->masm_->PopSafepointRegisters(); 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch codegen_->expected_safepoint_kind_ = Safepoint::kSimple; 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LCodeGen* codegen_; 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch }; 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class LDeferredCode; 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class LEnvironment; 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class SafepointGenerator; 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch friend class X87Stack; 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(LCodeGen); 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass LDeferredCode : public ZoneObject { 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch explicit LDeferredCode(LCodeGen* codegen, const LCodeGen::X87Stack& x87_stack) 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : codegen_(codegen), 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch external_exit_(NULL), 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instruction_index_(codegen->current_instruction_), 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch x87_stack_(x87_stack) { 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch codegen->AddDeferredCode(this); 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual ~LDeferredCode() {} 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual void Generate() = 0; 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch virtual LInstruction* instr() = 0; 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void SetExit(Label* exit) { external_exit_ = exit; } 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* entry() { return &entry_; } 473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; } 474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* done() { return codegen_->NeedsDeferredFrame() ? &done_ : exit(); } 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int instruction_index() const { return instruction_index_; } 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const LCodeGen::X87Stack& x87_stack() const { return x87_stack_; } 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected: 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LCodeGen* codegen() const { return codegen_; } 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MacroAssembler* masm() const { return codegen_->masm(); } 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LCodeGen* codegen_; 484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label entry_; 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label exit_; 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label* external_exit_; 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Label done_; 488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int instruction_index_; 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LCodeGen::X87Stack x87_stack_; 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace internal 493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch} // namespace v8 494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif // V8_CRANKSHAFT_X87_LITHIUM_CODEGEN_X87_H_ 496