1f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// Copyright 2013 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 4f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 5fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org#ifndef V8_ARM64_LITHIUM_CODEGEN_ARM64_H_ 6fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org#define V8_ARM64_LITHIUM_CODEGEN_ARM64_H_ 7f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/arm64/lithium-arm64.h" 9f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/arm64/lithium-gap-resolver-arm64.h" 11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/deoptimizer.h" 12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/lithium-codegen.h" 13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/safepoint-table.h" 14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/scopes.h" 15196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/utils.h" 16f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 17f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgnamespace v8 { 18f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgnamespace internal { 19f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 20f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// Forward declarations. 21f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgclass LDeferredCode; 22f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgclass SafepointGenerator; 23f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgclass BranchGenerator; 24f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 25f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgclass LCodeGen: public LCodeGenBase { 26f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org public: 27f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info) 28f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org : LCodeGenBase(chunk, assembler, info), 29f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org deoptimizations_(4, info->zone()), 30a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org jump_table_(4, info->zone()), 31f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org deoptimization_literals_(8, info->zone()), 32f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org inlined_function_count_(0), 33f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org scope_(info->scope()), 34f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org translations_(info->zone()), 35f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org deferred_(8, info->zone()), 36f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org osr_pc_offset_(-1), 37f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org frame_is_built_(false), 38f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org safepoints_(info->zone()), 39f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org resolver_(this), 40a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org expected_safepoint_kind_(Safepoint::kSimple), 41a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org after_push_argument_(false), 42a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org inlined_arguments_(false) { 43f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org PopulateDeoptimizationLiteralsWithInlinedFunctions(); 44f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 45f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 46a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org ~LCodeGen() { 47e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(!after_push_argument_ || inlined_arguments_); 48a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org } 49a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 50f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Simple accessors. 51f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Scope* scope() const { return scope_; } 52f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 53f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int LookupDestination(int block_id) const { 54f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return chunk()->LookupDestination(block_id); 55f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 56f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 57f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool IsNextEmittedBlock(int block_id) const { 58f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return LookupDestination(block_id) == GetNextEmittedBlock(); 59f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 60f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 61f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool NeedsEagerFrame() const { 62f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return GetStackSlotCount() > 0 || 63f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org info()->is_non_deferred_calling() || 64f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org !info()->IsStub() || 65f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org info()->requires_frame(); 66f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 67f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool NeedsDeferredFrame() const { 68f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return !NeedsEagerFrame() && info()->is_deferred_calling(); 69f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 70f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 71f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LinkRegisterStatus GetLinkRegisterState() const { 72f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org return frame_is_built_ ? kLRHasBeenSaved : kLRHasNotBeenSaved; 73f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 74f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 75f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Try to generate code for the entire chunk, but it may fail if the 76f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // chunk contains constructs we cannot handle. Returns true if the 77f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // code generation attempt succeeded. 78f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool GenerateCode(); 79f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 80f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Finish the code by setting stack height, safepoint, and bailout 81f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // information on it. 82f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void FinishCode(Handle<Code> code); 83f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 845924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 }; 85f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Support for converting LOperands to assembler types. 86f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Register ToRegister(LOperand* op) const; 87f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Register ToRegister32(LOperand* op) const; 88f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Operand ToOperand(LOperand* op); 897dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org Operand ToOperand32(LOperand* op); 90a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org enum StackMode { kMustUseFramePointer, kCanUseStackPointer }; 91a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org MemOperand ToMemOperand(LOperand* op, 92a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org StackMode stack_mode = kCanUseStackPointer) const; 93f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Handle<Object> ToHandle(LConstantOperand* op) const; 94f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 957dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org template <class LI> 967dae5b9f8500ada1f217a27db8a1f5c62becd404machenbach@chromium.org Operand ToShiftedRightOperand32(LOperand* right, LI* shift_info); 975924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org 985924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org int JSShiftAmountFromLConstant(LOperand* constant) { 995924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org return ToInteger32(LConstantOperand::cast(constant)) & 0x1f; 1005924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org } 1015924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org 102f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // TODO(jbramley): Examine these helpers and check that they make sense. 103f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // IsInteger32Constant returns true for smi constants, for example. 104f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool IsInteger32Constant(LConstantOperand* op) const; 105f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool IsSmi(LConstantOperand* op) const; 106f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 107f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int32_t ToInteger32(LConstantOperand* op) const; 108f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Smi* ToSmi(LConstantOperand* op) const; 109f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org double ToDouble(LConstantOperand* op) const; 110f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org DoubleRegister ToDoubleRegister(LOperand* op) const; 111f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 112f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Declare methods that deal with the individual node types. 113f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#define DECLARE_DO(type) void Do##type(L##type* node); 114f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO) 115f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org#undef DECLARE_DO 116f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 117f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org private: 118f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Return a double scratch register which can be used locally 119f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // when generating code for a lithium instruction. 120f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org DoubleRegister double_scratch() { return crankshaft_fp_scratch; } 121f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 122f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Deferred code support. 123f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void DoDeferredNumberTagD(LNumberTagD* instr); 124f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void DoDeferredStackCheck(LStackCheck* instr); 125f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr); 126f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void DoDeferredStringCharFromCode(LStringCharFromCode* instr); 127f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void DoDeferredMathAbsTagged(LMathAbsTagged* instr, 128f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Label* exit, 129f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Label* allocation_entry); 130f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 131f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void DoDeferredNumberTagU(LInstruction* instr, 132f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LOperand* value, 133f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LOperand* temp1, 134f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LOperand* temp2); 135f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void DoDeferredTaggedToI(LTaggedToI* instr, 136f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LOperand* value, 137f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LOperand* temp1, 138f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LOperand* temp2); 139f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void DoDeferredAllocate(LAllocate* instr); 140f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr); 141f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void DoDeferredInstanceMigration(LCheckMaps* instr, Register object); 14263a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org void DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr, 14363a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org Register result, 14463a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org Register object, 14563a7c9f848e755c52a37721debae242cf5d1682dmachenbach@chromium.org Register index); 146f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 147f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org static Condition TokenToCondition(Token::Value op, bool is_unsigned); 148f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void EmitGoto(int block); 149f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void DoGap(LGap* instr); 150f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 151f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Generic version of EmitBranch. It contains some code to avoid emitting a 152f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // branch on the next emitted basic block where we could just fall-through. 153f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // You shouldn't use that directly but rather consider one of the helper like 154f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // LCodeGen::EmitBranch, LCodeGen::EmitCompareAndBranch... 155f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org template<class InstrType> 156f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void EmitBranchGeneric(InstrType instr, 157f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org const BranchGenerator& branch); 158f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 159f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org template<class InstrType> 160f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void EmitBranch(InstrType instr, Condition condition); 161f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 162f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org template<class InstrType> 163f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void EmitCompareAndBranch(InstrType instr, 164f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Condition condition, 165f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org const Register& lhs, 166f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org const Operand& rhs); 167f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 168f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org template<class InstrType> 169f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void EmitTestAndBranch(InstrType instr, 170f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Condition condition, 171f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org const Register& value, 172f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org uint64_t mask); 173f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 174f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org template<class InstrType> 175f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void EmitBranchIfNonZeroNumber(InstrType instr, 176f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org const FPRegister& value, 177f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org const FPRegister& scratch); 178f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 179f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org template<class InstrType> 180f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void EmitBranchIfHeapNumber(InstrType instr, 181f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org const Register& value); 182f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 183f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org template<class InstrType> 184f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void EmitBranchIfRoot(InstrType instr, 185f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org const Register& value, 186f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Heap::RootListIndex index); 187f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 188f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Emits optimized code to deep-copy the contents of statically known object 189f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // graphs (e.g. object literal boilerplate). Expects a pointer to the 190f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // allocated destination object in the result register, and a pointer to the 191f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // source object in the source register. 192f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void EmitDeepCopy(Handle<JSObject> object, 193f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Register result, 194f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Register source, 195f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Register scratch, 196f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int* offset, 197f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org AllocationSiteMode mode); 198f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 1996474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org template <class T> 2006474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org void EmitVectorLoadICRegisters(T* instr); 2016474a1cfee1cdad45de5cc96960085e1c7daf11cmachenbach@chromium.org 202f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Emits optimized code for %_IsString(x). Preserves input register. 203f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Returns the condition on which a final split to 204f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // true and false label should be made, to optimize fallthrough. 205f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Condition EmitIsString(Register input, Register temp1, Label* is_not_string, 206f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SmiCheck check_needed); 207f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 208f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int DefineDeoptimizationLiteral(Handle<Object> literal); 209f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void PopulateDeoptimizationData(Handle<Code> code); 210f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void PopulateDeoptimizationLiteralsWithInlinedFunctions(); 211f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 212f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org MemOperand BuildSeqStringOperand(Register string, 213f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Register temp, 214f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LOperand* index, 215f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org String::Encoding encoding); 21606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org void DeoptimizeBranch(LInstruction* instr, const char* detail, 217a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org BranchType branch_type, Register reg = NoReg, 218a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org int bit = -1, 219a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Deoptimizer::BailoutType* override_bailout_type = NULL); 220a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void Deoptimize(LInstruction* instr, 221a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org Deoptimizer::BailoutType* override_bailout_type = NULL, 22206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org const char* detail = NULL); 223a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void DeoptimizeIf(Condition cond, LInstruction* instr, 22406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org const char* detail = NULL); 225a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void DeoptimizeIfZero(Register rt, LInstruction* instr, 22606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org const char* detail = NULL); 227a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void DeoptimizeIfNotZero(Register rt, LInstruction* instr, 22806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org const char* detail = NULL); 229a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void DeoptimizeIfNegative(Register rt, LInstruction* instr, 23006b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org const char* detail = NULL); 231a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void DeoptimizeIfSmi(Register rt, LInstruction* instr, 23206b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org const char* detail = NULL); 233a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void DeoptimizeIfNotSmi(Register rt, LInstruction* instr, 23406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org const char* detail = NULL); 235a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void DeoptimizeIfRoot(Register rt, Heap::RootListIndex index, 23606b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org LInstruction* instr, const char* detail = NULL); 237a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void DeoptimizeIfNotRoot(Register rt, Heap::RootListIndex index, 23806b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org LInstruction* instr, const char* detail = NULL); 239b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org void DeoptimizeIfNotHeapNumber(Register object, LInstruction* instr); 240a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void DeoptimizeIfMinusZero(DoubleRegister input, LInstruction* instr, 24106b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org const char* detail = NULL); 242a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void DeoptimizeIfBitSet(Register rt, int bit, LInstruction* instr, 24306b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org const char* detail = NULL); 244a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org void DeoptimizeIfBitClear(Register rt, int bit, LInstruction* instr, 24506b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org const char* detail = NULL); 246f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 247f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org MemOperand PrepareKeyedExternalArrayOperand(Register key, 248f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Register base, 249f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Register scratch, 250f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool key_is_smi, 251f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool key_is_constant, 252f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int constant_key, 253f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ElementsKind elements_kind, 254fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org int base_offset); 2555924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org MemOperand PrepareKeyedArrayOperand(Register base, 2565924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org Register elements, 2575924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org Register key, 2585924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org bool key_is_tagged, 2595924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org ElementsKind elements_kind, 2605924917d324a643d00a8aefee030bd4acea0de0bmachenbach@chromium.org Representation representation, 261fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org int base_offset); 262f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 263f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void RegisterEnvironmentForDeoptimization(LEnvironment* environment, 264f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Safepoint::DeoptMode mode); 265f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 266f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int GetStackSlotCount() const { return chunk()->spill_slot_count(); } 267f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 268f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); } 269f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 270f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Emit frame translation commands for an environment. 271f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void WriteTranslation(LEnvironment* environment, Translation* translation); 272f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 273f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void AddToTranslation(LEnvironment* environment, 274f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Translation* translation, 275f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LOperand* op, 276f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool is_tagged, 277f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool is_uint32, 278f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int* object_index_pointer, 279f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int* dematerialized_index_pointer); 280f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 281f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void SaveCallerDoubles(); 282f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void RestoreCallerDoubles(); 283f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 284f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Code generation steps. Returns true if code generation should continue. 285ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org void GenerateBodyInstructionPre(LInstruction* instr) OVERRIDE; 286f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool GeneratePrologue(); 287f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool GenerateDeferredCode(); 288a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org bool GenerateJumpTable(); 289f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool GenerateSafepointTable(); 290f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 291f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Generates the custom OSR entrypoint and sets the osr_pc_offset. 292f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void GenerateOsrPrologue(); 293f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 294f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org enum SafepointMode { 295f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org RECORD_SIMPLE_SAFEPOINT, 296f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS 297f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org }; 298f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 299f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void CallCode(Handle<Code> code, 300f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org RelocInfo::Mode mode, 301f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LInstruction* instr); 302f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 303f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void CallCodeGeneric(Handle<Code> code, 304f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org RelocInfo::Mode mode, 305f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LInstruction* instr, 306f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SafepointMode safepoint_mode); 307f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 308f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void CallRuntime(const Runtime::Function* function, 309f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int num_arguments, 310f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LInstruction* instr, 311f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SaveFPRegsMode save_doubles = kDontSaveFPRegs); 312f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 313f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void CallRuntime(Runtime::FunctionId id, 314f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int num_arguments, 315f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LInstruction* instr) { 316f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org const Runtime::Function* function = Runtime::FunctionForId(id); 317f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org CallRuntime(function, num_arguments, instr); 318f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 319f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 320f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void LoadContextFromDeferred(LOperand* context); 321f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void CallRuntimeFromDeferred(Runtime::FunctionId id, 322f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int argc, 323f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LInstruction* instr, 324f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LOperand* context); 325f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 326f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Generate a direct call to a known function. 327f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // If the function is already loaded into x1 by the caller, function_reg may 328f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // be set to x1. Otherwise, it must be NoReg, and CallKnownFunction will 329f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // automatically load it. 330f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void CallKnownFunction(Handle<JSFunction> function, 331f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int formal_parameter_count, 332f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int arity, 333f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LInstruction* instr, 334f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Register function_reg = NoReg); 335f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 336f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Support for recording safepoint and position information. 337ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org void RecordAndWritePosition(int position) OVERRIDE; 338f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void RecordSafepoint(LPointerMap* pointers, 339f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Safepoint::Kind kind, 340f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int arguments, 341f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Safepoint::DeoptMode mode); 342f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode); 343f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void RecordSafepoint(Safepoint::DeoptMode mode); 344f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void RecordSafepointWithRegisters(LPointerMap* pointers, 345f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int arguments, 346f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Safepoint::DeoptMode mode); 347f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void RecordSafepointWithLazyDeopt(LInstruction* instr, 348f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SafepointMode safepoint_mode); 349f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 350ada3a6017e603965f87fa34f6e2fa60379e8d697machenbach@chromium.org void EnsureSpaceForLazyDeopt(int space_needed) OVERRIDE; 351f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 352f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ZoneList<LEnvironment*> deoptimizations_; 353a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org ZoneList<Deoptimizer::JumpTableEntry*> jump_table_; 354f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ZoneList<Handle<Object> > deoptimization_literals_; 355f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int inlined_function_count_; 356f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Scope* const scope_; 357f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org TranslationBuffer translations_; 358f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ZoneList<LDeferredCode*> deferred_; 359f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int osr_pc_offset_; 360f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org bool frame_is_built_; 361f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 362f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Builder that keeps track of safepoints in the code. The table itself is 363f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // emitted at the end of the generated code. 364f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org SafepointTableBuilder safepoints_; 365f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 366f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org // Compiler from a set of parallel moves to a sequential list of moves. 367f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LGapResolver resolver_; 368f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 369f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Safepoint::Kind expected_safepoint_kind_; 370f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 371a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // This flag is true when we are after a push (but before a call). 372a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // In this situation, jssp no longer references the end of the stack slots so, 373a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // we can only reference a stack slot via fp. 374a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org bool after_push_argument_; 375a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // If we have inlined arguments, we are no longer able to use jssp because 376a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // jssp is modified and we never know if we are in a block after or before 377a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org // the pop of the arguments (which restores jssp). 378a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org bool inlined_arguments_; 379a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org 380f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int old_position_; 381f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 382f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org class PushSafepointRegistersScope BASE_EMBEDDED { 383f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org public: 3849d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org explicit PushSafepointRegistersScope(LCodeGen* codegen) 385f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org : codegen_(codegen) { 386e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(codegen_->info()->is_calling()); 387e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kSimple); 3889d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org codegen_->expected_safepoint_kind_ = Safepoint::kWithRegisters; 389f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 390a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org UseScratchRegisterScope temps(codegen_->masm_); 391a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org // Preserve the value of lr which must be saved on the stack (the call to 392a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org // the stub will clobber it). 393a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org Register to_be_pushed_lr = 394a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org temps.UnsafeAcquire(StoreRegistersStateStub::to_be_pushed_lr()); 395a221880197f38ff22d942851060daffa5d036bdfmachenbach@chromium.org codegen_->masm_->Mov(to_be_pushed_lr, lr); 3969d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org StoreRegistersStateStub stub(codegen_->isolate()); 3979d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org codegen_->masm_->CallStub(&stub); 398f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 399f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 400f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org ~PushSafepointRegistersScope() { 401e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters); 4029d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org RestoreRegistersStateStub stub(codegen_->isolate()); 4039d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org codegen_->masm_->CallStub(&stub); 404f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org codegen_->expected_safepoint_kind_ = Safepoint::kSimple; 405f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 406f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 407f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org private: 408f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LCodeGen* codegen_; 409f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org }; 410f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 411f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org friend class LDeferredCode; 412f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org friend class SafepointGenerator; 413f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org DISALLOW_COPY_AND_ASSIGN(LCodeGen); 414f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}; 415f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 416f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 417f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgclass LDeferredCode: public ZoneObject { 418f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org public: 419f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org explicit LDeferredCode(LCodeGen* codegen) 420f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org : codegen_(codegen), 421f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org external_exit_(NULL), 422f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org instruction_index_(codegen->current_instruction_) { 423f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org codegen->AddDeferredCode(this); 424f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org } 425f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 426f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org virtual ~LDeferredCode() { } 427f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org virtual void Generate() = 0; 428f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org virtual LInstruction* instr() = 0; 429f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 430f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org void SetExit(Label* exit) { external_exit_ = exit; } 431f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Label* entry() { return &entry_; } 432f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Label* exit() { return (external_exit_ != NULL) ? external_exit_ : &exit_; } 433f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int instruction_index() const { return instruction_index_; } 434f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 435f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org protected: 436f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LCodeGen* codegen() const { return codegen_; } 437f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org MacroAssembler* masm() const { return codegen_->masm(); } 438f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 439f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org private: 440f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LCodeGen* codegen_; 441f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Label entry_; 442f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Label exit_; 443f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org Label* external_exit_; 444f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org int instruction_index_; 445f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}; 446f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 447f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 448f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// This is the abstract class used by EmitBranchGeneric. 449f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// It is used to emit code for conditional branching. The Emit() function 450f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// emits code to branch when the condition holds and EmitInverted() emits 451f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// the branch when the inverted condition is verified. 452f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// 453f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org// For actual examples of condition see the concrete implementation in 454fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org// lithium-codegen-arm64.cc (e.g. BranchOnCondition, CompareAndBranch). 455f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgclass BranchGenerator BASE_EMBEDDED { 456f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org public: 457f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org explicit BranchGenerator(LCodeGen* codegen) 458f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org : codegen_(codegen) { } 459f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 460f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org virtual ~BranchGenerator() { } 461f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 462f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org virtual void Emit(Label* label) const = 0; 463f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org virtual void EmitInverted(Label* label) const = 0; 464f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 465f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org protected: 466f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org MacroAssembler* masm() const { return codegen_->masm(); } 467f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 468f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org LCodeGen* codegen_; 469f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org}; 470f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 471f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org} } // namespace v8::internal 472f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org 473fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org#endif // V8_ARM64_LITHIUM_CODEGEN_ARM64_H_ 474