blob: adb6e1bb73e4ad6f70f4bc857e79968dfa4b7a32 [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 the V8 project authors. All rights reserved.
Ben Murdochb0fe1622011-05-05 13:52:32 +01002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_ARM_LITHIUM_CODEGEN_ARM_H_
29#define V8_ARM_LITHIUM_CODEGEN_ARM_H_
30
31#include "arm/lithium-arm.h"
Ben Murdoche0cee9b2011-05-25 10:26:03 +010032#include "arm/lithium-gap-resolver-arm.h"
Ben Murdochb0fe1622011-05-05 13:52:32 +010033#include "deoptimizer.h"
34#include "safepoint-table.h"
35#include "scopes.h"
36
37namespace v8 {
38namespace internal {
39
40// Forward declarations.
41class LDeferredCode;
42class SafepointGenerator;
43
Ben Murdochb0fe1622011-05-05 13:52:32 +010044class LCodeGen BASE_EMBEDDED {
45 public:
46 LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
47 : chunk_(chunk),
48 masm_(assembler),
49 info_(info),
50 current_block_(-1),
51 current_instruction_(-1),
52 instructions_(chunk->instructions()),
53 deoptimizations_(4),
Ben Murdoch257744e2011-11-30 15:57:28 +000054 deopt_jump_table_(4),
Ben Murdochb0fe1622011-05-05 13:52:32 +010055 deoptimization_literals_(8),
56 inlined_function_count_(0),
Ben Murdoche0cee9b2011-05-25 10:26:03 +010057 scope_(info->scope()),
Ben Murdochb0fe1622011-05-05 13:52:32 +010058 status_(UNUSED),
59 deferred_(8),
Ben Murdoche0cee9b2011-05-25 10:26:03 +010060 osr_pc_offset_(-1),
Ben Murdoch2b4ba112012-01-20 14:57:15 +000061 last_lazy_deopt_pc_(0),
Ben Murdoch8b112d22011-06-08 16:22:53 +010062 resolver_(this),
63 expected_safepoint_kind_(Safepoint::kSimple) {
Ben Murdochb0fe1622011-05-05 13:52:32 +010064 PopulateDeoptimizationLiteralsWithInlinedFunctions();
65 }
66
Ben Murdoche0cee9b2011-05-25 10:26:03 +010067
68 // Simple accessors.
69 MacroAssembler* masm() const { return masm_; }
70 CompilationInfo* info() const { return info_; }
Steve Block44f0eee2011-05-26 01:26:41 +010071 Isolate* isolate() const { return info_->isolate(); }
72 Factory* factory() const { return isolate()->factory(); }
73 Heap* heap() const { return isolate()->heap(); }
Ben Murdoche0cee9b2011-05-25 10:26:03 +010074
75 // Support for converting LOperands to assembler types.
76 // LOperand must be a register.
77 Register ToRegister(LOperand* op) const;
78
79 // LOperand is loaded into scratch, unless already a register.
80 Register EmitLoadRegister(LOperand* op, Register scratch);
81
82 // LOperand must be a double register.
83 DoubleRegister ToDoubleRegister(LOperand* op) const;
84
85 // LOperand is loaded into dbl_scratch, unless already a double register.
86 DoubleRegister EmitLoadDoubleRegister(LOperand* op,
87 SwVfpRegister flt_scratch,
88 DoubleRegister dbl_scratch);
89 int ToInteger32(LConstantOperand* op) const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +010090 double ToDouble(LConstantOperand* op) const;
Ben Murdoche0cee9b2011-05-25 10:26:03 +010091 Operand ToOperand(LOperand* op);
92 MemOperand ToMemOperand(LOperand* op) const;
93 // Returns a MemOperand pointing to the high word of a DoubleStackSlot.
94 MemOperand ToHighMemOperand(LOperand* op) const;
95
Ben Murdoch3ef787d2012-04-12 10:51:47 +010096 bool IsInteger32(LConstantOperand* op) const;
97 Handle<Object> ToHandle(LConstantOperand* op) const;
98
Ben Murdochb0fe1622011-05-05 13:52:32 +010099 // Try to generate code for the entire chunk, but it may fail if the
100 // chunk contains constructs we cannot handle. Returns true if the
101 // code generation attempt succeeded.
102 bool GenerateCode();
103
104 // Finish the code by setting stack height, safepoint, and bailout
105 // information on it.
106 void FinishCode(Handle<Code> code);
107
108 // Deferred code support.
Steve Block1e0659c2011-05-24 12:43:12 +0100109 template<int T>
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100110 void DoDeferredBinaryOpStub(LTemplateInstruction<1, 2, T>* instr,
111 Token::Value op);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100112 void DoDeferredNumberTagD(LNumberTagD* instr);
113 void DoDeferredNumberTagI(LNumberTagI* instr);
114 void DoDeferredTaggedToI(LTaggedToI* instr);
115 void DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000116 void DoDeferredStackCheck(LStackCheck* instr);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100117 void DoDeferredRandom(LRandom* instr);
Steve Block1e0659c2011-05-24 12:43:12 +0100118 void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
Steve Block44f0eee2011-05-26 01:26:41 +0100119 void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100120 void DoDeferredAllocateObject(LAllocateObject* instr);
Ben Murdoch2b4ba112012-01-20 14:57:15 +0000121 void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
122 Label* map_check);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100123
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100124 void DoCheckMapCommon(Register reg, Register scratch, Handle<Map> map,
125 CompareMapMode mode, LEnvironment* env);
126
Ben Murdochb0fe1622011-05-05 13:52:32 +0100127 // Parallel move support.
128 void DoParallelMove(LParallelMove* move);
Ben Murdoch257744e2011-11-30 15:57:28 +0000129 void DoGap(LGap* instr);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100130
Ben Murdochb8e0da22011-05-16 14:20:40 +0100131 // Emit frame translation commands for an environment.
132 void WriteTranslation(LEnvironment* environment, Translation* translation);
133
Ben Murdochb0fe1622011-05-05 13:52:32 +0100134 // Declare methods that deal with the individual node types.
135#define DECLARE_DO(type) void Do##type(L##type* node);
136 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
137#undef DECLARE_DO
138
139 private:
140 enum Status {
141 UNUSED,
142 GENERATING,
143 DONE,
144 ABORTED
145 };
146
147 bool is_unused() const { return status_ == UNUSED; }
148 bool is_generating() const { return status_ == GENERATING; }
149 bool is_done() const { return status_ == DONE; }
150 bool is_aborted() const { return status_ == ABORTED; }
151
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100152 StrictModeFlag strict_mode_flag() const {
153 return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100154 }
155
Ben Murdochb0fe1622011-05-05 13:52:32 +0100156 LChunk* chunk() const { return chunk_; }
157 Scope* scope() const { return scope_; }
158 HGraph* graph() const { return chunk_->graph(); }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100159
Steve Block9fac8402011-05-12 15:51:54 +0100160 Register scratch0() { return r9; }
Ben Murdoch692be652012-01-10 18:47:50 +0000161 DwVfpRegister double_scratch0() { return kScratchDoubleReg; }
Steve Block9fac8402011-05-12 15:51:54 +0100162
Ben Murdochb0fe1622011-05-05 13:52:32 +0100163 int GetNextEmittedBlock(int block);
164 LInstruction* GetNextInstruction();
165
166 void EmitClassOfTest(Label* if_true,
167 Label* if_false,
168 Handle<String> class_name,
169 Register input,
170 Register temporary,
171 Register temporary2);
172
Ben Murdoch257744e2011-11-30 15:57:28 +0000173 int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
174 int GetParameterCount() const { return scope()->num_parameters(); }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100175
176 void Abort(const char* format, ...);
177 void Comment(const char* format, ...);
178
179 void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code); }
180
181 // Code generation passes. Returns true if code generation should
182 // continue.
183 bool GeneratePrologue();
184 bool GenerateBody();
185 bool GenerateDeferredCode();
Ben Murdoch257744e2011-11-30 15:57:28 +0000186 bool GenerateDeoptJumpTable();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100187 bool GenerateSafepointTable();
188
Ben Murdoch8b112d22011-06-08 16:22:53 +0100189 enum SafepointMode {
190 RECORD_SIMPLE_SAFEPOINT,
191 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS
192 };
193
Ben Murdochb0fe1622011-05-05 13:52:32 +0100194 void CallCode(Handle<Code> code,
195 RelocInfo::Mode mode,
196 LInstruction* instr);
Ben Murdoch8b112d22011-06-08 16:22:53 +0100197
198 void CallCodeGeneric(Handle<Code> code,
199 RelocInfo::Mode mode,
200 LInstruction* instr,
201 SafepointMode safepoint_mode);
202
Steve Block44f0eee2011-05-26 01:26:41 +0100203 void CallRuntime(const Runtime::Function* function,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100204 int num_arguments,
205 LInstruction* instr);
Ben Murdoch8b112d22011-06-08 16:22:53 +0100206
Ben Murdochb0fe1622011-05-05 13:52:32 +0100207 void CallRuntime(Runtime::FunctionId id,
208 int num_arguments,
209 LInstruction* instr) {
Steve Block44f0eee2011-05-26 01:26:41 +0100210 const Runtime::Function* function = Runtime::FunctionForId(id);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100211 CallRuntime(function, num_arguments, instr);
212 }
213
Ben Murdoch8b112d22011-06-08 16:22:53 +0100214 void CallRuntimeFromDeferred(Runtime::FunctionId id,
215 int argc,
216 LInstruction* instr);
217
Ben Murdochb0fe1622011-05-05 13:52:32 +0100218 // Generate a direct call to a known function. Expects the function
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100219 // to be in r1.
Ben Murdochb0fe1622011-05-05 13:52:32 +0100220 void CallKnownFunction(Handle<JSFunction> function,
221 int arity,
Ben Murdoch257744e2011-11-30 15:57:28 +0000222 LInstruction* instr,
223 CallKind call_kind);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100224
Ben Murdochb8e0da22011-05-16 14:20:40 +0100225 void LoadHeapObject(Register result, Handle<HeapObject> object);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100226
Ben Murdoch2b4ba112012-01-20 14:57:15 +0000227 void RecordSafepointWithLazyDeopt(LInstruction* instr,
228 SafepointMode safepoint_mode);
Ben Murdoch8b112d22011-06-08 16:22:53 +0100229
Ben Murdoch2b4ba112012-01-20 14:57:15 +0000230 void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
231 Safepoint::DeoptMode mode);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100232 void DeoptimizeIf(Condition cc, LEnvironment* environment);
233
234 void AddToTranslation(Translation* translation,
235 LOperand* op,
236 bool is_tagged);
237 void PopulateDeoptimizationData(Handle<Code> code);
238 int DefineDeoptimizationLiteral(Handle<Object> literal);
239
240 void PopulateDeoptimizationLiteralsWithInlinedFunctions();
241
242 Register ToRegister(int index) const;
243 DoubleRegister ToDoubleRegister(int index) const;
244
Ben Murdochb0fe1622011-05-05 13:52:32 +0100245 // Specific math operations - used from DoUnaryMathOperation.
Steve Block1e0659c2011-05-24 12:43:12 +0100246 void EmitIntegerMathAbs(LUnaryMathOperation* instr);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100247 void DoMathAbs(LUnaryMathOperation* instr);
248 void DoMathFloor(LUnaryMathOperation* instr);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100249 void DoMathRound(LUnaryMathOperation* instr);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100250 void DoMathSqrt(LUnaryMathOperation* instr);
Steve Block44f0eee2011-05-26 01:26:41 +0100251 void DoMathPowHalf(LUnaryMathOperation* instr);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100252 void DoMathLog(LUnaryMathOperation* instr);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100253 void DoMathTan(LUnaryMathOperation* instr);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100254 void DoMathCos(LUnaryMathOperation* instr);
255 void DoMathSin(LUnaryMathOperation* instr);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100256
257 // Support for recording safepoint and position information.
Steve Block1e0659c2011-05-24 12:43:12 +0100258 void RecordSafepoint(LPointerMap* pointers,
259 Safepoint::Kind kind,
260 int arguments,
Ben Murdoch2b4ba112012-01-20 14:57:15 +0000261 Safepoint::DeoptMode mode);
262 void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
263 void RecordSafepoint(Safepoint::DeoptMode mode);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100264 void RecordSafepointWithRegisters(LPointerMap* pointers,
265 int arguments,
Ben Murdoch2b4ba112012-01-20 14:57:15 +0000266 Safepoint::DeoptMode mode);
Ben Murdochb8e0da22011-05-16 14:20:40 +0100267 void RecordSafepointWithRegistersAndDoubles(LPointerMap* pointers,
268 int arguments,
Ben Murdoch2b4ba112012-01-20 14:57:15 +0000269 Safepoint::DeoptMode mode);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100270 void RecordPosition(int position);
271
272 static Condition TokenToCondition(Token::Value op, bool is_unsigned);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000273 void EmitGoto(int block);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100274 void EmitBranch(int left_block, int right_block, Condition cc);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100275 void EmitNumberUntagD(Register input,
276 DoubleRegister result,
Ben Murdoch7d3e7fc2011-07-12 16:37:06 +0100277 bool deoptimize_on_undefined,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100278 bool deoptimize_on_minus_zero,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100279 LEnvironment* env);
280
281 // Emits optimized code for typeof x == "y". Modifies input register.
282 // Returns the condition on which a final split to
283 // true and false label should be made, to optimize fallthrough.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100284 Condition EmitTypeofIs(Label* true_label,
285 Label* false_label,
286 Register input,
287 Handle<String> type_name);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100288
289 // Emits optimized code for %_IsObject(x). Preserves input register.
290 // Returns the condition on which a final split to
291 // true and false label should be made, to optimize fallthrough.
292 Condition EmitIsObject(Register input,
293 Register temp1,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100294 Label* is_not_object,
295 Label* is_object);
296
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100297 // Emits optimized code for %_IsString(x). Preserves input register.
298 // Returns the condition on which a final split to
299 // true and false label should be made, to optimize fallthrough.
300 Condition EmitIsString(Register input,
301 Register temp1,
302 Label* is_not_string);
303
Steve Block1e0659c2011-05-24 12:43:12 +0100304 // Emits optimized code for %_IsConstructCall().
305 // Caller should branch on equal condition.
306 void EmitIsConstructCall(Register temp1, Register temp2);
307
Ben Murdoch257744e2011-11-30 15:57:28 +0000308 void EmitLoadFieldOrConstantFunction(Register result,
309 Register object,
310 Handle<Map> type,
311 Handle<String> name);
312
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100313 // Emits optimized code to deep-copy the contents of statically known
314 // object graphs (e.g. object literal boilerplate).
315 void EmitDeepCopy(Handle<JSObject> object,
316 Register result,
317 Register source,
318 int* offset);
319
Ben Murdoch257744e2011-11-30 15:57:28 +0000320 struct JumpTableEntry {
321 explicit inline JumpTableEntry(Address entry)
322 : label(),
323 address(entry) { }
324 Label label;
325 Address address;
326 };
Steve Block44f0eee2011-05-26 01:26:41 +0100327
Ben Murdoch2b4ba112012-01-20 14:57:15 +0000328 void EnsureSpaceForLazyDeopt();
329
Ben Murdochb0fe1622011-05-05 13:52:32 +0100330 LChunk* const chunk_;
331 MacroAssembler* const masm_;
332 CompilationInfo* const info_;
333
334 int current_block_;
335 int current_instruction_;
336 const ZoneList<LInstruction*>* instructions_;
337 ZoneList<LEnvironment*> deoptimizations_;
Ben Murdoch257744e2011-11-30 15:57:28 +0000338 ZoneList<JumpTableEntry> deopt_jump_table_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100339 ZoneList<Handle<Object> > deoptimization_literals_;
340 int inlined_function_count_;
341 Scope* const scope_;
342 Status status_;
343 TranslationBuffer translations_;
344 ZoneList<LDeferredCode*> deferred_;
345 int osr_pc_offset_;
Ben Murdoch2b4ba112012-01-20 14:57:15 +0000346 int last_lazy_deopt_pc_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100347
348 // Builder that keeps track of safepoints in the code. The table
349 // itself is emitted at the end of the generated code.
350 SafepointTableBuilder safepoints_;
351
Ben Murdochb8e0da22011-05-16 14:20:40 +0100352 // Compiler from a set of parallel moves to a sequential list of moves.
353 LGapResolver resolver_;
354
Ben Murdoch8b112d22011-06-08 16:22:53 +0100355 Safepoint::Kind expected_safepoint_kind_;
356
357 class PushSafepointRegistersScope BASE_EMBEDDED {
358 public:
359 PushSafepointRegistersScope(LCodeGen* codegen,
360 Safepoint::Kind kind)
361 : codegen_(codegen) {
362 ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
363 codegen_->expected_safepoint_kind_ = kind;
364
365 switch (codegen_->expected_safepoint_kind_) {
366 case Safepoint::kWithRegisters:
367 codegen_->masm_->PushSafepointRegisters();
368 break;
369 case Safepoint::kWithRegistersAndDoubles:
370 codegen_->masm_->PushSafepointRegistersAndDoubles();
371 break;
372 default:
373 UNREACHABLE();
374 }
375 }
376
377 ~PushSafepointRegistersScope() {
378 Safepoint::Kind kind = codegen_->expected_safepoint_kind_;
379 ASSERT((kind & Safepoint::kWithRegisters) != 0);
380 switch (kind) {
381 case Safepoint::kWithRegisters:
382 codegen_->masm_->PopSafepointRegisters();
383 break;
384 case Safepoint::kWithRegistersAndDoubles:
385 codegen_->masm_->PopSafepointRegistersAndDoubles();
386 break;
387 default:
388 UNREACHABLE();
389 }
390 codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
391 }
392
393 private:
394 LCodeGen* codegen_;
395 };
396
Ben Murdochb0fe1622011-05-05 13:52:32 +0100397 friend class LDeferredCode;
398 friend class LEnvironment;
399 friend class SafepointGenerator;
400 DISALLOW_COPY_AND_ASSIGN(LCodeGen);
401};
402
403
404class LDeferredCode: public ZoneObject {
405 public:
406 explicit LDeferredCode(LCodeGen* codegen)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100407 : codegen_(codegen),
408 external_exit_(NULL),
409 instruction_index_(codegen->current_instruction_) {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100410 codegen->AddDeferredCode(this);
411 }
412
413 virtual ~LDeferredCode() { }
414 virtual void Generate() = 0;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100415 virtual LInstruction* instr() = 0;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100416
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100417 void SetExit(Label* exit) { external_exit_ = exit; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100418 Label* entry() { return &entry_; }
419 Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100420 int instruction_index() const { return instruction_index_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100421
422 protected:
423 LCodeGen* codegen() const { return codegen_; }
424 MacroAssembler* masm() const { return codegen_->masm(); }
425
426 private:
427 LCodeGen* codegen_;
428 Label entry_;
429 Label exit_;
430 Label* external_exit_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100431 int instruction_index_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100432};
433
434} } // namespace v8::internal
435
436#endif // V8_ARM_LITHIUM_CODEGEN_ARM_H_