105ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
45c838251403b0be9a882540f1922577abba4c872ager@chromium.org
57516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#ifndef V8_MIPS_LITHIUM_CODEGEN_MIPS_H_
67516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#define V8_MIPS_LITHIUM_CODEGEN_MIPS_H_
75c838251403b0be9a882540f1922577abba4c872ager@chromium.org
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/deoptimizer.h"
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/mips/lithium-gap-resolver-mips.h"
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/mips/lithium-mips.h"
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/lithium-codegen.h"
12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/safepoint-table.h"
13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/scopes.h"
14196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/utils.h"
157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
165c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace v8 {
175c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace internal {
185c838251403b0be9a882540f1922577abba4c872ager@chromium.org
197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Forward declarations.
207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgclass LDeferredCode;
21c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.orgclass SafepointGenerator;
22ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
23d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.orgclass LCodeGen: public LCodeGenBase {
247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org public:
255a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
26d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org      : LCodeGenBase(chunk, assembler, info),
275a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        deoptimizations_(4, info->zone()),
285a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        deopt_jump_table_(4, info->zone()),
295a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        deoptimization_literals_(8, info->zone()),
30c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        inlined_function_count_(0),
31c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        scope_(info->scope()),
325a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        translations_(info->zone()),
335a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        deferred_(8, info->zone()),
34c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        osr_pc_offset_(-1),
3559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        frame_is_built_(false),
365a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org        safepoints_(info->zone()),
37c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        resolver_(this),
3871f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org        expected_safepoint_kind_(Safepoint::kSimple) {
39c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    PopulateDeoptimizationLiteralsWithInlinedFunctions();
40c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
41c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
42c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
4332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  int LookupDestination(int block_id) const {
4432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    return chunk()->LookupDestination(block_id);
4532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  }
4632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org
4732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  bool IsNextEmittedBlock(int block_id) const {
4832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org    return LookupDestination(block_id) == GetNextEmittedBlock();
4932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  }
5032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org
5159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  bool NeedsEagerFrame() const {
5259297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return GetStackSlotCount() > 0 ||
5359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org        info()->is_non_deferred_calling() ||
5477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org        !info()->IsStub() ||
5577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org        info()->requires_frame();
5659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  }
5759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  bool NeedsDeferredFrame() const {
5859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org    return !NeedsEagerFrame() && info()->is_deferred_calling();
5959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  }
6059297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
61c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  RAStatus GetRAState() const {
62c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org    return frame_is_built_ ? kRAHasBeenSaved : kRAHasNotBeenSaved;
63c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org  }
64c99cd48a7a41dae45e3b166f9d71a3dd1f76fa27danno@chromium.org
65c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Support for converting LOperands to assembler types.
66c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // LOperand must be a register.
67c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register ToRegister(LOperand* op) const;
68c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
69c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // LOperand is loaded into scratch, unless already a register.
70c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register EmitLoadRegister(LOperand* op, Register scratch);
71c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
72c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // LOperand must be a double register.
73c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DoubleRegister ToDoubleRegister(LOperand* op) const;
74c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
75c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // LOperand is loaded into dbl_scratch, unless already a double register.
76c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DoubleRegister EmitLoadDoubleRegister(LOperand* op,
77c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                        FloatRegister flt_scratch,
78c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                        DoubleRegister dbl_scratch);
79594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  int32_t ToRepresentation(LConstantOperand* op, const Representation& r) const;
80fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  int32_t ToInteger32(LConstantOperand* op) const;
81b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org  Smi* ToSmi(LConstantOperand* op) const;
82c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  double ToDouble(LConstantOperand* op) const;
83c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Operand ToOperand(LOperand* op);
84c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  MemOperand ToMemOperand(LOperand* op) const;
85c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Returns a MemOperand pointing to the high word of a DoubleStackSlot.
86c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  MemOperand ToHighMemOperand(LOperand* op) const;
87fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org
88fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  bool IsInteger32(LConstantOperand* op) const;
89a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org  bool IsSmi(LConstantOperand* op) const;
90fab1498f2f42726c7de46c3ed560d56dd072a8b3rossberg@chromium.org  Handle<Object> ToHandle(LConstantOperand* op) const;
915c838251403b0be9a882540f1922577abba4c872ager@chromium.org
927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Try to generate code for the entire chunk, but it may fail if the
937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // chunk contains constructs we cannot handle. Returns true if the
947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // code generation attempt succeeded.
95c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  bool GenerateCode();
965c838251403b0be9a882540f1922577abba4c872ager@chromium.org
977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Finish the code by setting stack height, safepoint, and bailout
987516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // information on it.
99c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void FinishCode(Handle<Code> code);
100c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
101c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void DoDeferredNumberTagD(LNumberTagD* instr);
10278502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
10378502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org  enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
104bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org  void DoDeferredNumberTagIU(LInstruction* instr,
105bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org                             LOperand* value,
106bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org                             LOperand* temp1,
107bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org                             LOperand* temp2,
108bc176057ae476990672de915df235c9aeadc8521titzer@chromium.org                             IntegerSignedness signedness);
10978502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org
110c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void DoDeferredTaggedToI(LTaggedToI* instr);
111e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
112c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void DoDeferredStackCheck(LStackCheck* instr);
113c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
114c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
1157c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org  void DoDeferredAllocate(LAllocate* instr);
1160ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
1170ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                                       Label* map_check);
118c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
119594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void DoDeferredInstanceMigration(LCheckMaps* instr, Register object);
120ab43d2fe8b76a093650c03e80a89b6344b6be49emachenbach@chromium.org  void DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
121ab43d2fe8b76a093650c03e80a89b6344b6be49emachenbach@chromium.org                                   Register result,
122ab43d2fe8b76a093650c03e80a89b6344b6be49emachenbach@chromium.org                                   Register object,
123ab43d2fe8b76a093650c03e80a89b6344b6be49emachenbach@chromium.org                                   Register index);
12405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org
125c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Parallel move support.
126c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void DoParallelMove(LParallelMove* move);
127c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void DoGap(LGap* instr);
128c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
129129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org  MemOperand PrepareKeyedOperand(Register key,
130129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org                                 Register base,
131129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org                                 bool key_is_constant,
132129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org                                 int constant_key,
133129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org                                 int element_size,
134129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org                                 int shift_size,
135fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org                                 int base_offset);
136129d398d682e6ca3910808c913212ce532f1e155danno@chromium.org
137c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Emit frame translation commands for an environment.
138b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  void WriteTranslation(LEnvironment* environment, Translation* translation);
139c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
140c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Declare methods that deal with the individual node types.
141c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#define DECLARE_DO(type) void Do##type(L##type* node);
142c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
143c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org#undef DECLARE_DO
144c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
145c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org private:
146486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  StrictMode strict_mode() const { return info()->strict_mode(); }
147c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
148c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Scope* scope() const { return scope_; }
149c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
150f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  Register scratch0() { return kLithiumScratchReg; }
151f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  Register scratch1() { return kLithiumScratchReg2; }
152f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  DoubleRegister double_scratch0() { return kLithiumScratchDouble; }
153c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
154c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  LInstruction* GetNextInstruction();
155c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
156c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void EmitClassOfTest(Label* if_true,
157c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       Label* if_false,
158c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       Handle<String> class_name,
159c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       Register input,
160c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       Register temporary,
161c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       Register temporary2);
162c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
163c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
164c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
1657028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
166c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
167f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  void SaveCallerDoubles();
168f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  void RestoreCallerDoubles();
169f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org
170c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Code generation passes.  Returns true if code generation should
171c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // continue.
172486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  void GenerateBodyInstructionPre(LInstruction* instr) V8_OVERRIDE;
173c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  bool GeneratePrologue();
174c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  bool GenerateDeferredCode();
175c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  bool GenerateDeoptJumpTable();
176c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  bool GenerateSafepointTable();
177c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
178c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  // Generates the custom OSR entrypoint and sets the osr_pc_offset.
179c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org  void GenerateOsrPrologue();
180c5d4971574b7a205fa0e788d8121dc79485e5e67hpayer@chromium.org
181c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  enum SafepointMode {
182c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    RECORD_SIMPLE_SAFEPOINT,
183c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS
184c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  };
185c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
186c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void CallCode(Handle<Code> code,
187c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                RelocInfo::Mode mode,
188c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                LInstruction* instr);
189c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
190c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void CallCodeGeneric(Handle<Code> code,
191c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       RelocInfo::Mode mode,
192c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       LInstruction* instr,
193c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       SafepointMode safepoint_mode);
194c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
195c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void CallRuntime(const Runtime::Function* function,
196c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                   int num_arguments,
197fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                   LInstruction* instr,
198fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                   SaveFPRegsMode save_doubles = kDontSaveFPRegs);
199c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
200c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void CallRuntime(Runtime::FunctionId id,
201c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                   int num_arguments,
202c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                   LInstruction* instr) {
203c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    const Runtime::Function* function = Runtime::FunctionForId(id);
204c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    CallRuntime(function, num_arguments, instr);
205c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
206c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
207fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  void LoadContextFromDeferred(LOperand* context);
208c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void CallRuntimeFromDeferred(Runtime::FunctionId id,
209c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                               int argc,
210fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                               LInstruction* instr,
211fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                               LOperand* context);
212c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
213fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org  enum A1State {
214fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org    A1_UNINITIALIZED,
215fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org    A1_CONTAINS_TARGET
216fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org  };
217fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org
218c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Generate a direct call to a known function.  Expects the function
219c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // to be in a1.
220c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void CallKnownFunction(Handle<JSFunction> function,
22132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                         int formal_parameter_count,
222c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                         int arity,
223c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                         LInstruction* instr,
224fb0463312815affb1f0e9d5e351b7f9a3422e3a2svenpanne@chromium.org                         A1State a1_state);
225c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2260ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  void RecordSafepointWithLazyDeopt(LInstruction* instr,
2270ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                                    SafepointMode safepoint_mode);
228c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
2290ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
2300ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                                            Safepoint::DeoptMode mode);
231c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  void DeoptimizeIf(Condition condition,
232c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                    LEnvironment* environment,
2330410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com                    Deoptimizer::BailoutType bailout_type,
23405ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                    Register src1 = zero_reg,
23505ed9ddc6ff3a1ab3983c50d378cddfa257869b6jkummerow@chromium.org                    const Operand& src2 = Operand(zero_reg));
236c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  void DeoptimizeIf(Condition condition,
2370410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com                    LEnvironment* environment,
2380410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com                    Register src1 = zero_reg,
2390410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com                    const Operand& src2 = Operand(zero_reg));
240c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
241594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void AddToTranslation(LEnvironment* environment,
242594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                        Translation* translation,
243c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                        LOperand* op,
24478502a9310f9ff7ecb5377453c4e16d091c93676jkummerow@chromium.org                        bool is_tagged,
245594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                        bool is_uint32,
246594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                        int* object_index_pointer,
247594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org                        int* dematerialized_index_pointer);
248c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void PopulateDeoptimizationData(Handle<Code> code);
249c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int DefineDeoptimizationLiteral(Handle<Object> literal);
250c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
251c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void PopulateDeoptimizationLiteralsWithInlinedFunctions();
252c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
253c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Register ToRegister(int index) const;
254c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DoubleRegister ToDoubleRegister(int index) const;
255c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
256e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  MemOperand BuildSeqStringOperand(Register string,
257e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                                   LOperand* index,
258e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                                   String::Encoding encoding);
259e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
260e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  void EmitIntegerMathAbs(LMathAbs* instr);
261c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
262c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Support for recording safepoint and position information.
263c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void RecordSafepoint(LPointerMap* pointers,
264c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       Safepoint::Kind kind,
265c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                       int arguments,
2660ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                       Safepoint::DeoptMode mode);
2670ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
2680ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry  void RecordSafepoint(Safepoint::DeoptMode mode);
269c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void RecordSafepointWithRegisters(LPointerMap* pointers,
270c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                    int arguments,
2710ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                                    Safepoint::DeoptMode mode);
272c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void RecordSafepointWithRegistersAndDoubles(LPointerMap* pointers,
273c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                              int arguments,
2740ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                                              Safepoint::DeoptMode mode);
27571f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org
27671f9fca5cfb606009211e0631f33b76cc2ddce3cbmeurer@chromium.org  void RecordAndWritePosition(int position) V8_OVERRIDE;
277c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
278c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  static Condition TokenToCondition(Token::Value op, bool is_unsigned);
279c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void EmitGoto(int block);
2800cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org
2810cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  // EmitBranch expects to be the last instruction of a block.
2821510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  template<class InstrType>
2831510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  void EmitBranch(InstrType instr,
284c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com                  Condition condition,
285c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                  Register src1,
286c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                  const Operand& src2);
2871510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  template<class InstrType>
2881510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  void EmitBranchF(InstrType instr,
289c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com                   Condition condition,
290c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                   FPURegister src1,
291c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                   FPURegister src2);
292c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  template<class InstrType>
2930cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  void EmitFalseBranch(InstrType instr,
2940cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org                       Condition condition,
2950cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org                       Register src1,
2960cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org                       const Operand& src2);
2970cc095007a3ccded63f6577751c6a04300eb7ae9machenbach@chromium.org  template<class InstrType>
298c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com  void EmitFalseBranchF(InstrType instr,
299c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com                        Condition condition,
300c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com                        FPURegister src1,
301c4c71ea2d66514cf02679bc673c5ba8c9406bad8palfia@homejinni.com                        FPURegister src2);
302c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void EmitCmpI(LOperand* left, LOperand* right);
303c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void EmitNumberUntagD(Register input,
304c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                        DoubleRegister result,
305b99c75496e05b4cd58815ada1e39e6029130d11crossberg@chromium.org                        bool allow_undefined_as_nan,
3062efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org                        bool deoptimize_on_minus_zero,
3077c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org                        LEnvironment* env,
3087c3372bc426136cb79479c1b59d1770f5528882ahpayer@chromium.org                        NumberUntagDMode mode);
30946839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org
310c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Emits optimized code for typeof x == "y".  Modifies input register.
311c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Returns the condition on which a final split to
312c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // true and false label should be made, to optimize fallthrough.
313c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Returns two registers in cmp1 and cmp2 that can be used in the
314c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Branch instruction after EmitTypeofIs.
315c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Condition EmitTypeofIs(Label* true_label,
316c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                         Label* false_label,
317c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                         Register input,
318c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                         Handle<String> type_name,
319196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                         Register* cmp1,
320196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                         Operand* cmp2);
321c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
322c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Emits optimized code for %_IsObject(x).  Preserves input register.
323c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Returns the condition on which a final split to
324c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // true and false label should be made, to optimize fallthrough.
325c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Condition EmitIsObject(Register input,
326c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                         Register temp1,
3270ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry                         Register temp2,
328c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                         Label* is_not_object,
329c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                         Label* is_object);
330c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
331f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org  // Emits optimized code for %_IsString(x).  Preserves input register.
332f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org  // Returns the condition on which a final split to
333f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org  // true and false label should be made, to optimize fallthrough.
334f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org  Condition EmitIsString(Register input,
335f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org                         Register temp1,
3361510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                         Label* is_not_string,
3371510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org                         SmiCheck check_needed);
338f8c6bd531c2a8ba717cb8d316206347b05acebedmstarzinger@chromium.org
339c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Emits optimized code for %_IsConstructCall().
340c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Caller should branch on equal condition.
341c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void EmitIsConstructCall(Register temp1, Register temp2);
342c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
34364e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // Emits optimized code to deep-copy the contents of statically known
34464e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  // object graphs (e.g. object literal boilerplate).
34564e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org  void EmitDeepCopy(Handle<JSObject> object,
34664e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org                    Register result,
34764e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org                    Register source,
34828381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org                    int* offset,
34928381b491d5ea9f256a3937000de7953639ef93fyangguo@chromium.org                    AllocationSiteMode mode);
350b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  // Emit optimized code for integer division.
351b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  // Inputs are signed.
352b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  // All registers are clobbered.
353b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  // If 'remainder' is no_reg, it is not computed.
354b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org  void EmitSignedIntegerDivisionByConstant(Register result,
355b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                           Register dividend,
356b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                           int32_t divisor,
357b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                           Register remainder,
358b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                           Register scratch,
359b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                           LEnvironment* environment);
360b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org
36164e3a4be4a99f31920128de34573c8ac9038de42ricow@chromium.org
362d8a3a149cb9dac7437e264a2fe50f680418c3a45jkummerow@chromium.org  void EnsureSpaceForLazyDeopt(int space_needed) V8_OVERRIDE;
363e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  void DoLoadKeyedExternalArray(LLoadKeyed* instr);
364e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr);
365e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  void DoLoadKeyedFixedArray(LLoadKeyed* instr);
366e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  void DoStoreKeyedExternalArray(LStoreKeyed* instr);
367e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
368e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  void DoStoreKeyedFixedArray(LStoreKeyed* instr);
3690ad885c06ff6a0d68bc9ad75629f7ddfaa6860b9erikcorry
370c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ZoneList<LEnvironment*> deoptimizations_;
3710410973aac1fa3a7aa16285ba799f531983bc916palfia@homejinni.com  ZoneList<Deoptimizer::JumpTableEntry> deopt_jump_table_;
372c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ZoneList<Handle<Object> > deoptimization_literals_;
373c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int inlined_function_count_;
374c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Scope* const scope_;
375c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  TranslationBuffer translations_;
376c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  ZoneList<LDeferredCode*> deferred_;
377c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int osr_pc_offset_;
37859297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  bool frame_is_built_;
379c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
380c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Builder that keeps track of safepoints in the code. The table
381c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // itself is emitted at the end of the generated code.
382c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  SafepointTableBuilder safepoints_;
383c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
384c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Compiler from a set of parallel moves to a sequential list of moves.
385c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  LGapResolver resolver_;
386c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
387c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Safepoint::Kind expected_safepoint_kind_;
388c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
38932cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  class PushSafepointRegistersScope V8_FINAL  BASE_EMBEDDED {
390c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org   public:
391c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    PushSafepointRegistersScope(LCodeGen* codegen,
392c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org                                Safepoint::Kind kind)
393c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        : codegen_(codegen) {
39459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org      ASSERT(codegen_->info()->is_calling());
395c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
396c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      codegen_->expected_safepoint_kind_ = kind;
397c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
398c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      switch (codegen_->expected_safepoint_kind_) {
3994954674151afa960af66efb4831df06bde727333yangguo@chromium.org        case Safepoint::kWithRegisters: {
400f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org          StoreRegistersStateStub stub1(codegen_->masm_->isolate(),
401f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org                                        kDontSaveFPRegs);
4024954674151afa960af66efb4831df06bde727333yangguo@chromium.org          codegen_->masm_->push(ra);
4034954674151afa960af66efb4831df06bde727333yangguo@chromium.org          codegen_->masm_->CallStub(&stub1);
404c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          break;
4054954674151afa960af66efb4831df06bde727333yangguo@chromium.org        }
4064954674151afa960af66efb4831df06bde727333yangguo@chromium.org        case Safepoint::kWithRegistersAndDoubles: {
407f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org          StoreRegistersStateStub stub2(codegen_->masm_->isolate(),
408f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org                                        kSaveFPRegs);
4094954674151afa960af66efb4831df06bde727333yangguo@chromium.org          codegen_->masm_->push(ra);
4104954674151afa960af66efb4831df06bde727333yangguo@chromium.org          codegen_->masm_->CallStub(&stub2);
411c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          break;
4124954674151afa960af66efb4831df06bde727333yangguo@chromium.org        }
413c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        default:
414c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          UNREACHABLE();
415c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      }
416c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
417c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
418c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    ~PushSafepointRegistersScope() {
419c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      Safepoint::Kind kind = codegen_->expected_safepoint_kind_;
420c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      ASSERT((kind & Safepoint::kWithRegisters) != 0);
421c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      switch (kind) {
4224954674151afa960af66efb4831df06bde727333yangguo@chromium.org        case Safepoint::kWithRegisters: {
423f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org          RestoreRegistersStateStub stub1(codegen_->masm_->isolate(),
424f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org                                          kDontSaveFPRegs);
4254954674151afa960af66efb4831df06bde727333yangguo@chromium.org          codegen_->masm_->push(ra);
4264954674151afa960af66efb4831df06bde727333yangguo@chromium.org          codegen_->masm_->CallStub(&stub1);
427c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          break;
4284954674151afa960af66efb4831df06bde727333yangguo@chromium.org        }
4294954674151afa960af66efb4831df06bde727333yangguo@chromium.org        case Safepoint::kWithRegistersAndDoubles: {
430f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org          RestoreRegistersStateStub stub2(codegen_->masm_->isolate(),
431f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org                                          kSaveFPRegs);
4324954674151afa960af66efb4831df06bde727333yangguo@chromium.org          codegen_->masm_->push(ra);
4334954674151afa960af66efb4831df06bde727333yangguo@chromium.org          codegen_->masm_->CallStub(&stub2);
434c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          break;
4354954674151afa960af66efb4831df06bde727333yangguo@chromium.org        }
436c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        default:
437c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org          UNREACHABLE();
438c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      }
439c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
440c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    }
441c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
442c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org   private:
443c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    LCodeGen* codegen_;
444c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  };
445c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
446c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  friend class LDeferredCode;
447c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  friend class LEnvironment;
448c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  friend class SafepointGenerator;
449c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  DISALLOW_COPY_AND_ASSIGN(LCodeGen);
450c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org};
451c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
452c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
45332cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.orgclass LDeferredCode : public ZoneObject {
454c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org public:
455c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  explicit LDeferredCode(LCodeGen* codegen)
456c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org      : codegen_(codegen),
457c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        external_exit_(NULL),
458c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org        instruction_index_(codegen->current_instruction_) {
459c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org    codegen->AddDeferredCode(this);
460c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  }
461c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
46232cb9b2c195baa85d4c04f4c7b22b9aa04e97d3fverwaest@chromium.org  virtual ~LDeferredCode() {}
463c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  virtual void Generate() = 0;
464c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  virtual LInstruction* instr() = 0;
465c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
466f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  void SetExit(Label* exit) { external_exit_ = exit; }
467c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label* entry() { return &entry_; }
468c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
469c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int instruction_index() const { return instruction_index_; }
470c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
471c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org protected:
472c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  LCodeGen* codegen() const { return codegen_; }
473c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  MacroAssembler* masm() const { return codegen_->masm(); }
474c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org
475c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org private:
476c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  LCodeGen* codegen_;
477c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label entry_;
478c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label exit_;
479c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Label* external_exit_;
480c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  int instruction_index_;
4817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org};
4825c838251403b0be9a882540f1922577abba4c872ager@chromium.org
4835c838251403b0be9a882540f1922577abba4c872ager@chromium.org} }  // namespace v8::internal
4845c838251403b0be9a882540f1922577abba4c872ager@chromium.org
4857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#endif  // V8_MIPS_LITHIUM_CODEGEN_MIPS_H_
486