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