blob: 00823e1638c297c6ff18c5c052f7a09cca617173 [file] [log] [blame]
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001// Copyright 2012 the V8 project authors. All rights reserved.
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002// 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"
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000032#include "arm/lithium-gap-resolver-arm.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000033#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
kasperl@chromium.orga5551262010-12-07 12:49:48 +000044class 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),
danno@chromium.org40cb8782011-05-25 07:58:50 +000054 deopt_jump_table_(4),
kasperl@chromium.orga5551262010-12-07 12:49:48 +000055 deoptimization_literals_(8),
56 inlined_function_count_(0),
karlklose@chromium.org8f806e82011-03-07 14:06:08 +000057 scope_(info->scope()),
kasperl@chromium.orga5551262010-12-07 12:49:48 +000058 status_(UNUSED),
59 deferred_(8),
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000060 osr_pc_offset_(-1),
ricow@chromium.org27bf2882011-11-17 08:34:43 +000061 last_lazy_deopt_pc_(0),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +000062 resolver_(this),
63 expected_safepoint_kind_(Safepoint::kSimple) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +000064 PopulateDeoptimizationLiteralsWithInlinedFunctions();
65 }
66
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000067
68 // Simple accessors.
69 MacroAssembler* masm() const { return masm_; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +000070 CompilationInfo* info() const { return info_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000071 Isolate* isolate() const { return info_->isolate(); }
72 Factory* factory() const { return isolate()->factory(); }
73 Heap* heap() const { return isolate()->heap(); }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000074
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;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000090 double ToDouble(LConstantOperand* op) const;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000091 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
danno@chromium.orgbf0c8202011-12-27 10:09:42 +000096 bool IsInteger32(LConstantOperand* op) const;
97 Handle<Object> ToHandle(LConstantOperand* op) const;
98
kasperl@chromium.orga5551262010-12-07 12:49:48 +000099 // 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.
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000109 template<int T>
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000110 void DoDeferredBinaryOpStub(LTemplateInstruction<1, 2, T>* instr,
111 Token::Value op);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000112 void DoDeferredNumberTagD(LNumberTagD* instr);
113 void DoDeferredNumberTagI(LNumberTagI* instr);
114 void DoDeferredTaggedToI(LTaggedToI* instr);
115 void DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr);
ager@chromium.org04921a82011-06-27 13:21:41 +0000116 void DoDeferredStackCheck(LStackCheck* instr);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000117 void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000118 void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000119 void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
120 Label* map_check);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000121
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000122 void DoCheckMapCommon(Register reg, Register scratch, Handle<Map> map,
123 CompareMapMode mode, LEnvironment* env);
124
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000125 // Parallel move support.
126 void DoParallelMove(LParallelMove* move);
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000127 void DoGap(LGap* instr);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000128
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000129 // Emit frame translation commands for an environment.
130 void WriteTranslation(LEnvironment* environment, Translation* translation);
131
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000132 // Declare methods that deal with the individual node types.
133#define DECLARE_DO(type) void Do##type(L##type* node);
134 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
135#undef DECLARE_DO
136
137 private:
138 enum Status {
139 UNUSED,
140 GENERATING,
141 DONE,
142 ABORTED
143 };
144
145 bool is_unused() const { return status_ == UNUSED; }
146 bool is_generating() const { return status_ == GENERATING; }
147 bool is_done() const { return status_ == DONE; }
148 bool is_aborted() const { return status_ == ABORTED; }
149
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000150 StrictModeFlag strict_mode_flag() const {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000151 return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000152 }
153
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000154 LChunk* chunk() const { return chunk_; }
155 Scope* scope() const { return scope_; }
156 HGraph* graph() const { return chunk_->graph(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000157
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000158 Register scratch0() { return r9; }
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000159 DwVfpRegister double_scratch0() { return kScratchDoubleReg; }
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000160
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000161 int GetNextEmittedBlock(int block);
162 LInstruction* GetNextInstruction();
163
164 void EmitClassOfTest(Label* if_true,
165 Label* if_false,
166 Handle<String> class_name,
167 Register input,
168 Register temporary,
169 Register temporary2);
170
danno@chromium.org160a7b02011-04-18 15:51:38 +0000171 int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
172 int GetParameterCount() const { return scope()->num_parameters(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000173
174 void Abort(const char* format, ...);
175 void Comment(const char* format, ...);
176
177 void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code); }
178
179 // Code generation passes. Returns true if code generation should
180 // continue.
181 bool GeneratePrologue();
182 bool GenerateBody();
183 bool GenerateDeferredCode();
danno@chromium.org40cb8782011-05-25 07:58:50 +0000184 bool GenerateDeoptJumpTable();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000185 bool GenerateSafepointTable();
186
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000187 enum SafepointMode {
188 RECORD_SIMPLE_SAFEPOINT,
189 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS
190 };
191
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000192 void CallCode(Handle<Code> code,
193 RelocInfo::Mode mode,
194 LInstruction* instr);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000195
196 void CallCodeGeneric(Handle<Code> code,
197 RelocInfo::Mode mode,
198 LInstruction* instr,
199 SafepointMode safepoint_mode);
200
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000201 void CallRuntime(const Runtime::Function* function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000202 int num_arguments,
203 LInstruction* instr);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000204
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000205 void CallRuntime(Runtime::FunctionId id,
206 int num_arguments,
207 LInstruction* instr) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000208 const Runtime::Function* function = Runtime::FunctionForId(id);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000209 CallRuntime(function, num_arguments, instr);
210 }
211
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000212 void CallRuntimeFromDeferred(Runtime::FunctionId id,
213 int argc,
214 LInstruction* instr);
215
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000216 // Generate a direct call to a known function. Expects the function
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000217 // to be in r1.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000218 void CallKnownFunction(Handle<JSFunction> function,
219 int arity,
danno@chromium.org40cb8782011-05-25 07:58:50 +0000220 LInstruction* instr,
221 CallKind call_kind);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000222
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000223 void LoadHeapObject(Register result, Handle<HeapObject> object);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000224
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000225 void RecordSafepointWithLazyDeopt(LInstruction* instr,
226 SafepointMode safepoint_mode);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000227
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000228 void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
229 Safepoint::DeoptMode mode);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000230 void DeoptimizeIf(Condition cc, LEnvironment* environment);
231
232 void AddToTranslation(Translation* translation,
233 LOperand* op,
234 bool is_tagged);
235 void PopulateDeoptimizationData(Handle<Code> code);
236 int DefineDeoptimizationLiteral(Handle<Object> literal);
237
238 void PopulateDeoptimizationLiteralsWithInlinedFunctions();
239
240 Register ToRegister(int index) const;
241 DoubleRegister ToDoubleRegister(int index) const;
242
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000243 // Specific math operations - used from DoUnaryMathOperation.
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000244 void EmitIntegerMathAbs(LUnaryMathOperation* instr);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000245 void DoMathAbs(LUnaryMathOperation* instr);
246 void DoMathFloor(LUnaryMathOperation* instr);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000247 void DoMathRound(LUnaryMathOperation* instr);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000248 void DoMathSqrt(LUnaryMathOperation* instr);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000249 void DoMathPowHalf(LUnaryMathOperation* instr);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000250 void DoMathLog(LUnaryMathOperation* instr);
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000251 void DoMathTan(LUnaryMathOperation* instr);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000252 void DoMathCos(LUnaryMathOperation* instr);
253 void DoMathSin(LUnaryMathOperation* instr);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000254
255 // Support for recording safepoint and position information.
ager@chromium.org378b34e2011-01-28 08:04:38 +0000256 void RecordSafepoint(LPointerMap* pointers,
257 Safepoint::Kind kind,
258 int arguments,
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000259 Safepoint::DeoptMode mode);
260 void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
261 void RecordSafepoint(Safepoint::DeoptMode mode);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000262 void RecordSafepointWithRegisters(LPointerMap* pointers,
263 int arguments,
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000264 Safepoint::DeoptMode mode);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000265 void RecordSafepointWithRegistersAndDoubles(LPointerMap* pointers,
266 int arguments,
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000267 Safepoint::DeoptMode mode);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000268 void RecordPosition(int position);
269
270 static Condition TokenToCondition(Token::Value op, bool is_unsigned);
ager@chromium.org04921a82011-06-27 13:21:41 +0000271 void EmitGoto(int block);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000272 void EmitBranch(int left_block, int right_block, Condition cc);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000273 void EmitNumberUntagD(Register input,
274 DoubleRegister result,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000275 bool deoptimize_on_undefined,
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000276 bool deoptimize_on_minus_zero,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000277 LEnvironment* env);
278
279 // Emits optimized code for typeof x == "y". Modifies input register.
280 // Returns the condition on which a final split to
281 // true and false label should be made, to optimize fallthrough.
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000282 Condition EmitTypeofIs(Label* true_label,
283 Label* false_label,
284 Register input,
285 Handle<String> type_name);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000286
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000287 // Emits optimized code for %_IsObject(x). Preserves input register.
288 // Returns the condition on which a final split to
289 // true and false label should be made, to optimize fallthrough.
290 Condition EmitIsObject(Register input,
291 Register temp1,
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000292 Label* is_not_object,
293 Label* is_object);
294
erikcorry0ad885c2011-11-21 13:51:57 +0000295 // Emits optimized code for %_IsString(x). Preserves input register.
296 // Returns the condition on which a final split to
297 // true and false label should be made, to optimize fallthrough.
298 Condition EmitIsString(Register input,
299 Register temp1,
300 Label* is_not_string);
301
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +0000302 // Emits optimized code for %_IsConstructCall().
303 // Caller should branch on equal condition.
304 void EmitIsConstructCall(Register temp1, Register temp2);
305
lrn@chromium.org1c092762011-05-09 09:42:16 +0000306 void EmitLoadFieldOrConstantFunction(Register result,
307 Register object,
308 Handle<Map> type,
309 Handle<String> name);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000310
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000311 // Emits optimized code to deep-copy the contents of statically known
312 // object graphs (e.g. object literal boilerplate).
313 void EmitDeepCopy(Handle<JSObject> object,
314 Register result,
315 Register source,
316 int* offset);
317
danno@chromium.org40cb8782011-05-25 07:58:50 +0000318 struct JumpTableEntry {
319 explicit inline JumpTableEntry(Address entry)
320 : label(),
321 address(entry) { }
322 Label label;
323 Address address;
324 };
325
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000326 void EnsureSpaceForLazyDeopt();
327
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000328 LChunk* const chunk_;
329 MacroAssembler* const masm_;
330 CompilationInfo* const info_;
331
332 int current_block_;
333 int current_instruction_;
334 const ZoneList<LInstruction*>* instructions_;
335 ZoneList<LEnvironment*> deoptimizations_;
danno@chromium.org40cb8782011-05-25 07:58:50 +0000336 ZoneList<JumpTableEntry> deopt_jump_table_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000337 ZoneList<Handle<Object> > deoptimization_literals_;
338 int inlined_function_count_;
339 Scope* const scope_;
340 Status status_;
341 TranslationBuffer translations_;
342 ZoneList<LDeferredCode*> deferred_;
343 int osr_pc_offset_;
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000344 int last_lazy_deopt_pc_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000345
346 // Builder that keeps track of safepoints in the code. The table
347 // itself is emitted at the end of the generated code.
348 SafepointTableBuilder safepoints_;
349
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000350 // Compiler from a set of parallel moves to a sequential list of moves.
351 LGapResolver resolver_;
352
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000353 Safepoint::Kind expected_safepoint_kind_;
354
355 class PushSafepointRegistersScope BASE_EMBEDDED {
356 public:
357 PushSafepointRegistersScope(LCodeGen* codegen,
358 Safepoint::Kind kind)
359 : codegen_(codegen) {
360 ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
361 codegen_->expected_safepoint_kind_ = kind;
362
363 switch (codegen_->expected_safepoint_kind_) {
364 case Safepoint::kWithRegisters:
365 codegen_->masm_->PushSafepointRegisters();
366 break;
367 case Safepoint::kWithRegistersAndDoubles:
368 codegen_->masm_->PushSafepointRegistersAndDoubles();
369 break;
370 default:
371 UNREACHABLE();
372 }
373 }
374
375 ~PushSafepointRegistersScope() {
376 Safepoint::Kind kind = codegen_->expected_safepoint_kind_;
377 ASSERT((kind & Safepoint::kWithRegisters) != 0);
378 switch (kind) {
379 case Safepoint::kWithRegisters:
380 codegen_->masm_->PopSafepointRegisters();
381 break;
382 case Safepoint::kWithRegistersAndDoubles:
383 codegen_->masm_->PopSafepointRegistersAndDoubles();
384 break;
385 default:
386 UNREACHABLE();
387 }
388 codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
389 }
390
391 private:
392 LCodeGen* codegen_;
393 };
394
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000395 friend class LDeferredCode;
396 friend class LEnvironment;
397 friend class SafepointGenerator;
398 DISALLOW_COPY_AND_ASSIGN(LCodeGen);
399};
400
401
402class LDeferredCode: public ZoneObject {
403 public:
404 explicit LDeferredCode(LCodeGen* codegen)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000405 : codegen_(codegen),
406 external_exit_(NULL),
407 instruction_index_(codegen->current_instruction_) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000408 codegen->AddDeferredCode(this);
409 }
410
411 virtual ~LDeferredCode() { }
412 virtual void Generate() = 0;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000413 virtual LInstruction* instr() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000414
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000415 void SetExit(Label* exit) { external_exit_ = exit; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000416 Label* entry() { return &entry_; }
417 Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000418 int instruction_index() const { return instruction_index_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000419
420 protected:
421 LCodeGen* codegen() const { return codegen_; }
422 MacroAssembler* masm() const { return codegen_->masm(); }
423
424 private:
425 LCodeGen* codegen_;
426 Label entry_;
427 Label exit_;
428 Label* external_exit_;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000429 int instruction_index_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000430};
431
432} } // namespace v8::internal
433
434#endif // V8_ARM_LITHIUM_CODEGEN_ARM_H_