blob: 686241db799c7800271913b5fbe57a4ddabab04d [file] [log] [blame]
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001// Copyright 2012 the V8 project authors. All rights reserved.
kasperl@chromium.orga5551262010-12-07 12:49:48 +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
28#ifndef V8_ARM_LITHIUM_CODEGEN_ARM_H_
29#define V8_ARM_LITHIUM_CODEGEN_ARM_H_
30
31#include "arm/lithium-arm.h"
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000032#include "arm/lithium-gap-resolver-arm.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000033#include "deoptimizer.h"
34#include "safepoint-table.h"
35#include "scopes.h"
36
37namespace v8 {
38namespace internal {
39
40// Forward declarations.
41class LDeferredCode;
42class SafepointGenerator;
43
kasperl@chromium.orga5551262010-12-07 12:49:48 +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)),
kasperl@chromium.orga5551262010-12-07 12:49:48 +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()),
ulan@chromium.org2e04b582013-02-21 14:06:02 +000057 prototype_maps_(0, info->zone()),
kasperl@chromium.orga5551262010-12-07 12:49:48 +000058 inlined_function_count_(0),
karlklose@chromium.org8f806e82011-03-07 14:06:08 +000059 scope_(info->scope()),
kasperl@chromium.orga5551262010-12-07 12:49:48 +000060 status_(UNUSED),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000061 translations_(info->zone()),
62 deferred_(8, info->zone()),
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000063 osr_pc_offset_(-1),
ricow@chromium.org27bf2882011-11-17 08:34:43 +000064 last_lazy_deopt_pc_(0),
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000065 frame_is_built_(false),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000066 safepoints_(info->zone()),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +000067 resolver_(this),
mmassi@chromium.org7028c052012-06-13 11:51:58 +000068 expected_safepoint_kind_(Safepoint::kSimple) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +000069 PopulateDeoptimizationLiteralsWithInlinedFunctions();
70 }
71
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000072
73 // Simple accessors.
74 MacroAssembler* masm() const { return masm_; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +000075 CompilationInfo* info() const { return info_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000076 Isolate* isolate() const { return info_->isolate(); }
77 Factory* factory() const { return isolate()->factory(); }
78 Heap* heap() const { return isolate()->heap(); }
rossberg@chromium.org400388e2012-06-06 09:29:22 +000079 Zone* zone() const { return zone_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000080
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000081 bool NeedsEagerFrame() const {
82 return GetStackSlotCount() > 0 ||
83 info()->is_non_deferred_calling() ||
84 !info()->IsStub();
85 }
86 bool NeedsDeferredFrame() const {
87 return !NeedsEagerFrame() && info()->is_deferred_calling();
88 }
89
jkummerow@chromium.org7bd87f02013-03-20 18:06:29 +000090 LinkRegisterStatus GetLinkRegisterState() const {
91 return frame_is_built_ ? kLRHasBeenSaved : kLRHasNotBeenSaved;
92 }
93
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000094 // Support for converting LOperands to assembler types.
95 // LOperand must be a register.
96 Register ToRegister(LOperand* op) const;
97
98 // LOperand is loaded into scratch, unless already a register.
99 Register EmitLoadRegister(LOperand* op, Register scratch);
100
101 // LOperand must be a double register.
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000102 DwVfpRegister ToDoubleRegister(LOperand* op) const;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000103
104 // LOperand is loaded into dbl_scratch, unless already a double register.
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000105 DwVfpRegister EmitLoadDoubleRegister(LOperand* op,
106 SwVfpRegister flt_scratch,
107 DwVfpRegister dbl_scratch);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000108 int ToInteger32(LConstantOperand* op) const;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000109 double ToDouble(LConstantOperand* op) const;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000110 Operand ToOperand(LOperand* op);
111 MemOperand ToMemOperand(LOperand* op) const;
112 // Returns a MemOperand pointing to the high word of a DoubleStackSlot.
113 MemOperand ToHighMemOperand(LOperand* op) const;
114
danno@chromium.orgbf0c8202011-12-27 10:09:42 +0000115 bool IsInteger32(LConstantOperand* op) const;
116 Handle<Object> ToHandle(LConstantOperand* op) const;
117
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000118 // Try to generate code for the entire chunk, but it may fail if the
119 // chunk contains constructs we cannot handle. Returns true if the
120 // code generation attempt succeeded.
121 bool GenerateCode();
122
123 // Finish the code by setting stack height, safepoint, and bailout
124 // information on it.
125 void FinishCode(Handle<Code> code);
126
127 // Deferred code support.
verwaest@chromium.org33e09c82012-10-10 17:07:22 +0000128 void DoDeferredBinaryOpStub(LPointerMap* pointer_map,
129 LOperand* left_argument,
130 LOperand* right_argument,
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000131 Token::Value op);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000132 void DoDeferredNumberTagD(LNumberTagD* instr);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000133
134 enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
135 void DoDeferredNumberTagI(LInstruction* instr,
136 LOperand* value,
137 IntegerSignedness signedness);
138
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000139 void DoDeferredTaggedToI(LTaggedToI* instr);
140 void DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr);
ager@chromium.org04921a82011-06-27 13:21:41 +0000141 void DoDeferredStackCheck(LStackCheck* instr);
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000142 void DoDeferredRandom(LRandom* instr);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000143 void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000144 void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
ulan@chromium.org967e2702012-02-28 09:49:15 +0000145 void DoDeferredAllocateObject(LAllocateObject* instr);
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000146 void DoDeferredAllocate(LAllocate* instr);
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000147 void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
148 Label* map_check);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000149
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000150 void DoCheckMapCommon(Register map_reg, Handle<Map> map,
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000151 CompareMapMode mode, LEnvironment* env);
152
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000153 // Parallel move support.
154 void DoParallelMove(LParallelMove* move);
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000155 void DoGap(LGap* instr);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000156
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000157 MemOperand PrepareKeyedOperand(Register key,
158 Register base,
159 bool key_is_constant,
160 int constant_key,
161 int element_size,
162 int shift_size,
163 int additional_index,
164 int additional_offset);
165
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000166 // Emit frame translation commands for an environment.
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000167 void WriteTranslation(LEnvironment* environment,
168 Translation* translation,
169 int* arguments_index,
170 int* arguments_count);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000171
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000172 // Declare methods that deal with the individual node types.
173#define DECLARE_DO(type) void Do##type(L##type* node);
174 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
175#undef DECLARE_DO
176
177 private:
178 enum Status {
179 UNUSED,
180 GENERATING,
181 DONE,
182 ABORTED
183 };
184
185 bool is_unused() const { return status_ == UNUSED; }
186 bool is_generating() const { return status_ == GENERATING; }
187 bool is_done() const { return status_ == DONE; }
188 bool is_aborted() const { return status_ == ABORTED; }
189
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000190 StrictModeFlag strict_mode_flag() const {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000191 return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000192 }
193
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000194 LPlatformChunk* chunk() const { return chunk_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000195 Scope* scope() const { return scope_; }
196 HGraph* graph() const { return chunk_->graph(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000197
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000198 Register scratch0() { return r9; }
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000199 DwVfpRegister double_scratch0() { return kScratchDoubleReg; }
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000200
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000201 int GetNextEmittedBlock(int block);
202 LInstruction* GetNextInstruction();
203
204 void EmitClassOfTest(Label* if_true,
205 Label* if_false,
206 Handle<String> class_name,
207 Register input,
208 Register temporary,
209 Register temporary2);
210
danno@chromium.org160a7b02011-04-18 15:51:38 +0000211 int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000212
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000213 void Abort(const char* reason);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000214 void Comment(const char* format, ...);
215
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000216 void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000217
218 // Code generation passes. Returns true if code generation should
219 // continue.
220 bool GeneratePrologue();
221 bool GenerateBody();
222 bool GenerateDeferredCode();
danno@chromium.org40cb8782011-05-25 07:58:50 +0000223 bool GenerateDeoptJumpTable();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000224 bool GenerateSafepointTable();
225
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000226 enum SafepointMode {
227 RECORD_SIMPLE_SAFEPOINT,
228 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS
229 };
230
rossberg@chromium.org89e18f52012-10-22 13:09:53 +0000231 void CallCode(
232 Handle<Code> code,
233 RelocInfo::Mode mode,
234 LInstruction* instr,
235 TargetAddressStorageMode storage_mode = CAN_INLINE_TARGET_ADDRESS);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000236
rossberg@chromium.org89e18f52012-10-22 13:09:53 +0000237 void CallCodeGeneric(
238 Handle<Code> code,
239 RelocInfo::Mode mode,
240 LInstruction* instr,
241 SafepointMode safepoint_mode,
242 TargetAddressStorageMode storage_mode = CAN_INLINE_TARGET_ADDRESS);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000243
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000244 void CallRuntime(const Runtime::Function* function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000245 int num_arguments,
246 LInstruction* instr);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000247
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000248 void CallRuntime(Runtime::FunctionId id,
249 int num_arguments,
250 LInstruction* instr) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000251 const Runtime::Function* function = Runtime::FunctionForId(id);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000252 CallRuntime(function, num_arguments, instr);
253 }
254
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000255 void CallRuntimeFromDeferred(Runtime::FunctionId id,
256 int argc,
257 LInstruction* instr);
258
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +0000259 enum R1State {
260 R1_UNINITIALIZED,
261 R1_CONTAINS_TARGET
262 };
263
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000264 // Generate a direct call to a known function. Expects the function
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000265 // to be in r1.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000266 void CallKnownFunction(Handle<JSFunction> function,
267 int arity,
danno@chromium.org40cb8782011-05-25 07:58:50 +0000268 LInstruction* instr,
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +0000269 CallKind call_kind,
270 R1State r1_state);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000271
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000272 void LoadHeapObject(Register result, Handle<HeapObject> object);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000273
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000274 void RecordSafepointWithLazyDeopt(LInstruction* instr,
275 SafepointMode safepoint_mode);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000276
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000277 void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
278 Safepoint::DeoptMode mode);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000279 void DeoptimizeIf(Condition cc, LEnvironment* environment);
280
281 void AddToTranslation(Translation* translation,
282 LOperand* op,
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000283 bool is_tagged,
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000284 bool is_uint32,
hpayer@chromium.org8432c912013-02-28 15:55:26 +0000285 bool arguments_known,
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000286 int arguments_index,
287 int arguments_count);
ulan@chromium.org6ba1fd02013-02-14 14:56:11 +0000288 void RegisterDependentCodeForEmbeddedMaps(Handle<Code> code);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000289 void PopulateDeoptimizationData(Handle<Code> code);
290 int DefineDeoptimizationLiteral(Handle<Object> literal);
291
292 void PopulateDeoptimizationLiteralsWithInlinedFunctions();
293
294 Register ToRegister(int index) const;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000295 DwVfpRegister ToDoubleRegister(int index) const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000296
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000297 // Specific math operations - used from DoUnaryMathOperation.
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000298 void EmitIntegerMathAbs(LUnaryMathOperation* instr);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000299 void DoMathAbs(LUnaryMathOperation* instr);
300 void DoMathFloor(LUnaryMathOperation* instr);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000301 void DoMathRound(LUnaryMathOperation* instr);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000302 void DoMathSqrt(LUnaryMathOperation* instr);
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000303 void DoMathPowHalf(LUnaryMathOperation* instr);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000304 void DoMathLog(LUnaryMathOperation* instr);
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000305 void DoMathTan(LUnaryMathOperation* instr);
karlklose@chromium.org8f806e82011-03-07 14:06:08 +0000306 void DoMathCos(LUnaryMathOperation* instr);
307 void DoMathSin(LUnaryMathOperation* instr);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000308
309 // Support for recording safepoint and position information.
ager@chromium.org378b34e2011-01-28 08:04:38 +0000310 void RecordSafepoint(LPointerMap* pointers,
311 Safepoint::Kind kind,
312 int arguments,
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000313 Safepoint::DeoptMode mode);
314 void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
315 void RecordSafepoint(Safepoint::DeoptMode mode);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000316 void RecordSafepointWithRegisters(LPointerMap* pointers,
317 int arguments,
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000318 Safepoint::DeoptMode mode);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000319 void RecordSafepointWithRegistersAndDoubles(LPointerMap* pointers,
320 int arguments,
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000321 Safepoint::DeoptMode mode);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000322 void RecordPosition(int position);
323
324 static Condition TokenToCondition(Token::Value op, bool is_unsigned);
ager@chromium.org04921a82011-06-27 13:21:41 +0000325 void EmitGoto(int block);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000326 void EmitBranch(int left_block, int right_block, Condition cc);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000327 void EmitNumberUntagD(Register input,
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000328 DwVfpRegister result,
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000329 bool deoptimize_on_undefined,
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000330 bool deoptimize_on_minus_zero,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000331 LEnvironment* env,
332 NumberUntagDMode mode);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000333
334 // Emits optimized code for typeof x == "y". Modifies input register.
335 // Returns the condition on which a final split to
336 // true and false label should be made, to optimize fallthrough.
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000337 Condition EmitTypeofIs(Label* true_label,
338 Label* false_label,
339 Register input,
340 Handle<String> type_name);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000341
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000342 // Emits optimized code for %_IsObject(x). Preserves input register.
343 // Returns the condition on which a final split to
344 // true and false label should be made, to optimize fallthrough.
345 Condition EmitIsObject(Register input,
346 Register temp1,
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000347 Label* is_not_object,
348 Label* is_object);
349
erikcorry0ad885c2011-11-21 13:51:57 +0000350 // Emits optimized code for %_IsString(x). Preserves input register.
351 // Returns the condition on which a final split to
352 // true and false label should be made, to optimize fallthrough.
353 Condition EmitIsString(Register input,
354 Register temp1,
355 Label* is_not_string);
356
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +0000357 // Emits optimized code for %_IsConstructCall().
358 // Caller should branch on equal condition.
359 void EmitIsConstructCall(Register temp1, Register temp2);
360
lrn@chromium.org1c092762011-05-09 09:42:16 +0000361 void EmitLoadFieldOrConstantFunction(Register result,
362 Register object,
363 Handle<Map> type,
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000364 Handle<String> name,
365 LEnvironment* env);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000366
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000367 // Emits optimized code to deep-copy the contents of statically known
368 // object graphs (e.g. object literal boilerplate).
369 void EmitDeepCopy(Handle<JSObject> object,
370 Register result,
371 Register source,
yangguo@chromium.org46a2a512013-01-18 16:29:40 +0000372 int* offset,
373 AllocationSiteMode mode);
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000374
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +0000375 // Emit optimized code for integer division.
376 // Inputs are signed.
377 // All registers are clobbered.
378 // If 'remainder' is no_reg, it is not computed.
379 void EmitSignedIntegerDivisionByConstant(Register result,
380 Register dividend,
381 int32_t divisor,
382 Register remainder,
383 Register scratch,
384 LEnvironment* environment);
385
danno@chromium.org40cb8782011-05-25 07:58:50 +0000386 struct JumpTableEntry {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000387 inline JumpTableEntry(Address entry, bool frame, bool is_lazy)
danno@chromium.org40cb8782011-05-25 07:58:50 +0000388 : label(),
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000389 address(entry),
390 needs_frame(frame),
391 is_lazy_deopt(is_lazy) { }
danno@chromium.org40cb8782011-05-25 07:58:50 +0000392 Label label;
393 Address address;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000394 bool needs_frame;
395 bool is_lazy_deopt;
danno@chromium.org40cb8782011-05-25 07:58:50 +0000396 };
397
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000398 void EnsureSpaceForLazyDeopt();
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +0000399 void DoLoadKeyedExternalArray(LLoadKeyed* instr);
400 void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr);
401 void DoLoadKeyedFixedArray(LLoadKeyed* instr);
402 void DoStoreKeyedExternalArray(LStoreKeyed* instr);
403 void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
404 void DoStoreKeyedFixedArray(LStoreKeyed* instr);
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000405
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000406 Zone* zone_;
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000407 LPlatformChunk* const chunk_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000408 MacroAssembler* const masm_;
409 CompilationInfo* const info_;
410
411 int current_block_;
412 int current_instruction_;
413 const ZoneList<LInstruction*>* instructions_;
414 ZoneList<LEnvironment*> deoptimizations_;
danno@chromium.org40cb8782011-05-25 07:58:50 +0000415 ZoneList<JumpTableEntry> deopt_jump_table_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000416 ZoneList<Handle<Object> > deoptimization_literals_;
ulan@chromium.org2e04b582013-02-21 14:06:02 +0000417 ZoneList<Handle<Map> > prototype_maps_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000418 int inlined_function_count_;
419 Scope* const scope_;
420 Status status_;
421 TranslationBuffer translations_;
422 ZoneList<LDeferredCode*> deferred_;
423 int osr_pc_offset_;
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000424 int last_lazy_deopt_pc_;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000425 bool frame_is_built_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000426
427 // Builder that keeps track of safepoints in the code. The table
428 // itself is emitted at the end of the generated code.
429 SafepointTableBuilder safepoints_;
430
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000431 // Compiler from a set of parallel moves to a sequential list of moves.
432 LGapResolver resolver_;
433
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000434 Safepoint::Kind expected_safepoint_kind_;
435
436 class PushSafepointRegistersScope BASE_EMBEDDED {
437 public:
438 PushSafepointRegistersScope(LCodeGen* codegen,
439 Safepoint::Kind kind)
440 : codegen_(codegen) {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000441 ASSERT(codegen_->info()->is_calling());
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000442 ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
443 codegen_->expected_safepoint_kind_ = kind;
444
445 switch (codegen_->expected_safepoint_kind_) {
446 case Safepoint::kWithRegisters:
447 codegen_->masm_->PushSafepointRegisters();
448 break;
449 case Safepoint::kWithRegistersAndDoubles:
450 codegen_->masm_->PushSafepointRegistersAndDoubles();
451 break;
452 default:
453 UNREACHABLE();
454 }
455 }
456
457 ~PushSafepointRegistersScope() {
458 Safepoint::Kind kind = codegen_->expected_safepoint_kind_;
459 ASSERT((kind & Safepoint::kWithRegisters) != 0);
460 switch (kind) {
461 case Safepoint::kWithRegisters:
462 codegen_->masm_->PopSafepointRegisters();
463 break;
464 case Safepoint::kWithRegistersAndDoubles:
465 codegen_->masm_->PopSafepointRegistersAndDoubles();
466 break;
467 default:
468 UNREACHABLE();
469 }
470 codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
471 }
472
473 private:
474 LCodeGen* codegen_;
475 };
476
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000477 friend class LDeferredCode;
478 friend class LEnvironment;
479 friend class SafepointGenerator;
480 DISALLOW_COPY_AND_ASSIGN(LCodeGen);
481};
482
483
484class LDeferredCode: public ZoneObject {
485 public:
486 explicit LDeferredCode(LCodeGen* codegen)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000487 : codegen_(codegen),
488 external_exit_(NULL),
489 instruction_index_(codegen->current_instruction_) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000490 codegen->AddDeferredCode(this);
491 }
492
493 virtual ~LDeferredCode() { }
494 virtual void Generate() = 0;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000495 virtual LInstruction* instr() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000496
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000497 void SetExit(Label* exit) { external_exit_ = exit; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000498 Label* entry() { return &entry_; }
499 Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000500 int instruction_index() const { return instruction_index_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000501
502 protected:
503 LCodeGen* codegen() const { return codegen_; }
504 MacroAssembler* masm() const { return codegen_->masm(); }
505
506 private:
507 LCodeGen* codegen_;
508 Label entry_;
509 Label exit_;
510 Label* external_exit_;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000511 int instruction_index_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000512};
513
514} } // namespace v8::internal
515
516#endif // V8_ARM_LITHIUM_CODEGEN_ARM_H_