blob: 7363eb8efe26f0fd9b5fb47721d3c7c01fe5ca6d [file] [log] [blame]
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +00001// Copyright 2012 the V8 project authors. All rights reserved.
ager@chromium.org5c838252010-02-19 08:53:10 +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
lrn@chromium.org7516f052011-03-30 08:52:27 +000028#ifndef V8_MIPS_LITHIUM_CODEGEN_MIPS_H_
29#define V8_MIPS_LITHIUM_CODEGEN_MIPS_H_
ager@chromium.org5c838252010-02-19 08:53:10 +000030
lrn@chromium.org7516f052011-03-30 08:52:27 +000031#include "mips/lithium-mips.h"
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000032#include "mips/lithium-gap-resolver-mips.h"
lrn@chromium.org7516f052011-03-30 08:52:27 +000033#include "deoptimizer.h"
34#include "safepoint-table.h"
35#include "scopes.h"
36
ager@chromium.org5c838252010-02-19 08:53:10 +000037namespace v8 {
38namespace internal {
39
lrn@chromium.org7516f052011-03-30 08:52:27 +000040// Forward declarations.
41class LDeferredCode;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000042class SafepointGenerator;
ager@chromium.org5c838252010-02-19 08:53:10 +000043
lrn@chromium.org7516f052011-03-30 08:52:27 +000044class LCodeGen BASE_EMBEDDED {
45 public:
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000046 LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
47 : zone_(info->zone()),
jkummerow@chromium.org28583c92012-07-16 11:31:55 +000048 chunk_(static_cast<LPlatformChunk*>(chunk)),
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000049 masm_(assembler),
50 info_(info),
51 current_block_(-1),
52 current_instruction_(-1),
53 instructions_(chunk->instructions()),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000054 deoptimizations_(4, info->zone()),
55 deopt_jump_table_(4, info->zone()),
56 deoptimization_literals_(8, info->zone()),
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000057 inlined_function_count_(0),
58 scope_(info->scope()),
59 status_(UNUSED),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000060 translations_(info->zone()),
61 deferred_(8, info->zone()),
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000062 osr_pc_offset_(-1),
erikcorry0ad885c2011-11-21 13:51:57 +000063 last_lazy_deopt_pc_(0),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000064 safepoints_(info->zone()),
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000065 resolver_(this),
66 expected_safepoint_kind_(Safepoint::kSimple) {
67 PopulateDeoptimizationLiteralsWithInlinedFunctions();
68 }
69
70
71 // Simple accessors.
72 MacroAssembler* masm() const { return masm_; }
73 CompilationInfo* info() const { return info_; }
74 Isolate* isolate() const { return info_->isolate(); }
75 Factory* factory() const { return isolate()->factory(); }
76 Heap* heap() const { return isolate()->heap(); }
mmassi@chromium.org7028c052012-06-13 11:51:58 +000077 Zone* zone() const { return zone_; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000078
79 // Support for converting LOperands to assembler types.
80 // LOperand must be a register.
81 Register ToRegister(LOperand* op) const;
82
83 // LOperand is loaded into scratch, unless already a register.
84 Register EmitLoadRegister(LOperand* op, Register scratch);
85
86 // LOperand must be a double register.
87 DoubleRegister ToDoubleRegister(LOperand* op) const;
88
89 // LOperand is loaded into dbl_scratch, unless already a double register.
90 DoubleRegister EmitLoadDoubleRegister(LOperand* op,
91 FloatRegister flt_scratch,
92 DoubleRegister dbl_scratch);
93 int ToInteger32(LConstantOperand* op) const;
94 double ToDouble(LConstantOperand* op) const;
95 Operand ToOperand(LOperand* op);
96 MemOperand ToMemOperand(LOperand* op) const;
97 // Returns a MemOperand pointing to the high word of a DoubleStackSlot.
98 MemOperand ToHighMemOperand(LOperand* op) const;
ager@chromium.orgce5e87b2010-03-10 10:24:18 +000099
rossberg@chromium.orgfab14982012-01-05 15:02:15 +0000100 bool IsInteger32(LConstantOperand* op) const;
101 Handle<Object> ToHandle(LConstantOperand* op) const;
102
lrn@chromium.org7516f052011-03-30 08:52:27 +0000103 // Try to generate code for the entire chunk, but it may fail if the
104 // chunk contains constructs we cannot handle. Returns true if the
105 // code generation attempt succeeded.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000106 bool GenerateCode();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000107
lrn@chromium.org7516f052011-03-30 08:52:27 +0000108 // Finish the code by setting stack height, safepoint, and bailout
109 // information on it.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000110 void FinishCode(Handle<Code> code);
111
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000112 void DoDeferredNumberTagD(LNumberTagD* instr);
jkummerow@chromium.org78502a92012-09-06 13:50:42 +0000113
114 enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
115 void DoDeferredNumberTagI(LInstruction* instr,
116 LOperand* value,
117 IntegerSignedness signedness);
118
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000119 void DoDeferredTaggedToI(LTaggedToI* instr);
120 void DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr);
121 void DoDeferredStackCheck(LStackCheck* instr);
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000122 void DoDeferredRandom(LRandom* instr);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000123 void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
124 void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
ulan@chromium.org967e2702012-02-28 09:49:15 +0000125 void DoDeferredAllocateObject(LAllocateObject* instr);
erikcorry0ad885c2011-11-21 13:51:57 +0000126 void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
127 Label* map_check);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000128
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000129 void DoCheckMapCommon(Register reg, Register scratch, Handle<Map> map,
130 CompareMapMode mode, LEnvironment* env);
131
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000132 // Parallel move support.
133 void DoParallelMove(LParallelMove* move);
134 void DoGap(LGap* instr);
135
danno@chromium.org129d3982012-07-25 15:01:47 +0000136 MemOperand PrepareKeyedOperand(Register key,
137 Register base,
138 bool key_is_constant,
139 int constant_key,
140 int element_size,
141 int shift_size,
142 int additional_index,
143 int additional_offset);
144
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000145 // Emit frame translation commands for an environment.
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000146 void WriteTranslation(LEnvironment* environment,
147 Translation* translation,
148 int* arguments_index,
149 int* arguments_count);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000150
151 // Declare methods that deal with the individual node types.
152#define DECLARE_DO(type) void Do##type(L##type* node);
153 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
154#undef DECLARE_DO
155
156 private:
157 enum Status {
158 UNUSED,
159 GENERATING,
160 DONE,
161 ABORTED
162 };
163
164 bool is_unused() const { return status_ == UNUSED; }
165 bool is_generating() const { return status_ == GENERATING; }
166 bool is_done() const { return status_ == DONE; }
167 bool is_aborted() const { return status_ == ABORTED; }
168
169 StrictModeFlag strict_mode_flag() const {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000170 return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000171 }
172
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000173 LPlatformChunk* chunk() const { return chunk_; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000174 Scope* scope() const { return scope_; }
175 HGraph* graph() const { return chunk_->graph(); }
176
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000177 Register scratch0() { return kLithiumScratchReg; }
178 Register scratch1() { return kLithiumScratchReg2; }
179 DoubleRegister double_scratch0() { return kLithiumScratchDouble; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000180
181 int GetNextEmittedBlock(int block);
182 LInstruction* GetNextInstruction();
183
184 void EmitClassOfTest(Label* if_true,
185 Label* if_false,
186 Handle<String> class_name,
187 Register input,
188 Register temporary,
189 Register temporary2);
190
191 int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
192 int GetParameterCount() const { return scope()->num_parameters(); }
193
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000194 void Abort(const char* reason);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000195 void Comment(const char* format, ...);
196
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000197 void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000198
199 // Code generation passes. Returns true if code generation should
200 // continue.
201 bool GeneratePrologue();
202 bool GenerateBody();
203 bool GenerateDeferredCode();
204 bool GenerateDeoptJumpTable();
205 bool GenerateSafepointTable();
206
207 enum SafepointMode {
208 RECORD_SIMPLE_SAFEPOINT,
209 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS
210 };
211
212 void CallCode(Handle<Code> code,
213 RelocInfo::Mode mode,
214 LInstruction* instr);
215
216 void CallCodeGeneric(Handle<Code> code,
217 RelocInfo::Mode mode,
218 LInstruction* instr,
219 SafepointMode safepoint_mode);
220
221 void CallRuntime(const Runtime::Function* function,
222 int num_arguments,
223 LInstruction* instr);
224
225 void CallRuntime(Runtime::FunctionId id,
226 int num_arguments,
227 LInstruction* instr) {
228 const Runtime::Function* function = Runtime::FunctionForId(id);
229 CallRuntime(function, num_arguments, instr);
230 }
231
232 void CallRuntimeFromDeferred(Runtime::FunctionId id,
233 int argc,
234 LInstruction* instr);
235
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +0000236 enum A1State {
237 A1_UNINITIALIZED,
238 A1_CONTAINS_TARGET
239 };
240
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000241 // Generate a direct call to a known function. Expects the function
242 // to be in a1.
243 void CallKnownFunction(Handle<JSFunction> function,
244 int arity,
245 LInstruction* instr,
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +0000246 CallKind call_kind,
247 A1State a1_state);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000248
249 void LoadHeapObject(Register result, Handle<HeapObject> object);
250
erikcorry0ad885c2011-11-21 13:51:57 +0000251 void RecordSafepointWithLazyDeopt(LInstruction* instr,
252 SafepointMode safepoint_mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000253
erikcorry0ad885c2011-11-21 13:51:57 +0000254 void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
255 Safepoint::DeoptMode mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000256 void DeoptimizeIf(Condition cc,
257 LEnvironment* environment,
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000258 Register src1 = zero_reg,
259 const Operand& src2 = Operand(zero_reg));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000260
261 void AddToTranslation(Translation* translation,
262 LOperand* op,
jkummerow@chromium.org78502a92012-09-06 13:50:42 +0000263 bool is_tagged,
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000264 bool is_uint32,
265 int arguments_index,
266 int arguments_count);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000267 void PopulateDeoptimizationData(Handle<Code> code);
268 int DefineDeoptimizationLiteral(Handle<Object> literal);
269
270 void PopulateDeoptimizationLiteralsWithInlinedFunctions();
271
272 Register ToRegister(int index) const;
273 DoubleRegister ToDoubleRegister(int index) const;
274
275 // Specific math operations - used from DoUnaryMathOperation.
276 void EmitIntegerMathAbs(LUnaryMathOperation* instr);
277 void DoMathAbs(LUnaryMathOperation* instr);
278 void DoMathFloor(LUnaryMathOperation* instr);
279 void DoMathRound(LUnaryMathOperation* instr);
280 void DoMathSqrt(LUnaryMathOperation* instr);
281 void DoMathPowHalf(LUnaryMathOperation* instr);
282 void DoMathLog(LUnaryMathOperation* instr);
svenpanne@chromium.orgecb9dd62011-12-01 08:22:35 +0000283 void DoMathTan(LUnaryMathOperation* instr);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000284 void DoMathCos(LUnaryMathOperation* instr);
285 void DoMathSin(LUnaryMathOperation* instr);
286
287 // Support for recording safepoint and position information.
288 void RecordSafepoint(LPointerMap* pointers,
289 Safepoint::Kind kind,
290 int arguments,
erikcorry0ad885c2011-11-21 13:51:57 +0000291 Safepoint::DeoptMode mode);
292 void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
293 void RecordSafepoint(Safepoint::DeoptMode mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000294 void RecordSafepointWithRegisters(LPointerMap* pointers,
295 int arguments,
erikcorry0ad885c2011-11-21 13:51:57 +0000296 Safepoint::DeoptMode mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000297 void RecordSafepointWithRegistersAndDoubles(LPointerMap* pointers,
298 int arguments,
erikcorry0ad885c2011-11-21 13:51:57 +0000299 Safepoint::DeoptMode mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000300 void RecordPosition(int position);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000301
302 static Condition TokenToCondition(Token::Value op, bool is_unsigned);
303 void EmitGoto(int block);
304 void EmitBranch(int left_block,
305 int right_block,
306 Condition cc,
307 Register src1,
308 const Operand& src2);
309 void EmitBranchF(int left_block,
310 int right_block,
311 Condition cc,
312 FPURegister src1,
313 FPURegister src2);
314 void EmitCmpI(LOperand* left, LOperand* right);
315 void EmitNumberUntagD(Register input,
316 DoubleRegister result,
317 bool deoptimize_on_undefined,
ulan@chromium.org2efb9002012-01-19 15:36:35 +0000318 bool deoptimize_on_minus_zero,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000319 LEnvironment* env);
320
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000321 void DeoptIfTaggedButNotSmi(LEnvironment* environment,
322 HValue* value,
323 LOperand* operand);
324
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000325 // Emits optimized code for typeof x == "y". Modifies input register.
326 // Returns the condition on which a final split to
327 // true and false label should be made, to optimize fallthrough.
328 // Returns two registers in cmp1 and cmp2 that can be used in the
329 // Branch instruction after EmitTypeofIs.
330 Condition EmitTypeofIs(Label* true_label,
331 Label* false_label,
332 Register input,
333 Handle<String> type_name,
334 Register& cmp1,
335 Operand& cmp2);
336
337 // Emits optimized code for %_IsObject(x). Preserves input register.
338 // Returns the condition on which a final split to
339 // true and false label should be made, to optimize fallthrough.
340 Condition EmitIsObject(Register input,
341 Register temp1,
erikcorry0ad885c2011-11-21 13:51:57 +0000342 Register temp2,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000343 Label* is_not_object,
344 Label* is_object);
345
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +0000346 // Emits optimized code for %_IsString(x). Preserves input register.
347 // Returns the condition on which a final split to
348 // true and false label should be made, to optimize fallthrough.
349 Condition EmitIsString(Register input,
350 Register temp1,
351 Label* is_not_string);
352
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000353 // Emits optimized code for %_IsConstructCall().
354 // Caller should branch on equal condition.
355 void EmitIsConstructCall(Register temp1, Register temp2);
356
357 void EmitLoadFieldOrConstantFunction(Register result,
358 Register object,
359 Handle<Map> type,
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000360 Handle<String> name,
361 LEnvironment* env);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000362
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000363 // Emits optimized code to deep-copy the contents of statically known
364 // object graphs (e.g. object literal boilerplate).
365 void EmitDeepCopy(Handle<JSObject> object,
366 Register result,
367 Register source,
368 int* offset);
369
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000370 struct JumpTableEntry {
371 explicit inline JumpTableEntry(Address entry)
372 : label(),
373 address(entry) { }
374 Label label;
375 Address address;
376 };
377
erikcorry0ad885c2011-11-21 13:51:57 +0000378 void EnsureSpaceForLazyDeopt();
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000379 void DoLoadKeyedExternalArray(LLoadKeyed* instr);
380 void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr);
381 void DoLoadKeyedFixedArray(LLoadKeyed* instr);
382 void DoStoreKeyedExternalArray(LStoreKeyed* instr);
383 void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
384 void DoStoreKeyedFixedArray(LStoreKeyed* instr);
erikcorry0ad885c2011-11-21 13:51:57 +0000385
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000386 Zone* zone_;
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000387 LPlatformChunk* const chunk_;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000388 MacroAssembler* const masm_;
389 CompilationInfo* const info_;
390
391 int current_block_;
392 int current_instruction_;
393 const ZoneList<LInstruction*>* instructions_;
394 ZoneList<LEnvironment*> deoptimizations_;
395 ZoneList<JumpTableEntry> deopt_jump_table_;
396 ZoneList<Handle<Object> > deoptimization_literals_;
397 int inlined_function_count_;
398 Scope* const scope_;
399 Status status_;
400 TranslationBuffer translations_;
401 ZoneList<LDeferredCode*> deferred_;
402 int osr_pc_offset_;
erikcorry0ad885c2011-11-21 13:51:57 +0000403 int last_lazy_deopt_pc_;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000404
405 // Builder that keeps track of safepoints in the code. The table
406 // itself is emitted at the end of the generated code.
407 SafepointTableBuilder safepoints_;
408
409 // Compiler from a set of parallel moves to a sequential list of moves.
410 LGapResolver resolver_;
411
412 Safepoint::Kind expected_safepoint_kind_;
413
414 class PushSafepointRegistersScope BASE_EMBEDDED {
415 public:
416 PushSafepointRegistersScope(LCodeGen* codegen,
417 Safepoint::Kind kind)
418 : codegen_(codegen) {
419 ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
420 codegen_->expected_safepoint_kind_ = kind;
421
422 switch (codegen_->expected_safepoint_kind_) {
423 case Safepoint::kWithRegisters:
424 codegen_->masm_->PushSafepointRegisters();
425 break;
426 case Safepoint::kWithRegistersAndDoubles:
427 codegen_->masm_->PushSafepointRegistersAndDoubles();
428 break;
429 default:
430 UNREACHABLE();
431 }
432 }
433
434 ~PushSafepointRegistersScope() {
435 Safepoint::Kind kind = codegen_->expected_safepoint_kind_;
436 ASSERT((kind & Safepoint::kWithRegisters) != 0);
437 switch (kind) {
438 case Safepoint::kWithRegisters:
439 codegen_->masm_->PopSafepointRegisters();
440 break;
441 case Safepoint::kWithRegistersAndDoubles:
442 codegen_->masm_->PopSafepointRegistersAndDoubles();
443 break;
444 default:
445 UNREACHABLE();
446 }
447 codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
448 }
449
450 private:
451 LCodeGen* codegen_;
452 };
453
454 friend class LDeferredCode;
455 friend class LEnvironment;
456 friend class SafepointGenerator;
457 DISALLOW_COPY_AND_ASSIGN(LCodeGen);
458};
459
460
461class LDeferredCode: public ZoneObject {
462 public:
463 explicit LDeferredCode(LCodeGen* codegen)
464 : codegen_(codegen),
465 external_exit_(NULL),
466 instruction_index_(codegen->current_instruction_) {
467 codegen->AddDeferredCode(this);
468 }
469
470 virtual ~LDeferredCode() { }
471 virtual void Generate() = 0;
472 virtual LInstruction* instr() = 0;
473
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000474 void SetExit(Label* exit) { external_exit_ = exit; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000475 Label* entry() { return &entry_; }
476 Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
477 int instruction_index() const { return instruction_index_; }
478
479 protected:
480 LCodeGen* codegen() const { return codegen_; }
481 MacroAssembler* masm() const { return codegen_->masm(); }
482
483 private:
484 LCodeGen* codegen_;
485 Label entry_;
486 Label exit_;
487 Label* external_exit_;
488 int instruction_index_;
lrn@chromium.org7516f052011-03-30 08:52:27 +0000489};
ager@chromium.org5c838252010-02-19 08:53:10 +0000490
491} } // namespace v8::internal
492
lrn@chromium.org7516f052011-03-30 08:52:27 +0000493#endif // V8_MIPS_LITHIUM_CODEGEN_MIPS_H_