blob: cecf152eed1aaa8bab1447e746e52f5a2ed336cd [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"
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +000032
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000033#include "arm/lithium-gap-resolver-arm.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000034#include "deoptimizer.h"
35#include "safepoint-table.h"
36#include "scopes.h"
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +000037#include "v8utils.h"
kasperl@chromium.orga5551262010-12-07 12:49:48 +000038
39namespace v8 {
40namespace internal {
41
42// Forward declarations.
43class LDeferredCode;
44class SafepointGenerator;
45
kasperl@chromium.orga5551262010-12-07 12:49:48 +000046class LCodeGen BASE_EMBEDDED {
47 public:
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000048 LCodeGen(LChunk* chunk, MacroAssembler* assembler, CompilationInfo* info)
49 : zone_(info->zone()),
jkummerow@chromium.org28583c92012-07-16 11:31:55 +000050 chunk_(static_cast<LPlatformChunk*>(chunk)),
kasperl@chromium.orga5551262010-12-07 12:49:48 +000051 masm_(assembler),
52 info_(info),
53 current_block_(-1),
54 current_instruction_(-1),
55 instructions_(chunk->instructions()),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000056 deoptimizations_(4, info->zone()),
57 deopt_jump_table_(4, info->zone()),
58 deoptimization_literals_(8, info->zone()),
kasperl@chromium.orga5551262010-12-07 12:49:48 +000059 inlined_function_count_(0),
karlklose@chromium.org8f806e82011-03-07 14:06:08 +000060 scope_(info->scope()),
kasperl@chromium.orga5551262010-12-07 12:49:48 +000061 status_(UNUSED),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000062 translations_(info->zone()),
63 deferred_(8, info->zone()),
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000064 osr_pc_offset_(-1),
ricow@chromium.org27bf2882011-11-17 08:34:43 +000065 last_lazy_deopt_pc_(0),
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000066 frame_is_built_(false),
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +000067 safepoints_(info->zone()),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +000068 resolver_(this),
mmassi@chromium.org7028c052012-06-13 11:51:58 +000069 expected_safepoint_kind_(Safepoint::kSimple) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +000070 PopulateDeoptimizationLiteralsWithInlinedFunctions();
71 }
72
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000073
74 // Simple accessors.
75 MacroAssembler* masm() const { return masm_; }
karlklose@chromium.org8f806e82011-03-07 14:06:08 +000076 CompilationInfo* info() const { return info_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000077 Isolate* isolate() const { return info_->isolate(); }
78 Factory* factory() const { return isolate()->factory(); }
79 Heap* heap() const { return isolate()->heap(); }
rossberg@chromium.org400388e2012-06-06 09:29:22 +000080 Zone* zone() const { return zone_; }
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +000081
ulan@chromium.org32d7dba2013-04-24 10:59:06 +000082 // TODO(svenpanne) Use this consistently.
83 int LookupDestination(int block_id) const {
84 return chunk()->LookupDestination(block_id);
85 }
86
87 bool IsNextEmittedBlock(int block_id) const {
88 return LookupDestination(block_id) == GetNextEmittedBlock();
89 }
90
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000091 bool NeedsEagerFrame() const {
92 return GetStackSlotCount() > 0 ||
93 info()->is_non_deferred_calling() ||
ulan@chromium.org77ca49a2013-04-22 09:43:56 +000094 !info()->IsStub() ||
95 info()->requires_frame();
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +000096 }
97 bool NeedsDeferredFrame() const {
98 return !NeedsEagerFrame() && info()->is_deferred_calling();
99 }
100
jkummerow@chromium.org7bd87f02013-03-20 18:06:29 +0000101 LinkRegisterStatus GetLinkRegisterState() const {
102 return frame_is_built_ ? kLRHasBeenSaved : kLRHasNotBeenSaved;
103 }
104
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000105 // Support for converting LOperands to assembler types.
106 // LOperand must be a register.
107 Register ToRegister(LOperand* op) const;
108
109 // LOperand is loaded into scratch, unless already a register.
110 Register EmitLoadRegister(LOperand* op, Register scratch);
111
112 // LOperand must be a double register.
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000113 DwVfpRegister ToDoubleRegister(LOperand* op) const;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000114
115 // LOperand is loaded into dbl_scratch, unless already a double register.
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000116 DwVfpRegister EmitLoadDoubleRegister(LOperand* op,
117 SwVfpRegister flt_scratch,
118 DwVfpRegister dbl_scratch);
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000119 int ToInteger32(LConstantOperand* op) const;
jkummerow@chromium.orgc1184022013-05-28 16:58:15 +0000120 Smi* ToSmi(LConstantOperand* op) const;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000121 double ToDouble(LConstantOperand* op) const;
fschneider@chromium.org3a5fd782011-02-24 10:10:44 +0000122 Operand ToOperand(LOperand* op);
123 MemOperand ToMemOperand(LOperand* op) const;
124 // Returns a MemOperand pointing to the high word of a DoubleStackSlot.
125 MemOperand ToHighMemOperand(LOperand* op) const;
126
danno@chromium.orgbf0c8202011-12-27 10:09:42 +0000127 bool IsInteger32(LConstantOperand* op) const;
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +0000128 bool IsSmi(LConstantOperand* op) const;
danno@chromium.orgbf0c8202011-12-27 10:09:42 +0000129 Handle<Object> ToHandle(LConstantOperand* op) const;
130
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000131 // Try to generate code for the entire chunk, but it may fail if the
132 // chunk contains constructs we cannot handle. Returns true if the
133 // code generation attempt succeeded.
134 bool GenerateCode();
135
136 // Finish the code by setting stack height, safepoint, and bailout
137 // information on it.
138 void FinishCode(Handle<Code> code);
139
140 // Deferred code support.
141 void DoDeferredNumberTagD(LNumberTagD* instr);
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000142
143 enum IntegerSignedness { SIGNED_INT32, UNSIGNED_INT32 };
144 void DoDeferredNumberTagI(LInstruction* instr,
145 LOperand* value,
146 IntegerSignedness signedness);
147
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000148 void DoDeferredTaggedToI(LTaggedToI* instr);
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000149 void DoDeferredMathAbsTaggedHeapNumber(LMathAbs* instr);
ager@chromium.org04921a82011-06-27 13:21:41 +0000150 void DoDeferredStackCheck(LStackCheck* instr);
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000151 void DoDeferredRandom(LRandom* instr);
vegorov@chromium.org0a4e9012011-01-24 12:33:13 +0000152 void DoDeferredStringCharCodeAt(LStringCharCodeAt* instr);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +0000153 void DoDeferredStringCharFromCode(LStringCharFromCode* instr);
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000154 void DoDeferredAllocate(LAllocate* instr);
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000155 void DoDeferredInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr,
156 Label* map_check);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000157
svenpanne@chromium.orga53e8e02013-05-24 12:35:50 +0000158 void DoCheckMapCommon(Register map_reg, Handle<Map> map, LEnvironment* env);
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000159
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000160 // Parallel move support.
161 void DoParallelMove(LParallelMove* move);
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +0000162 void DoGap(LGap* instr);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000163
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000164 MemOperand PrepareKeyedOperand(Register key,
165 Register base,
166 bool key_is_constant,
167 int constant_key,
168 int element_size,
169 int shift_size,
170 int additional_index,
171 int additional_offset);
172
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000173 // Emit frame translation commands for an environment.
danno@chromium.orgfe578672013-06-15 14:38:35 +0000174 void WriteTranslation(LEnvironment* environment,
175 Translation* translation,
176 int* arguments_index,
177 int* arguments_count);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000178
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000179 // Declare methods that deal with the individual node types.
180#define DECLARE_DO(type) void Do##type(L##type* node);
181 LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
182#undef DECLARE_DO
183
184 private:
185 enum Status {
186 UNUSED,
187 GENERATING,
188 DONE,
189 ABORTED
190 };
191
192 bool is_unused() const { return status_ == UNUSED; }
193 bool is_generating() const { return status_ == GENERATING; }
194 bool is_done() const { return status_ == DONE; }
195 bool is_aborted() const { return status_ == ABORTED; }
196
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000197 StrictModeFlag strict_mode_flag() const {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000198 return info()->is_classic_mode() ? kNonStrictMode : kStrictMode;
kmillikin@chromium.org49edbdf2011-02-16 12:32:18 +0000199 }
200
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000201 LPlatformChunk* chunk() const { return chunk_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000202 Scope* scope() const { return scope_; }
ulan@chromium.org32d7dba2013-04-24 10:59:06 +0000203 HGraph* graph() const { return chunk()->graph(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000204
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000205 Register scratch0() { return r9; }
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000206 DwVfpRegister double_scratch0() { return kScratchDoubleReg; }
lrn@chromium.org5d00b602011-01-05 09:51:43 +0000207
ulan@chromium.org32d7dba2013-04-24 10:59:06 +0000208 int GetNextEmittedBlock() const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000209 LInstruction* GetNextInstruction();
210
211 void EmitClassOfTest(Label* if_true,
212 Label* if_false,
213 Handle<String> class_name,
214 Register input,
215 Register temporary,
216 Register temporary2);
217
danno@chromium.org160a7b02011-04-18 15:51:38 +0000218 int GetStackSlotCount() const { return chunk()->spill_slot_count(); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000219
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000220 void Abort(const char* reason);
mstarzinger@chromium.orgb228be02013-04-18 14:56:59 +0000221 void FPRINTF_CHECKING Comment(const char* format, ...);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000222
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000223 void AddDeferredCode(LDeferredCode* code) { deferred_.Add(code, zone()); }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000224
225 // Code generation passes. Returns true if code generation should
226 // continue.
227 bool GeneratePrologue();
228 bool GenerateBody();
229 bool GenerateDeferredCode();
danno@chromium.org40cb8782011-05-25 07:58:50 +0000230 bool GenerateDeoptJumpTable();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000231 bool GenerateSafepointTable();
232
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000233 enum SafepointMode {
234 RECORD_SIMPLE_SAFEPOINT,
235 RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS
236 };
237
rossberg@chromium.org89e18f52012-10-22 13:09:53 +0000238 void CallCode(
239 Handle<Code> code,
240 RelocInfo::Mode mode,
241 LInstruction* instr,
242 TargetAddressStorageMode storage_mode = CAN_INLINE_TARGET_ADDRESS);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000243
rossberg@chromium.org89e18f52012-10-22 13:09:53 +0000244 void CallCodeGeneric(
245 Handle<Code> code,
246 RelocInfo::Mode mode,
247 LInstruction* instr,
248 SafepointMode safepoint_mode,
249 TargetAddressStorageMode storage_mode = CAN_INLINE_TARGET_ADDRESS);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000250
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000251 void CallRuntime(const Runtime::Function* function,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000252 int num_arguments,
253 LInstruction* instr);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000254
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000255 void CallRuntime(Runtime::FunctionId id,
256 int num_arguments,
257 LInstruction* instr) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000258 const Runtime::Function* function = Runtime::FunctionForId(id);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000259 CallRuntime(function, num_arguments, instr);
260 }
261
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000262 void CallRuntimeFromDeferred(Runtime::FunctionId id,
263 int argc,
264 LInstruction* instr);
265
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +0000266 enum R1State {
267 R1_UNINITIALIZED,
268 R1_CONTAINS_TARGET
269 };
270
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000271 // Generate a direct call to a known function. Expects the function
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000272 // to be in r1.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000273 void CallKnownFunction(Handle<JSFunction> function,
ulan@chromium.org32d7dba2013-04-24 10:59:06 +0000274 int formal_parameter_count,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000275 int arity,
danno@chromium.org40cb8782011-05-25 07:58:50 +0000276 LInstruction* instr,
svenpanne@chromium.orgfb046332012-04-19 12:02:44 +0000277 CallKind call_kind,
278 R1State r1_state);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000279
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000280 void LoadHeapObject(Register result, Handle<HeapObject> object);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000281
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000282 void RecordSafepointWithLazyDeopt(LInstruction* instr,
283 SafepointMode safepoint_mode);
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000284
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000285 void RegisterEnvironmentForDeoptimization(LEnvironment* environment,
286 Safepoint::DeoptMode mode);
danno@chromium.orgaefd6072013-05-14 14:11:47 +0000287 void DeoptimizeIf(Condition cc,
288 LEnvironment* environment,
289 Deoptimizer::BailoutType bailout_type);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000290 void DeoptimizeIf(Condition cc, LEnvironment* environment);
danno@chromium.orgaefd6072013-05-14 14:11:47 +0000291 void SoftDeoptimize(LEnvironment* environment);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000292
293 void AddToTranslation(Translation* translation,
294 LOperand* op,
yangguo@chromium.org46839fb2012-08-28 09:06:19 +0000295 bool is_tagged,
danno@chromium.orgfe578672013-06-15 14:38:35 +0000296 bool is_uint32,
297 bool arguments_known,
298 int arguments_index,
299 int arguments_count);
ulan@chromium.org6ba1fd02013-02-14 14:56:11 +0000300 void RegisterDependentCodeForEmbeddedMaps(Handle<Code> code);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000301 void PopulateDeoptimizationData(Handle<Code> code);
302 int DefineDeoptimizationLiteral(Handle<Object> literal);
303
304 void PopulateDeoptimizationLiteralsWithInlinedFunctions();
305
306 Register ToRegister(int index) const;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000307 DwVfpRegister ToDoubleRegister(int index) const;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000308
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000309 void EmitIntegerMathAbs(LMathAbs* instr);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000310
311 // Support for recording safepoint and position information.
ager@chromium.org378b34e2011-01-28 08:04:38 +0000312 void RecordSafepoint(LPointerMap* pointers,
313 Safepoint::Kind kind,
314 int arguments,
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000315 Safepoint::DeoptMode mode);
316 void RecordSafepoint(LPointerMap* pointers, Safepoint::DeoptMode mode);
317 void RecordSafepoint(Safepoint::DeoptMode mode);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000318 void RecordSafepointWithRegisters(LPointerMap* pointers,
319 int arguments,
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000320 Safepoint::DeoptMode mode);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000321 void RecordSafepointWithRegistersAndDoubles(LPointerMap* pointers,
322 int arguments,
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000323 Safepoint::DeoptMode mode);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000324 void RecordPosition(int position);
325
326 static Condition TokenToCondition(Token::Value op, bool is_unsigned);
ager@chromium.org04921a82011-06-27 13:21:41 +0000327 void EmitGoto(int block);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000328 void EmitBranch(int left_block, int right_block, Condition cc);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000329 void EmitNumberUntagD(Register input,
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000330 DwVfpRegister result,
rossberg@chromium.orgb99c7542013-05-31 11:40:45 +0000331 bool allow_undefined_as_nan,
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000332 bool deoptimize_on_minus_zero,
danno@chromium.org94b0d6f2013-02-04 13:33:20 +0000333 LEnvironment* env,
334 NumberUntagDMode mode);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000335
336 // Emits optimized code for typeof x == "y". Modifies input register.
337 // Returns the condition on which a final split to
338 // true and false label should be made, to optimize fallthrough.
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000339 Condition EmitTypeofIs(Label* true_label,
340 Label* false_label,
341 Register input,
342 Handle<String> type_name);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000343
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000344 // Emits optimized code for %_IsObject(x). Preserves input register.
345 // Returns the condition on which a final split to
346 // true and false label should be made, to optimize fallthrough.
347 Condition EmitIsObject(Register input,
348 Register temp1,
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000349 Label* is_not_object,
350 Label* is_object);
351
erikcorry0ad885c2011-11-21 13:51:57 +0000352 // Emits optimized code for %_IsString(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 EmitIsString(Register input,
356 Register temp1,
357 Label* is_not_string);
358
erik.corry@gmail.comd91075f2011-02-10 07:45:38 +0000359 // Emits optimized code for %_IsConstructCall().
360 // Caller should branch on equal condition.
361 void EmitIsConstructCall(Register temp1, Register temp2);
362
lrn@chromium.org1c092762011-05-09 09:42:16 +0000363 void EmitLoadFieldOrConstantFunction(Register result,
364 Register object,
365 Handle<Map> type,
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000366 Handle<String> name,
367 LEnvironment* env);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +0000368
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000369 // Emits optimized code to deep-copy the contents of statically known
370 // object graphs (e.g. object literal boilerplate).
371 void EmitDeepCopy(Handle<JSObject> object,
372 Register result,
373 Register source,
yangguo@chromium.org46a2a512013-01-18 16:29:40 +0000374 int* offset,
375 AllocationSiteMode mode);
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000376
yangguo@chromium.orgefdb9d72012-04-26 08:21:05 +0000377 // Emit optimized code for integer division.
378 // Inputs are signed.
379 // All registers are clobbered.
380 // If 'remainder' is no_reg, it is not computed.
381 void EmitSignedIntegerDivisionByConstant(Register result,
382 Register dividend,
383 int32_t divisor,
384 Register remainder,
385 Register scratch,
386 LEnvironment* environment);
387
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000388 void EnsureSpaceForLazyDeopt();
verwaest@chromium.orge4ee6de2012-11-06 12:13:00 +0000389 void DoLoadKeyedExternalArray(LLoadKeyed* instr);
390 void DoLoadKeyedFixedDoubleArray(LLoadKeyed* instr);
391 void DoLoadKeyedFixedArray(LLoadKeyed* instr);
392 void DoStoreKeyedExternalArray(LStoreKeyed* instr);
393 void DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr);
394 void DoStoreKeyedFixedArray(LStoreKeyed* instr);
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000395
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000396 Zone* zone_;
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000397 LPlatformChunk* const chunk_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000398 MacroAssembler* const masm_;
399 CompilationInfo* const info_;
400
401 int current_block_;
402 int current_instruction_;
403 const ZoneList<LInstruction*>* instructions_;
404 ZoneList<LEnvironment*> deoptimizations_;
danno@chromium.orgaefd6072013-05-14 14:11:47 +0000405 ZoneList<Deoptimizer::JumpTableEntry> deopt_jump_table_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000406 ZoneList<Handle<Object> > deoptimization_literals_;
407 int inlined_function_count_;
408 Scope* const scope_;
409 Status status_;
410 TranslationBuffer translations_;
411 ZoneList<LDeferredCode*> deferred_;
412 int osr_pc_offset_;
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000413 int last_lazy_deopt_pc_;
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000414 bool frame_is_built_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000415
416 // Builder that keeps track of safepoints in the code. The table
417 // itself is emitted at the end of the generated code.
418 SafepointTableBuilder safepoints_;
419
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000420 // Compiler from a set of parallel moves to a sequential list of moves.
421 LGapResolver resolver_;
422
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000423 Safepoint::Kind expected_safepoint_kind_;
424
425 class PushSafepointRegistersScope BASE_EMBEDDED {
426 public:
427 PushSafepointRegistersScope(LCodeGen* codegen,
428 Safepoint::Kind kind)
429 : codegen_(codegen) {
yangguo@chromium.orga6bbcc82012-12-21 12:35:02 +0000430 ASSERT(codegen_->info()->is_calling());
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000431 ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
432 codegen_->expected_safepoint_kind_ = kind;
433
434 switch (codegen_->expected_safepoint_kind_) {
435 case Safepoint::kWithRegisters:
436 codegen_->masm_->PushSafepointRegisters();
437 break;
438 case Safepoint::kWithRegistersAndDoubles:
439 codegen_->masm_->PushSafepointRegistersAndDoubles();
440 break;
441 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) {
450 case Safepoint::kWithRegisters:
451 codegen_->masm_->PopSafepointRegisters();
452 break;
453 case Safepoint::kWithRegistersAndDoubles:
454 codegen_->masm_->PopSafepointRegistersAndDoubles();
455 break;
456 default:
457 UNREACHABLE();
458 }
459 codegen_->expected_safepoint_kind_ = Safepoint::kSimple;
460 }
461
462 private:
463 LCodeGen* codegen_;
464 };
465
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000466 friend class LDeferredCode;
467 friend class LEnvironment;
468 friend class SafepointGenerator;
469 DISALLOW_COPY_AND_ASSIGN(LCodeGen);
470};
471
472
473class LDeferredCode: public ZoneObject {
474 public:
475 explicit LDeferredCode(LCodeGen* codegen)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000476 : codegen_(codegen),
477 external_exit_(NULL),
478 instruction_index_(codegen->current_instruction_) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000479 codegen->AddDeferredCode(this);
480 }
481
482 virtual ~LDeferredCode() { }
483 virtual void Generate() = 0;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000484 virtual LInstruction* instr() = 0;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000485
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +0000486 void SetExit(Label* exit) { external_exit_ = exit; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000487 Label* entry() { return &entry_; }
488 Label* exit() { return external_exit_ != NULL ? external_exit_ : &exit_; }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000489 int instruction_index() const { return instruction_index_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000490
491 protected:
492 LCodeGen* codegen() const { return codegen_; }
493 MacroAssembler* masm() const { return codegen_->masm(); }
494
495 private:
496 LCodeGen* codegen_;
497 Label entry_;
498 Label exit_;
499 Label* external_exit_;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000500 int instruction_index_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000501};
502
503} } // namespace v8::internal
504
505#endif // V8_ARM_LITHIUM_CODEGEN_ARM_H_