blob: 43316e471b5b055c17a7302c008c3ab4c2d59aba [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,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400232 Deoptimizer::BailoutType bailout_type, const char* detail,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100233 Register src1 = zero_reg,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400234 const Operand& src2 = Operand(zero_reg));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000235 void DeoptimizeIf(Condition condition, LInstruction* instr,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400236 const char* detail = NULL, Register src1 = zero_reg,
237 const Operand& src2 = Operand(zero_reg));
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100238
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000239 void AddToTranslation(LEnvironment* environment,
240 Translation* translation,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100241 LOperand* op,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000242 bool is_tagged,
243 bool is_uint32,
244 int* object_index_pointer,
245 int* dematerialized_index_pointer);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100246 void PopulateDeoptimizationData(Handle<Code> code);
247 int DefineDeoptimizationLiteral(Handle<Object> literal);
248
249 void PopulateDeoptimizationLiteralsWithInlinedFunctions();
250
251 Register ToRegister(int index) const;
252 DoubleRegister ToDoubleRegister(int index) const;
253
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000254 MemOperand BuildSeqStringOperand(Register string,
255 LOperand* index,
256 String::Encoding encoding);
257
258 void EmitIntegerMathAbs(LMathAbs* instr);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100259
260 // Support for recording safepoint and position information.
261 void RecordSafepoint(LPointerMap* pointers,
262 Safepoint::Kind kind,
263 int arguments,
264 Safepoint::DeoptMode mode);
265 void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
266 void RecordSafepoint(Safepoint::DeoptMode mode);
267 void RecordSafepointWithRegisters(LPointerMap* pointers,
268 int arguments,
269 Safepoint::DeoptMode mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000270
271 void RecordAndWritePosition(int position) OVERRIDE;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100272
273 static Condition TokenToCondition(Token::Value op, bool is_unsigned);
274 void EmitGoto(int block);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000275
276 // EmitBranch expects to be the last instruction of a block.
277 template<class InstrType>
278 void EmitBranch(InstrType instr,
279 Condition condition,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100280 Register src1,
281 const Operand& src2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000282 template<class InstrType>
283 void EmitBranchF(InstrType instr,
284 Condition condition,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100285 FPURegister src1,
286 FPURegister src2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000287 template<class InstrType>
288 void EmitFalseBranch(InstrType instr,
289 Condition condition,
290 Register src1,
291 const Operand& src2);
292 template<class InstrType>
293 void EmitFalseBranchF(InstrType instr,
294 Condition condition,
295 FPURegister src1,
296 FPURegister src2);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100297 void EmitCmpI(LOperand* left, LOperand* right);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000298 void EmitNumberUntagD(LNumberUntagD* instr, Register input,
299 DoubleRegister result, NumberUntagDMode mode);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100300
301 // Emits optimized code for typeof x == "y". Modifies input register.
302 // Returns the condition on which a final split to
303 // true and false label should be made, to optimize fallthrough.
304 // Returns two registers in cmp1 and cmp2 that can be used in the
305 // Branch instruction after EmitTypeofIs.
306 Condition EmitTypeofIs(Label* true_label,
307 Label* false_label,
308 Register input,
309 Handle<String> type_name,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000310 Register* cmp1,
311 Operand* cmp2);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100312
313 // Emits optimized code for %_IsObject(x). Preserves input register.
314 // Returns the condition on which a final split to
315 // true and false label should be made, to optimize fallthrough.
316 Condition EmitIsObject(Register input,
317 Register temp1,
318 Register temp2,
319 Label* is_not_object,
320 Label* is_object);
321
322 // Emits optimized code for %_IsString(x). Preserves input register.
323 // Returns the condition on which a final split to
324 // true and false label should be made, to optimize fallthrough.
325 Condition EmitIsString(Register input,
326 Register temp1,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000327 Label* is_not_string,
328 SmiCheck check_needed);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100329
330 // Emits optimized code for %_IsConstructCall().
331 // Caller should branch on equal condition.
332 void EmitIsConstructCall(Register temp1, Register temp2);
333
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100334 // Emits optimized code to deep-copy the contents of statically known
335 // object graphs (e.g. object literal boilerplate).
336 void EmitDeepCopy(Handle<JSObject> object,
337 Register result,
338 Register source,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000339 int* offset,
340 AllocationSiteMode mode);
341 // Emit optimized code for integer division.
342 // Inputs are signed.
343 // All registers are clobbered.
344 // If 'remainder' is no_reg, it is not computed.
345 void EmitSignedIntegerDivisionByConstant(Register result,
346 Register dividend,
347 int32_t divisor,
348 Register remainder,
349 Register scratch,
350 LEnvironment* environment);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100351
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100352
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000353 void EnsureSpaceForLazyDeopt(int space_needed) OVERRIDE;
354 void DoLoadKeyedExternalArray(LLoadKeyed* instr);
355 void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr);
356 void DoLoadKeyedFixedArray(LLoadKeyed* instr);
357 void DoStoreKeyedExternalArray(LStoreKeyed* instr);
358 void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
359 void DoStoreKeyedFixedArray(LStoreKeyed* instr);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100360
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000361 template <class T>
362 void EmitVectorLoadICRegisters(T* instr);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100363
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100364 ZoneList<LEnvironment*> deoptimizations_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000365 ZoneList<Deoptimizer::JumpTableEntry> jump_table_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100366 ZoneList<Handle<Object> > deoptimization_literals_;
367 int inlined_function_count_;
368 Scope* const scope_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100369 TranslationBuffer translations_;
370 ZoneList<LDeferredCode*> deferred_;
371 int osr_pc_offset_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000372 bool frame_is_built_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100373
374 // Builder that keeps track of safepoints in the code. The table
375 // itself is emitted at the end of the generated code.
376 SafepointTableBuilder safepoints_;
377
378 // Compiler from a set of parallel moves to a sequential list of moves.
379 LGapResolver resolver_;
380
381 Safepoint::Kind expected_safepoint_kind_;
382
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000383 class PushSafepointRegistersScope FINAL BASE_EMBEDDED {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100384 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000385 explicit PushSafepointRegistersScope(LCodeGen* codegen)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100386 : codegen_(codegen) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000387 DCHECK(codegen_->info()->is_calling());
388 DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
389 codegen_->expected_safepoint_kind_ = Safepoint::kWithRegisters;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100390
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000391 StoreRegistersStateStub stub(codegen_->isolate());
392 codegen_->masm_->push(ra);
393 codegen_->masm_->CallStub(&stub);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100394 }
395
396 ~PushSafepointRegistersScope() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000397 DCHECK(codegen_->expected_safepoint_kind_ == Safepoint::kWithRegisters);
398 RestoreRegistersStateStub stub(codegen_->isolate());
399 codegen_->masm_->push(ra);
400 codegen_->masm_->CallStub(&stub);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100401 codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
402 }
403
404 private:
405 LCodeGen* codegen_;
406 };
407
408 friend class LDeferredCode;
409 friend class LEnvironment;
410 friend class SafepointGenerator;
411 DISALLOW_COPY_AND_ASSIGN(LCodeGen);
412};
413
414
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000415class LDeferredCode : public ZoneObject {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100416 public:
417 explicit LDeferredCode(LCodeGen* codegen)
418 : codegen_(codegen),
419 external_exit_(NULL),
420 instruction_index_(codegen->current_instruction_) {
421 codegen->AddDeferredCode(this);
422 }
423
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000424 virtual ~LDeferredCode() {}
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100425 virtual void Generate() = 0;
426 virtual LInstruction* instr() = 0;
427
428 void SetExit(Label* exit) { external_exit_ = exit; }
429 Label* entry() { return &entry_; }
430 Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
431 int instruction_index() const { return instruction_index_; }
432
433 protected:
434 LCodeGen* codegen() const { return codegen_; }
435 MacroAssembler* masm() const { return codegen_->masm(); }
436
437 private:
438 LCodeGen* codegen_;
439 Label entry_;
440 Label exit_;
441 Label* external_exit_;
442 int instruction_index_;
Steve Block44f0eee2011-05-26 01:26:41 +0100443};
Andrei Popescu31002712010-02-23 13:46:05 +0000444
445} } // namespace v8::internal
446
Steve Block44f0eee2011-05-26 01:26:41 +0100447#endif // V8_MIPS_LITHIUM_CODEGEN_MIPS_H_