blob: 5402c9a7ba0065b7c9420eb470b644b5f8e51878 [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Andrei Popescu31002712010-02-23 13:46:05 +00004
Steve Block44f0eee2011-05-26 01:26:41 +01005#ifndef V8_MIPS_LITHIUM_CODEGEN_MIPS_H_
6#define V8_MIPS_LITHIUM_CODEGEN_MIPS_H_
Andrei Popescu31002712010-02-23 13:46:05 +00007
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include "src/deoptimizer.h"
9#include "src/lithium-codegen.h"
10#include "src/mips/lithium-gap-resolver-mips.h"
11#include "src/mips/lithium-mips.h"
12#include "src/safepoint-table.h"
13#include "src/scopes.h"
14#include "src/utils.h"
Steve Block44f0eee2011-05-26 01:26:41 +010015
Andrei Popescu31002712010-02-23 13:46:05 +000016namespace v8 {
17namespace internal {
18
Steve Block44f0eee2011-05-26 01:26:41 +010019// Forward declarations.
20class LDeferredCode;
Ben Murdoch3ef787d2012-04-12 10:51:47 +010021class SafepointGenerator;
Andrei Popescu31002712010-02-23 13:46:05 +000022
Ben Murdochb8a8cc12014-11-26 15:28:44 +000023class LCodeGen: public LCodeGenBase {
Steve Block44f0eee2011-05-26 01:26:41 +010024 public:
Ben Murdoch3ef787d2012-04-12 10:51:47 +010025 LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000026 : LCodeGenBase(chunk, assembler, info),
27 deoptimizations_(4, info->zone()),
28 jump_table_(4, info->zone()),
29 deoptimization_literals_(8, info->zone()),
Ben Murdoch3ef787d2012-04-12 10:51:47 +010030 inlined_function_count_(0),
31 scope_(info->scope()),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000032 translations_(info->zone()),
33 deferred_(8, info->zone()),
Ben Murdoch3ef787d2012-04-12 10:51:47 +010034 osr_pc_offset_(-1),
Ben Murdochb8a8cc12014-11-26 15:28:44 +000035 frame_is_built_(false),
36 safepoints_(info->zone()),
Ben Murdoch3ef787d2012-04-12 10:51:47 +010037 resolver_(this),
38 expected_safepoint_kind_(Safepoint::kSimple) {
39 PopulateDeoptimizationLiteralsWithInlinedFunctions();
40 }
41
42
Ben Murdochb8a8cc12014-11-26 15:28:44 +000043 int LookupDestination(int block_id) const {
44 return chunk()->LookupDestination(block_id);
45 }
46
47 bool IsNextEmittedBlock(int block_id) const {
48 return LookupDestination(block_id) == GetNextEmittedBlock();
49 }
50
51 bool NeedsEagerFrame() const {
52 return GetStackSlotCount() > 0 ||
53 info()->is_non_deferred_calling() ||
54 !info()->IsStub() ||
55 info()->requires_frame();
56 }
57 bool NeedsDeferredFrame() const {
58 return !NeedsEagerFrame() && info()->is_deferred_calling();
59 }
60
61 RAStatus GetRAState() const {
62 return frame_is_built_ ? kRAHasBeenSaved : kRAHasNotBeenSaved;
63 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +010064
65 // Support for converting LOperands to assembler types.
66 // LOperand must be a register.
67 Register ToRegister(LOperand* op) const;
68
69 // LOperand is loaded into scratch, unless already a register.
70 Register EmitLoadRegister(LOperand* op, Register scratch);
71
72 // LOperand must be a double register.
73 DoubleRegister ToDoubleRegister(LOperand* op) const;
74
75 // LOperand is loaded into dbl_scratch, unless already a double register.
76 DoubleRegister EmitLoadDoubleRegister(LOperand* op,
77 FloatRegister flt_scratch,
78 DoubleRegister dbl_scratch);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000079 int32_t ToRepresentation(LConstantOperand* op, const Representation& r) const;
80 int32_t ToInteger32(LConstantOperand* op) const;
81 Smi* ToSmi(LConstantOperand* op) const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +010082 double ToDouble(LConstantOperand* op) const;
83 Operand ToOperand(LOperand* op);
84 MemOperand ToMemOperand(LOperand* op) const;
85 // Returns a MemOperand pointing to the high word of a DoubleStackSlot.
86 MemOperand ToHighMemOperand(LOperand* op) const;
87
88 bool IsInteger32(LConstantOperand* op) const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000089 bool IsSmi(LConstantOperand* op) const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +010090 Handle<Object> ToHandle(LConstantOperand* op) const;
Ben Murdochc7cc0282012-03-05 14:35:55 +000091
Steve Block44f0eee2011-05-26 01:26:41 +010092 // Try to generate code for the entire chunk, but it may fail if the
93 // chunk contains constructs we cannot handle. Returns true if the
94 // code generation attempt succeeded.
Ben Murdoch3ef787d2012-04-12 10:51:47 +010095 bool GenerateCode();
Steve Block6ded16b2010-05-10 14:33:55 +010096
Steve Block44f0eee2011-05-26 01:26:41 +010097 // Finish the code by setting stack height, safepoint, and bailout
98 // information on it.
Ben Murdoch3ef787d2012-04-12 10:51:47 +010099 void FinishCode(Handle<Code> code);
100
101 void DoDeferredNumberTagD(LNumberTagD* instr);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000102
103 enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
104 void DoDeferredNumberTagIU(LInstruction* instr,
105 LOperand* value,
106 LOperand* temp1,
107 LOperand* temp2,
108 IntegerSignedness signedness);
109
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100110 void DoDeferredTaggedToI(LTaggedToI* instr);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000111 void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100112 void DoDeferredStackCheck(LStackCheck* instr);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100113 void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
114 void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000115 void DoDeferredAllocate(LAllocate* instr);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100116 void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
117 Label* map_check);
118
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000119 void DoDeferredInstanceMigration(LCheckMaps* instr, Register object);
120 void DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
121 Register result,
122 Register object,
123 Register index);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100124
125 // Parallel move support.
126 void DoParallelMove(LParallelMove* move);
127 void DoGap(LGap* instr);
128
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000129 MemOperand PrepareKeyedOperand(Register key,
130 Register base,
131 bool key_is_constant,
132 int constant_key,
133 int element_size,
134 int shift_size,
135 int base_offset);
136
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100137 // Emit frame translation commands for an environment.
138 void WriteTranslation(LEnvironment* environment, Translation* translation);
139
140 // Declare methods that deal with the individual node types.
141#define DECLARE_DO(type) void Do##type(L##type* node);
142 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
143#undef DECLARE_DO
144
145 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000146 StrictMode strict_mode() const { return info()->strict_mode(); }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100147
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100148 Scope* scope() const { return scope_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100149
150 Register scratch0() { return kLithiumScratchReg; }
151 Register scratch1() { return kLithiumScratchReg2; }
152 DoubleRegister double_scratch0() { return kLithiumScratchDouble; }
153
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100154 LInstruction* GetNextInstruction();
155
156 void EmitClassOfTest(Label* if_true,
157 Label* if_false,
158 Handle<String> class_name,
159 Register input,
160 Register temporary,
161 Register temporary2);
162
163 int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100164
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000165 void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100166
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000167 void SaveCallerDoubles();
168 void RestoreCallerDoubles();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100169
170 // Code generation passes. Returns true if code generation should
171 // continue.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000172 void GenerateBodyInstructionPre(LInstruction* instr) OVERRIDE;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100173 bool GeneratePrologue();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100174 bool GenerateDeferredCode();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000175 bool GenerateJumpTable();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100176 bool GenerateSafepointTable();
177
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000178 // Generates the custom OSR entrypoint and sets the osr_pc_offset.
179 void GenerateOsrPrologue();
180
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100181 enum SafepointMode {
182 RECORD_SIMPLE_SAFEPOINT,
183 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS
184 };
185
186 void CallCode(Handle<Code> code,
187 RelocInfo::Mode mode,
188 LInstruction* instr);
189
190 void CallCodeGeneric(Handle<Code> code,
191 RelocInfo::Mode mode,
192 LInstruction* instr,
193 SafepointMode safepoint_mode);
194
195 void CallRuntime(const Runtime::Function* function,
196 int num_arguments,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000197 LInstruction* instr,
198 SaveFPRegsMode save_doubles = kDontSaveFPRegs);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100199
200 void CallRuntime(Runtime::FunctionId id,
201 int num_arguments,
202 LInstruction* instr) {
203 const Runtime::Function* function = Runtime::FunctionForId(id);
204 CallRuntime(function, num_arguments, instr);
205 }
206
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000207 void LoadContextFromDeferred(LOperand* context);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100208 void CallRuntimeFromDeferred(Runtime::FunctionId id,
209 int argc,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000210 LInstruction* instr,
211 LOperand* context);
212
213 enum A1State {
214 A1_UNINITIALIZED,
215 A1_CONTAINS_TARGET
216 };
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100217
218 // Generate a direct call to a known function. Expects the function
219 // to be in a1.
220 void CallKnownFunction(Handle<JSFunction> function,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000221 int formal_parameter_count,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100222 int arity,
223 LInstruction* instr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000224 A1State a1_state);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100225
226 void RecordSafepointWithLazyDeopt(LInstruction* instr,
227 SafepointMode safepoint_mode);
228
229 void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
230 Safepoint::DeoptMode mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000231 void DeoptimizeIf(Condition condition, LInstruction* instr,
232 Deoptimizer::BailoutType bailout_type,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100233 Register src1 = zero_reg,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000234 const Operand& src2 = Operand(zero_reg),
235 const char* detail = NULL);
236 void DeoptimizeIf(Condition condition, LInstruction* instr,
237 Register src1 = zero_reg,
238 const Operand& src2 = Operand(zero_reg),
239 const char* detail = NULL);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100240
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000241 void AddToTranslation(LEnvironment* environment,
242 Translation* translation,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100243 LOperand* op,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000244 bool is_tagged,
245 bool is_uint32,
246 int* object_index_pointer,
247 int* dematerialized_index_pointer);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100248 void PopulateDeoptimizationData(Handle<Code> code);
249 int DefineDeoptimizationLiteral(Handle<Object> literal);
250
251 void PopulateDeoptimizationLiteralsWithInlinedFunctions();
252
253 Register ToRegister(int index) const;
254 DoubleRegister ToDoubleRegister(int index) const;
255
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000256 MemOperand BuildSeqStringOperand(Register string,
257 LOperand* index,
258 String::Encoding encoding);
259
260 void EmitIntegerMathAbs(LMathAbs* instr);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100261
262 // Support for recording safepoint and position information.
263 void RecordSafepoint(LPointerMap* pointers,
264 Safepoint::Kind kind,
265 int arguments,
266 Safepoint::DeoptMode mode);
267 void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
268 void RecordSafepoint(Safepoint::DeoptMode mode);
269 void RecordSafepointWithRegisters(LPointerMap* pointers,
270 int arguments,
271 Safepoint::DeoptMode mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000272
273 void RecordAndWritePosition(int position) OVERRIDE;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100274
275 static Condition TokenToCondition(Token::Value op, bool is_unsigned);
276 void EmitGoto(int block);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000277
278 // EmitBranch expects to be the last instruction of a block.
279 template<class InstrType>
280 void EmitBranch(InstrType instr,
281 Condition condition,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100282 Register src1,
283 const Operand& src2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000284 template<class InstrType>
285 void EmitBranchF(InstrType instr,
286 Condition condition,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100287 FPURegister src1,
288 FPURegister src2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000289 template<class InstrType>
290 void EmitFalseBranch(InstrType instr,
291 Condition condition,
292 Register src1,
293 const Operand& src2);
294 template<class InstrType>
295 void EmitFalseBranchF(InstrType instr,
296 Condition condition,
297 FPURegister src1,
298 FPURegister src2);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100299 void EmitCmpI(LOperand* left, LOperand* right);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000300 void EmitNumberUntagD(LNumberUntagD* instr, Register input,
301 DoubleRegister result, NumberUntagDMode mode);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100302
303 // Emits optimized code for typeof x == "y". Modifies input register.
304 // Returns the condition on which a final split to
305 // true and false label should be made, to optimize fallthrough.
306 // Returns two registers in cmp1 and cmp2 that can be used in the
307 // Branch instruction after EmitTypeofIs.
308 Condition EmitTypeofIs(Label* true_label,
309 Label* false_label,
310 Register input,
311 Handle<String> type_name,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000312 Register* cmp1,
313 Operand* cmp2);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100314
315 // Emits optimized code for %_IsObject(x). Preserves input register.
316 // Returns the condition on which a final split to
317 // true and false label should be made, to optimize fallthrough.
318 Condition EmitIsObject(Register input,
319 Register temp1,
320 Register temp2,
321 Label* is_not_object,
322 Label* is_object);
323
324 // Emits optimized code for %_IsString(x). Preserves input register.
325 // Returns the condition on which a final split to
326 // true and false label should be made, to optimize fallthrough.
327 Condition EmitIsString(Register input,
328 Register temp1,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000329 Label* is_not_string,
330 SmiCheck check_needed);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100331
332 // Emits optimized code for %_IsConstructCall().
333 // Caller should branch on equal condition.
334 void EmitIsConstructCall(Register temp1, Register temp2);
335
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100336 // Emits optimized code to deep-copy the contents of statically known
337 // object graphs (e.g. object literal boilerplate).
338 void EmitDeepCopy(Handle<JSObject> object,
339 Register result,
340 Register source,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000341 int* offset,
342 AllocationSiteMode mode);
343 // Emit optimized code for integer division.
344 // Inputs are signed.
345 // All registers are clobbered.
346 // If 'remainder' is no_reg, it is not computed.
347 void EmitSignedIntegerDivisionByConstant(Register result,
348 Register dividend,
349 int32_t divisor,
350 Register remainder,
351 Register scratch,
352 LEnvironment* environment);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100353
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100354
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000355 void EnsureSpaceForLazyDeopt(int space_needed) OVERRIDE;
356 void DoLoadKeyedExternalArray(LLoadKeyed* instr);
357 void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr);
358 void DoLoadKeyedFixedArray(LLoadKeyed* instr);
359 void DoStoreKeyedExternalArray(LStoreKeyed* instr);
360 void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
361 void DoStoreKeyedFixedArray(LStoreKeyed* instr);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100362
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000363 template <class T>
364 void EmitVectorLoadICRegisters(T* instr);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100365
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100366 ZoneList<LEnvironment*> deoptimizations_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000367 ZoneList<Deoptimizer::JumpTableEntry> jump_table_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100368 ZoneList<Handle<Object> > deoptimization_literals_;
369 int inlined_function_count_;
370 Scope* const scope_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100371 TranslationBuffer translations_;
372 ZoneList<LDeferredCode*> deferred_;
373 int osr_pc_offset_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000374 bool frame_is_built_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100375
376 // Builder that keeps track of safepoints in the code. The table
377 // itself is emitted at the end of the generated code.
378 SafepointTableBuilder safepoints_;
379
380 // Compiler from a set of parallel moves to a sequential list of moves.
381 LGapResolver resolver_;
382
383 Safepoint::Kind expected_safepoint_kind_;
384
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000385 class PushSafepointRegistersScope FINAL BASE_EMBEDDED {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100386 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000387 explicit PushSafepointRegistersScope(LCodeGen* codegen)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100388 : codegen_(codegen) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000389 DCHECK(codegen_->info()->is_calling());
390 DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
391 codegen_->expected_safepoint_kind_ = Safepoint::kWithRegisters;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100392
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000393 StoreRegistersStateStub stub(codegen_->isolate());
394 codegen_->masm_->push(ra);
395 codegen_->masm_->CallStub(&stub);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100396 }
397
398 ~PushSafepointRegistersScope() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000399 DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters);
400 RestoreRegistersStateStub stub(codegen_->isolate());
401 codegen_->masm_->push(ra);
402 codegen_->masm_->CallStub(&stub);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100403 codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
404 }
405
406 private:
407 LCodeGen* codegen_;
408 };
409
410 friend class LDeferredCode;
411 friend class LEnvironment;
412 friend class SafepointGenerator;
413 DISALLOW_COPY_AND_ASSIGN(LCodeGen);
414};
415
416
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000417class LDeferredCode : public ZoneObject {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100418 public:
419 explicit LDeferredCode(LCodeGen* codegen)
420 : codegen_(codegen),
421 external_exit_(NULL),
422 instruction_index_(codegen->current_instruction_) {
423 codegen->AddDeferredCode(this);
424 }
425
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000426 virtual ~LDeferredCode() {}
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100427 virtual void Generate() = 0;
428 virtual LInstruction* instr() = 0;
429
430 void SetExit(Label* exit) { external_exit_ = exit; }
431 Label* entry() { return &entry_; }
432 Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
433 int instruction_index() const { return instruction_index_; }
434
435 protected:
436 LCodeGen* codegen() const { return codegen_; }
437 MacroAssembler* masm() const { return codegen_->masm(); }
438
439 private:
440 LCodeGen* codegen_;
441 Label entry_;
442 Label exit_;
443 Label* external_exit_;
444 int instruction_index_;
Steve Block44f0eee2011-05-26 01:26:41 +0100445};
Andrei Popescu31002712010-02-23 13:46:05 +0000446
447} } // namespace v8::internal
448
Steve Block44f0eee2011-05-26 01:26:41 +0100449#endif // V8_MIPS_LITHIUM_CODEGEN_MIPS_H_