blob: 691559a11a5bba82a184b108e9135152bd38f401 [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 "deoptimizer.h"
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +000032#include "mips/lithium-gap-resolver-mips.h"
33#include "mips/lithium-mips.h"
jkummerow@chromium.orgd8a3a142013-10-03 12:15:05 +000034#include "lithium-codegen.h"
lrn@chromium.org7516f052011-03-30 08:52:27 +000035#include "safepoint-table.h"
36#include "scopes.h"
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +000037#include "v8utils.h"
lrn@chromium.org7516f052011-03-30 08:52:27 +000038
ager@chromium.org5c838252010-02-19 08:53:10 +000039namespace v8 {
40namespace internal {
41
lrn@chromium.org7516f052011-03-30 08:52:27 +000042// Forward declarations.
43class LDeferredCode;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000044class SafepointGenerator;
ager@chromium.org5c838252010-02-19 08:53:10 +000045
jkummerow@chromium.orgd8a3a142013-10-03 12:15:05 +000046class LCodeGen: public LCodeGenBase {
lrn@chromium.org7516f052011-03-30 08:52:27 +000047 public:
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000048 LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
jkummerow@chromium.orgd8a3a142013-10-03 12:15:05 +000049 : LCodeGenBase(chunk, assembler, info),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000050 deoptimizations_(4, info->zone()),
51 deopt_jump_table_(4, info->zone()),
52 deoptimization_literals_(8, info->zone()),
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000053 inlined_function_count_(0),
54 scope_(info->scope()),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000055 translations_(info->zone()),
56 deferred_(8, info->zone()),
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000057 osr_pc_offset_(-1),
jkummerow@chromium.org59297c72013-01-09 16:32:23 +000058 frame_is_built_(false),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000059 safepoints_(info->zone()),
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000060 resolver_(this),
bmeurer@chromium.org71f9fca2013-10-22 08:00:09 +000061 expected_safepoint_kind_(Safepoint::kSimple) {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000062 PopulateDeoptimizationLiteralsWithInlinedFunctions();
63 }
64
65
ulan@chromium.org32d7dba2013-04-24 10:59:06 +000066 int LookupDestination(int block_id) const {
67 return chunk()->LookupDestination(block_id);
68 }
69
70 bool IsNextEmittedBlock(int block_id) const {
71 return LookupDestination(block_id) == GetNextEmittedBlock();
72 }
73
jkummerow@chromium.org59297c72013-01-09 16:32:23 +000074 bool NeedsEagerFrame() const {
75 return GetStackSlotCount() > 0 ||
76 info()->is_non_deferred_calling() ||
ulan@chromium.org77ca49a2013-04-22 09:43:56 +000077 !info()->IsStub() ||
78 info()->requires_frame();
jkummerow@chromium.org59297c72013-01-09 16:32:23 +000079 }
80 bool NeedsDeferredFrame() const {
81 return !NeedsEagerFrame() && info()->is_deferred_calling();
82 }
83
danno@chromium.orgc99cd482013-03-21 15:26:42 +000084 RAStatus GetRAState() const {
85 return frame_is_built_ ? kRAHasBeenSaved : kRAHasNotBeenSaved;
86 }
87
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000088 // Support for converting LOperands to assembler types.
89 // LOperand must be a register.
90 Register ToRegister(LOperand* op) const;
91
92 // LOperand is loaded into scratch, unless already a register.
93 Register EmitLoadRegister(LOperand* op, Register scratch);
94
95 // LOperand must be a double register.
96 DoubleRegister ToDoubleRegister(LOperand* op) const;
97
98 // LOperand is loaded into dbl_scratch, unless already a double register.
99 DoubleRegister EmitLoadDoubleRegister(LOperand* op,
100 FloatRegister flt_scratch,
101 DoubleRegister dbl_scratch);
danno@chromium.org59400602013-08-13 17:09:37 +0000102 int32_t ToRepresentation(LConstantOperand* op, const Representation& r) const;
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000103 int32_t ToInteger32(LConstantOperand* op) const;
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +0000104 Smi* ToSmi(LConstantOperand* op) const;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000105 double ToDouble(LConstantOperand* op) const;
106 Operand ToOperand(LOperand* op);
107 MemOperand ToMemOperand(LOperand* op) const;
108 // Returns a MemOperand pointing to the high word of a DoubleStackSlot.
109 MemOperand ToHighMemOperand(LOperand* op) const;
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000110
rossberg@chromium.orgfab14982012-01-05 15:02:15 +0000111 bool IsInteger32(LConstantOperand* op) const;
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +0000112 bool IsSmi(LConstantOperand* op) const;
rossberg@chromium.orgfab14982012-01-05 15:02:15 +0000113 Handle<Object> ToHandle(LConstantOperand* op) const;
114
lrn@chromium.org7516f052011-03-30 08:52:27 +0000115 // Try to generate code for the entire chunk, but it may fail if the
116 // chunk contains constructs we cannot handle. Returns true if the
117 // code generation attempt succeeded.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000118 bool GenerateCode();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000119
lrn@chromium.org7516f052011-03-30 08:52:27 +0000120 // Finish the code by setting stack height, safepoint, and bailout
121 // information on it.
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000122 void FinishCode(Handle<Code> code);
123
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000124 void DoDeferredNumberTagD(LNumberTagD* instr);
jkummerow@chromium.org78502a92012-09-06 13:50:42 +0000125
126 enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
titzer@chromium.orgbc176052014-03-05 15:10:53 +0000127 void DoDeferredNumberTagIU(LInstruction* instr,
128 LOperand* value,
129 LOperand* temp1,
130 LOperand* temp2,
131 IntegerSignedness signedness);
jkummerow@chromium.org78502a92012-09-06 13:50:42 +0000132
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000133 void DoDeferredTaggedToI(LTaggedToI* instr);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000134 void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000135 void DoDeferredStackCheck(LStackCheck* instr);
136 void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
137 void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000138 void DoDeferredAllocate(LAllocate* instr);
erikcorry0ad885c2011-11-21 13:51:57 +0000139 void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
140 Label* map_check);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000141
danno@chromium.org59400602013-08-13 17:09:37 +0000142 void DoDeferredInstanceMigration(LCheckMaps* instr, Register object);
machenbach@chromium.orgab43d2f2014-04-01 06:35:49 +0000143 void DoDeferredLoadMutableDouble(LLoadFieldByIndex* instr,
144 Register result,
145 Register object,
146 Register index);
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000147
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000148 // Parallel move support.
149 void DoParallelMove(LParallelMove* move);
150 void DoGap(LGap* instr);
151
danno@chromium.org129d3982012-07-25 15:01:47 +0000152 MemOperand PrepareKeyedOperand(Register key,
153 Register base,
154 bool key_is_constant,
155 int constant_key,
156 int element_size,
157 int shift_size,
158 int additional_index,
159 int additional_offset);
160
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000161 // Emit frame translation commands for an environment.
dslomov@chromium.orgb752d402013-06-18 11:54:54 +0000162 void WriteTranslation(LEnvironment* environment, Translation* translation);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000163
164 // Declare methods that deal with the individual node types.
165#define DECLARE_DO(type) void Do##type(L##type* node);
166 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
167#undef DECLARE_DO
168
169 private:
dslomov@chromium.org486536d2014-03-12 13:09:18 +0000170 StrictMode strict_mode() const { return info()->strict_mode(); }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000171
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000172 Scope* scope() const { return scope_; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000173
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000174 Register scratch0() { return kLithiumScratchReg; }
175 Register scratch1() { return kLithiumScratchReg2; }
176 DoubleRegister double_scratch0() { return kLithiumScratchDouble; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000177
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000178 LInstruction* GetNextInstruction();
179
180 void EmitClassOfTest(Label* if_true,
181 Label* if_false,
182 Handle<String> class_name,
183 Register input,
184 Register temporary,
185 Register temporary2);
186
187 int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000188
danno@chromium.org59400602013-08-13 17:09:37 +0000189 void Abort(BailoutReason reason);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000190
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000191 void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000192
machenbach@chromium.orgf9841892013-11-25 12:01:13 +0000193 void SaveCallerDoubles();
194 void RestoreCallerDoubles();
195
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000196 // Code generation passes. Returns true if code generation should
197 // continue.
dslomov@chromium.org486536d2014-03-12 13:09:18 +0000198 void GenerateBodyInstructionPre(LInstruction* instr) V8_OVERRIDE;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000199 bool GeneratePrologue();
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000200 bool GenerateDeferredCode();
201 bool GenerateDeoptJumpTable();
202 bool GenerateSafepointTable();
203
hpayer@chromium.orgc5d49712013-09-11 08:25:48 +0000204 // Generates the custom OSR entrypoint and sets the osr_pc_offset.
205 void GenerateOsrPrologue();
206
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000207 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,
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +0000223 LInstruction* instr,
224 SaveFPRegsMode save_doubles = kDontSaveFPRegs);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000225
226 void CallRuntime(Runtime::FunctionId id,
227 int num_arguments,
228 LInstruction* instr) {
229 const Runtime::Function* function = Runtime::FunctionForId(id);
230 CallRuntime(function, num_arguments, instr);
231 }
232
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +0000233 void LoadContextFromDeferred(LOperand* context);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000234 void CallRuntimeFromDeferred(Runtime::FunctionId id,
235 int argc,
jkummerow@chromium.orgfb7a7c42013-10-02 11:41:02 +0000236 LInstruction* instr,
237 LOperand* context);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000238
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +0000239 enum A1State {
240 A1_UNINITIALIZED,
241 A1_CONTAINS_TARGET
242 };
243
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000244 // Generate a direct call to a known function. Expects the function
245 // to be in a1.
246 void CallKnownFunction(Handle<JSFunction> function,
ulan@chromium.org32d7dba2013-04-24 10:59:06 +0000247 int formal_parameter_count,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000248 int arity,
249 LInstruction* instr,
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +0000250 A1State a1_state);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000251
erikcorry0ad885c2011-11-21 13:51:57 +0000252 void RecordSafepointWithLazyDeopt(LInstruction* instr,
253 SafepointMode safepoint_mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000254
erikcorry0ad885c2011-11-21 13:51:57 +0000255 void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
256 Safepoint::DeoptMode mode);
palfia@homejinni.comc4c71ea2013-08-15 08:05:35 +0000257 void DeoptimizeIf(Condition condition,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000258 LEnvironment* environment,
palfia@homejinni.com04109732013-05-15 09:50:32 +0000259 Deoptimizer::BailoutType bailout_type,
jkummerow@chromium.org05ed9dd2012-01-23 14:42:48 +0000260 Register src1 = zero_reg,
261 const Operand& src2 = Operand(zero_reg));
palfia@homejinni.comc4c71ea2013-08-15 08:05:35 +0000262 void DeoptimizeIf(Condition condition,
palfia@homejinni.com04109732013-05-15 09:50:32 +0000263 LEnvironment* environment,
264 Register src1 = zero_reg,
265 const Operand& src2 = Operand(zero_reg));
palfia@homejinni.comc4c71ea2013-08-15 08:05:35 +0000266 void ApplyCheckIf(Condition condition,
jkummerow@chromium.orgfb732b12013-07-26 10:27:09 +0000267 LBoundsCheck* check,
268 Register src1 = zero_reg,
269 const Operand& src2 = Operand(zero_reg));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000270
danno@chromium.org59400602013-08-13 17:09:37 +0000271 void AddToTranslation(LEnvironment* environment,
272 Translation* translation,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000273 LOperand* op,
jkummerow@chromium.org78502a92012-09-06 13:50:42 +0000274 bool is_tagged,
danno@chromium.org59400602013-08-13 17:09:37 +0000275 bool is_uint32,
276 int* object_index_pointer,
277 int* dematerialized_index_pointer);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000278 void PopulateDeoptimizationData(Handle<Code> code);
279 int DefineDeoptimizationLiteral(Handle<Object> literal);
280
281 void PopulateDeoptimizationLiteralsWithInlinedFunctions();
282
283 Register ToRegister(int index) const;
284 DoubleRegister ToDoubleRegister(int index) const;
285
machenbach@chromium.orge8412be2013-11-08 10:23:52 +0000286 MemOperand BuildSeqStringOperand(Register string,
287 LOperand* index,
288 String::Encoding encoding);
289
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000290 void EmitIntegerMathAbs(LMathAbs* instr);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000291
292 // Support for recording safepoint and position information.
293 void RecordSafepoint(LPointerMap* pointers,
294 Safepoint::Kind kind,
295 int arguments,
erikcorry0ad885c2011-11-21 13:51:57 +0000296 Safepoint::DeoptMode mode);
297 void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
298 void RecordSafepoint(Safepoint::DeoptMode mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000299 void RecordSafepointWithRegisters(LPointerMap* pointers,
300 int arguments,
erikcorry0ad885c2011-11-21 13:51:57 +0000301 Safepoint::DeoptMode mode);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000302 void RecordSafepointWithRegistersAndDoubles(LPointerMap* pointers,
303 int arguments,
erikcorry0ad885c2011-11-21 13:51:57 +0000304 Safepoint::DeoptMode mode);
bmeurer@chromium.org71f9fca2013-10-22 08:00:09 +0000305
306 void RecordAndWritePosition(int position) V8_OVERRIDE;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000307
308 static Condition TokenToCondition(Token::Value op, bool is_unsigned);
309 void EmitGoto(int block);
machenbach@chromium.org0cc09502013-11-13 12:20:55 +0000310
311 // EmitBranch expects to be the last instruction of a block.
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000312 template<class InstrType>
313 void EmitBranch(InstrType instr,
palfia@homejinni.comc4c71ea2013-08-15 08:05:35 +0000314 Condition condition,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000315 Register src1,
316 const Operand& src2);
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000317 template<class InstrType>
318 void EmitBranchF(InstrType instr,
palfia@homejinni.comc4c71ea2013-08-15 08:05:35 +0000319 Condition condition,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000320 FPURegister src1,
321 FPURegister src2);
palfia@homejinni.comc4c71ea2013-08-15 08:05:35 +0000322 template<class InstrType>
machenbach@chromium.org0cc09502013-11-13 12:20:55 +0000323 void EmitFalseBranch(InstrType instr,
324 Condition condition,
325 Register src1,
326 const Operand& src2);
327 template<class InstrType>
palfia@homejinni.comc4c71ea2013-08-15 08:05:35 +0000328 void EmitFalseBranchF(InstrType instr,
329 Condition condition,
330 FPURegister src1,
331 FPURegister src2);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000332 void EmitCmpI(LOperand* left, LOperand* right);
333 void EmitNumberUntagD(Register input,
334 DoubleRegister result,
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +0000335 bool allow_undefined_as_nan,
ulan@chromium.org2efb9002012-01-19 15:36:35 +0000336 bool deoptimize_on_minus_zero,
hpayer@chromium.org7c3372b2013-02-13 17:26:04 +0000337 LEnvironment* env,
338 NumberUntagDMode mode);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000339
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000340 // Emits optimized code for typeof x == "y". Modifies input register.
341 // Returns the condition on which a final split to
342 // true and false label should be made, to optimize fallthrough.
343 // Returns two registers in cmp1 and cmp2 that can be used in the
344 // Branch instruction after EmitTypeofIs.
345 Condition EmitTypeofIs(Label* true_label,
346 Label* false_label,
347 Register input,
348 Handle<String> type_name,
349 Register& cmp1,
350 Operand& cmp2);
351
352 // Emits optimized code for %_IsObject(x). Preserves input register.
353 // Returns the condition on which a final split to
354 // true and false label should be made, to optimize fallthrough.
355 Condition EmitIsObject(Register input,
356 Register temp1,
erikcorry0ad885c2011-11-21 13:51:57 +0000357 Register temp2,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000358 Label* is_not_object,
359 Label* is_object);
360
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +0000361 // Emits optimized code for %_IsString(x). Preserves input register.
362 // Returns the condition on which a final split to
363 // true and false label should be made, to optimize fallthrough.
364 Condition EmitIsString(Register input,
365 Register temp1,
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000366 Label* is_not_string,
367 SmiCheck check_needed);
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +0000368
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000369 // Emits optimized code for %_IsConstructCall().
370 // Caller should branch on equal condition.
371 void EmitIsConstructCall(Register temp1, Register temp2);
372
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000373 // Emits optimized code to deep-copy the contents of statically known
374 // object graphs (e.g. object literal boilerplate).
375 void EmitDeepCopy(Handle<JSObject> object,
376 Register result,
377 Register source,
yangguo@chromium.org28381b42013-01-21 14:39:38 +0000378 int* offset,
379 AllocationSiteMode mode);
dslomov@chromium.orgb752d402013-06-18 11:54:54 +0000380 // Emit optimized code for integer division.
381 // Inputs are signed.
382 // All registers are clobbered.
383 // If 'remainder' is no_reg, it is not computed.
384 void EmitSignedIntegerDivisionByConstant(Register result,
385 Register dividend,
386 int32_t divisor,
387 Register remainder,
388 Register scratch,
389 LEnvironment* environment);
390
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000391
jkummerow@chromium.orgd8a3a142013-10-03 12:15:05 +0000392 void EnsureSpaceForLazyDeopt(int space_needed) V8_OVERRIDE;
mvstanton@chromium.orge4ac3ef2012-11-12 14:53:34 +0000393 void DoLoadKeyedExternalArray(LLoadKeyed* instr);
394 void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr);
395 void DoLoadKeyedFixedArray(LLoadKeyed* instr);
396 void DoStoreKeyedExternalArray(LStoreKeyed* instr);
397 void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
398 void DoStoreKeyedFixedArray(LStoreKeyed* instr);
erikcorry0ad885c2011-11-21 13:51:57 +0000399
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000400 ZoneList<LEnvironment*> deoptimizations_;
palfia@homejinni.com04109732013-05-15 09:50:32 +0000401 ZoneList<Deoptimizer::JumpTableEntry> deopt_jump_table_;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000402 ZoneList<Handle<Object> > deoptimization_literals_;
403 int inlined_function_count_;
404 Scope* const scope_;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000405 TranslationBuffer translations_;
406 ZoneList<LDeferredCode*> deferred_;
407 int osr_pc_offset_;
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000408 bool frame_is_built_;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000409
410 // Builder that keeps track of safepoints in the code. The table
411 // itself is emitted at the end of the generated code.
412 SafepointTableBuilder safepoints_;
413
414 // Compiler from a set of parallel moves to a sequential list of moves.
415 LGapResolver resolver_;
416
417 Safepoint::Kind expected_safepoint_kind_;
418
verwaest@chromium.org32cb9b22013-08-21 11:18:12 +0000419 class PushSafepointRegistersScope V8_FINAL BASE_EMBEDDED {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000420 public:
421 PushSafepointRegistersScope(LCodeGen* codegen,
422 Safepoint::Kind kind)
423 : codegen_(codegen) {
jkummerow@chromium.org59297c72013-01-09 16:32:23 +0000424 ASSERT(codegen_->info()->is_calling());
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000425 ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
426 codegen_->expected_safepoint_kind_ = kind;
427
428 switch (codegen_->expected_safepoint_kind_) {
yangguo@chromium.org49546742013-12-23 16:17:49 +0000429 case Safepoint::kWithRegisters: {
430 StoreRegistersStateStub stub1(kDontSaveFPRegs);
431 codegen_->masm_->push(ra);
432 codegen_->masm_->CallStub(&stub1);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000433 break;
yangguo@chromium.org49546742013-12-23 16:17:49 +0000434 }
435 case Safepoint::kWithRegistersAndDoubles: {
436 StoreRegistersStateStub stub2(kSaveFPRegs);
437 codegen_->masm_->push(ra);
438 codegen_->masm_->CallStub(&stub2);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000439 break;
yangguo@chromium.org49546742013-12-23 16:17:49 +0000440 }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000441 default:
442 UNREACHABLE();
443 }
444 }
445
446 ~PushSafepointRegistersScope() {
447 Safepoint::Kind kind = codegen_->expected_safepoint_kind_;
448 ASSERT((kind & Safepoint::kWithRegisters) != 0);
449 switch (kind) {
yangguo@chromium.org49546742013-12-23 16:17:49 +0000450 case Safepoint::kWithRegisters: {
451 RestoreRegistersStateStub stub1(kDontSaveFPRegs);
452 codegen_->masm_->push(ra);
453 codegen_->masm_->CallStub(&stub1);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000454 break;
yangguo@chromium.org49546742013-12-23 16:17:49 +0000455 }
456 case Safepoint::kWithRegistersAndDoubles: {
457 RestoreRegistersStateStub stub2(kSaveFPRegs);
458 codegen_->masm_->push(ra);
459 codegen_->masm_->CallStub(&stub2);
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000460 break;
yangguo@chromium.org49546742013-12-23 16:17:49 +0000461 }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000462 default:
463 UNREACHABLE();
464 }
465 codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
466 }
467
468 private:
469 LCodeGen* codegen_;
470 };
471
472 friend class LDeferredCode;
473 friend class LEnvironment;
474 friend class SafepointGenerator;
475 DISALLOW_COPY_AND_ASSIGN(LCodeGen);
476};
477
478
verwaest@chromium.org32cb9b22013-08-21 11:18:12 +0000479class LDeferredCode : public ZoneObject {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000480 public:
481 explicit LDeferredCode(LCodeGen* codegen)
482 : codegen_(codegen),
483 external_exit_(NULL),
484 instruction_index_(codegen->current_instruction_) {
485 codegen->AddDeferredCode(this);
486 }
487
verwaest@chromium.org32cb9b22013-08-21 11:18:12 +0000488 virtual ~LDeferredCode() {}
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000489 virtual void Generate() = 0;
490 virtual LInstruction* instr() = 0;
491
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000492 void SetExit(Label* exit) { external_exit_ = exit; }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000493 Label* entry() { return &entry_; }
494 Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
495 int instruction_index() const { return instruction_index_; }
496
497 protected:
498 LCodeGen* codegen() const { return codegen_; }
499 MacroAssembler* masm() const { return codegen_->masm(); }
500
501 private:
502 LCodeGen* codegen_;
503 Label entry_;
504 Label exit_;
505 Label* external_exit_;
506 int instruction_index_;
lrn@chromium.org7516f052011-03-30 08:52:27 +0000507};
ager@chromium.org5c838252010-02-19 08:53:10 +0000508
509} } // namespace v8::internal
510
lrn@chromium.org7516f052011-03-30 08:52:27 +0000511#endif // V8_MIPS_LITHIUM_CODEGEN_MIPS_H_