Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(384)

Side by Side Diff: src/arm/lithium-codegen-arm.cc

Issue 11414262: Revert 13105: "Enable stub generation using Hydrogen/Lithium." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/arm/lithium-gap-resolver-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 Safepoint::DeoptMode deopt_mode_; 58 Safepoint::DeoptMode deopt_mode_;
59 }; 59 };
60 60
61 61
62 #define __ masm()-> 62 #define __ masm()->
63 63
64 bool LCodeGen::GenerateCode() { 64 bool LCodeGen::GenerateCode() {
65 HPhase phase("Z_Code generation", chunk()); 65 HPhase phase("Z_Code generation", chunk());
66 ASSERT(is_unused()); 66 ASSERT(is_unused());
67 status_ = GENERATING; 67 status_ = GENERATING;
68 CpuFeatures::Scope scope1(VFP3);
69 CpuFeatures::Scope scope2(ARMv7);
68 70
69 CodeStub::GenerateFPStubs(); 71 CodeStub::GenerateFPStubs();
70 72
71 // Open a frame scope to indicate that there is a frame on the stack. The 73 // Open a frame scope to indicate that there is a frame on the stack. The
72 // NONE indicates that the scope shouldn't actually generate code to set up 74 // NONE indicates that the scope shouldn't actually generate code to set up
73 // the frame (that is done in GeneratePrologue). 75 // the frame (that is done in GeneratePrologue).
74 FrameScope frame_scope(masm_, StackFrame::NONE); 76 FrameScope frame_scope(masm_, StackFrame::NONE);
75 77
76 return GeneratePrologue() && 78 return GeneratePrologue() &&
77 GenerateBody() && 79 GenerateBody() &&
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 size_t length = builder.position(); 111 size_t length = builder.position();
110 Vector<char> copy = Vector<char>::New(length + 1); 112 Vector<char> copy = Vector<char>::New(length + 1);
111 memcpy(copy.start(), builder.Finalize(), copy.length()); 113 memcpy(copy.start(), builder.Finalize(), copy.length());
112 masm()->RecordComment(copy.start()); 114 masm()->RecordComment(copy.start());
113 } 115 }
114 116
115 117
116 bool LCodeGen::GeneratePrologue() { 118 bool LCodeGen::GeneratePrologue() {
117 ASSERT(is_generating()); 119 ASSERT(is_generating());
118 120
119 if (info()->IsOptimizing()) { 121 ProfileEntryHookStub::MaybeCallEntryHook(masm_);
120 ProfileEntryHookStub::MaybeCallEntryHook(masm_);
121 122
122 #ifdef DEBUG 123 #ifdef DEBUG
123 if (strlen(FLAG_stop_at) > 0 && 124 if (strlen(FLAG_stop_at) > 0 &&
124 info_->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) { 125 info_->function()->name()->IsEqualTo(CStrVector(FLAG_stop_at))) {
125 __ stop("stop_at"); 126 __ stop("stop_at");
126 } 127 }
127 #endif 128 #endif
128 129
129 // r1: Callee's JS function. 130 // r1: Callee's JS function.
130 // cp: Callee's context. 131 // cp: Callee's context.
131 // fp: Caller's frame pointer. 132 // fp: Caller's frame pointer.
132 // lr: Caller's pc. 133 // lr: Caller's pc.
133 134
134 // Strict mode functions and builtins need to replace the receiver 135 // Strict mode functions and builtins need to replace the receiver
135 // with undefined when called as functions (without an explicit 136 // with undefined when called as functions (without an explicit
136 // receiver object). r5 is zero for method calls and non-zero for 137 // receiver object). r5 is zero for method calls and non-zero for
137 // function calls. 138 // function calls.
138 if (!info_->is_classic_mode() || info_->is_native()) { 139 if (!info_->is_classic_mode() || info_->is_native()) {
139 Label ok; 140 Label ok;
140 __ cmp(r5, Operand(0)); 141 __ cmp(r5, Operand(0));
141 __ b(eq, &ok); 142 __ b(eq, &ok);
142 int receiver_offset = scope()->num_parameters() * kPointerSize; 143 int receiver_offset = scope()->num_parameters() * kPointerSize;
143 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex); 144 __ LoadRoot(r2, Heap::kUndefinedValueRootIndex);
144 __ str(r2, MemOperand(sp, receiver_offset)); 145 __ str(r2, MemOperand(sp, receiver_offset));
145 __ bind(&ok); 146 __ bind(&ok);
146 }
147 } 147 }
148 148
149
149 info()->set_prologue_offset(masm_->pc_offset()); 150 info()->set_prologue_offset(masm_->pc_offset());
150 if (NeedsEagerFrame()) { 151 // The following three instructions must remain together and unmodified for
151 // The following three instructions must remain together and unmodified for 152 // code aging to work properly.
152 // code aging to work properly. 153 __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit());
153 __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit()); 154 // Add unused load of ip to ensure prologue sequence is identical for
154 // Add unused load of ip to ensure prologue sequence is identical for 155 // full-codegen and lithium-codegen.
155 // full-codegen and lithium-codegen. 156 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
156 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 157 __ add(fp, sp, Operand(2 * kPointerSize)); // Adjust FP to point to saved FP.
157 __ add(fp, sp, Operand(2 * kPointerSize));
158 frame_is_built_ = true;
159 }
160 158
161 // Reserve space for the stack slots needed by the code. 159 // Reserve space for the stack slots needed by the code.
162 int slots = GetStackSlotCount(); 160 int slots = GetStackSlotCount();
163 if (slots > 0) { 161 if (slots > 0) {
164 if (FLAG_debug_code) { 162 if (FLAG_debug_code) {
165 __ mov(r0, Operand(slots)); 163 __ mov(r0, Operand(slots));
166 __ mov(r2, Operand(kSlotsZapValue)); 164 __ mov(r2, Operand(kSlotsZapValue));
167 Label loop; 165 Label loop;
168 __ bind(&loop); 166 __ bind(&loop);
169 __ push(r2); 167 __ push(r2);
170 __ sub(r0, r0, Operand(1), SetCC); 168 __ sub(r0, r0, Operand(1), SetCC);
171 __ b(ne, &loop); 169 __ b(ne, &loop);
172 } else { 170 } else {
173 __ sub(sp, sp, Operand(slots * kPointerSize)); 171 __ sub(sp, sp, Operand(slots * kPointerSize));
174 } 172 }
175 } 173 }
176 174
177 // Possibly allocate a local context. 175 // Possibly allocate a local context.
178 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 176 int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
179 if (heap_slots > 0) { 177 if (heap_slots > 0) {
180 Comment(";;; Allocate local context"); 178 Comment(";;; Allocate local context");
181 // Argument to NewContext is the function, which is in r1. 179 // Argument to NewContext is the function, which is in r1.
182 __ push(r1); 180 __ push(r1);
183 if (heap_slots <= FastNewContextStub::kMaximumSlots) { 181 if (heap_slots <= FastNewContextStub::kMaximumSlots) {
184 FastNewContextStub stub(heap_slots); 182 FastNewContextStub stub(heap_slots);
185 __ CallStub(&stub); 183 __ CallStub(&stub);
186 } else { 184 } else {
187 __ CallRuntime(Runtime::kNewFunctionContext, 1); 185 __ CallRuntime(Runtime::kNewFunctionContext, 1);
188 } 186 }
(...skipping 15 matching lines...) Expand all
204 __ str(r0, target); 202 __ str(r0, target);
205 // Update the write barrier. This clobbers r3 and r0. 203 // Update the write barrier. This clobbers r3 and r0.
206 __ RecordWriteContextSlot( 204 __ RecordWriteContextSlot(
207 cp, target.offset(), r0, r3, kLRHasBeenSaved, kSaveFPRegs); 205 cp, target.offset(), r0, r3, kLRHasBeenSaved, kSaveFPRegs);
208 } 206 }
209 } 207 }
210 Comment(";;; End allocate local context"); 208 Comment(";;; End allocate local context");
211 } 209 }
212 210
213 // Trace the call. 211 // Trace the call.
214 if (FLAG_trace && info()->IsOptimizing()) { 212 if (FLAG_trace) {
215 __ CallRuntime(Runtime::kTraceEnter, 0); 213 __ CallRuntime(Runtime::kTraceEnter, 0);
216 } 214 }
217 return !is_aborted(); 215 return !is_aborted();
218 } 216 }
219 217
220 218
221 bool LCodeGen::GenerateBody() { 219 bool LCodeGen::GenerateBody() {
222 ASSERT(is_generating()); 220 ASSERT(is_generating());
223 bool emit_instructions = true; 221 bool emit_instructions = true;
224 for (current_instruction_ = 0; 222 for (current_instruction_ = 0;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 return !is_aborted(); 260 return !is_aborted();
263 } 261 }
264 262
265 263
266 bool LCodeGen::GenerateDeferredCode() { 264 bool LCodeGen::GenerateDeferredCode() {
267 ASSERT(is_generating()); 265 ASSERT(is_generating());
268 if (deferred_.length() > 0) { 266 if (deferred_.length() > 0) {
269 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { 267 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
270 LDeferredCode* code = deferred_[i]; 268 LDeferredCode* code = deferred_[i];
271 __ bind(code->entry()); 269 __ bind(code->entry());
272 if (NeedsDeferredFrame()) {
273 Comment(";;; Deferred build frame",
274 code->instruction_index(),
275 code->instr()->Mnemonic());
276 ASSERT(!frame_is_built_);
277 ASSERT(info()->IsStub());
278 frame_is_built_ = true;
279 __ stm(db_w, sp, cp.bit() | fp.bit() | lr.bit());
280 __ mov(scratch0(), Operand(Smi::FromInt(StackFrame::STUB)));
281 __ push(scratch0());
282 __ add(fp, sp, Operand(2 * kPointerSize));
283 }
284 Comment(";;; Deferred code @%d: %s.", 270 Comment(";;; Deferred code @%d: %s.",
285 code->instruction_index(), 271 code->instruction_index(),
286 code->instr()->Mnemonic()); 272 code->instr()->Mnemonic());
287 code->Generate(); 273 code->Generate();
288 if (NeedsDeferredFrame()) {
289 Comment(";;; Deferred destroy frame",
290 code->instruction_index(),
291 code->instr()->Mnemonic());
292 ASSERT(frame_is_built_);
293 __ pop(ip);
294 __ ldm(ia_w, sp, cp.bit() | fp.bit() | lr.bit());
295 frame_is_built_ = false;
296 }
297 __ jmp(code->exit()); 274 __ jmp(code->exit());
298 } 275 }
299 } 276 }
300 277
301 // Force constant pool emission at the end of the deferred code to make 278 // Force constant pool emission at the end of the deferred code to make
302 // sure that no constant pools are emitted after. 279 // sure that no constant pools are emitted after.
303 masm()->CheckConstPool(true, false); 280 masm()->CheckConstPool(true, false);
304 281
305 return !is_aborted(); 282 return !is_aborted();
306 } 283 }
307 284
308 285
309 bool LCodeGen::GenerateDeoptJumpTable() { 286 bool LCodeGen::GenerateDeoptJumpTable() {
310 // Check that the jump table is accessible from everywhere in the function 287 // Check that the jump table is accessible from everywhere in the function
311 // code, i.e. that offsets to the table can be encoded in the 24bit signed 288 // code, i.e. that offsets to the table can be encoded in the 24bit signed
312 // immediate of a branch instruction. 289 // immediate of a branch instruction.
313 // To simplify we consider the code size from the first instruction to the 290 // To simplify we consider the code size from the first instruction to the
314 // end of the jump table. We also don't consider the pc load delta. 291 // end of the jump table. We also don't consider the pc load delta.
315 // Each entry in the jump table generates one instruction and inlines one 292 // Each entry in the jump table generates one instruction and inlines one
316 // 32bit data after it. 293 // 32bit data after it.
317 if (!is_int24((masm()->pc_offset() / Assembler::kInstrSize) + 294 if (!is_int24((masm()->pc_offset() / Assembler::kInstrSize) +
318 deopt_jump_table_.length() * 7)) { 295 deopt_jump_table_.length() * 2)) {
319 Abort("Generated code is too large"); 296 Abort("Generated code is too large");
320 } 297 }
321 298
299 // Block the constant pool emission during the jump table emission.
300 __ BlockConstPoolFor(deopt_jump_table_.length());
322 __ RecordComment("[ Deoptimisation jump table"); 301 __ RecordComment("[ Deoptimisation jump table");
323 Label table_start; 302 Label table_start;
324 __ bind(&table_start); 303 __ bind(&table_start);
325 Label needs_frame_not_call;
326 Label needs_frame_is_call;
327 for (int i = 0; i < deopt_jump_table_.length(); i++) { 304 for (int i = 0; i < deopt_jump_table_.length(); i++) {
328 __ bind(&deopt_jump_table_[i].label); 305 __ bind(&deopt_jump_table_[i].label);
329 Address entry = deopt_jump_table_[i].address; 306 __ ldr(pc, MemOperand(pc, Assembler::kInstrSize - Assembler::kPcLoadDelta));
330 if (deopt_jump_table_[i].needs_frame) { 307 __ dd(reinterpret_cast<uint32_t>(deopt_jump_table_[i].address));
331 __ mov(ip, Operand(ExternalReference::ForDeoptEntry(entry)));
332 if (deopt_jump_table_[i].is_lazy_deopt) {
333 if (needs_frame_is_call.is_bound()) {
334 __ b(&needs_frame_is_call);
335 } else {
336 __ bind(&needs_frame_is_call);
337 __ stm(db_w, sp, cp.bit() | fp.bit() | lr.bit());
338 // This variant of deopt can only be used with stubs. Since we don't
339 // have a function pointer to install in the stack frame that we're
340 // building, install a special marker there instead.
341 ASSERT(info()->IsStub());
342 __ mov(scratch0(), Operand(Smi::FromInt(StackFrame::STUB)));
343 __ push(scratch0());
344 __ add(fp, sp, Operand(2 * kPointerSize));
345 __ mov(lr, Operand(pc), LeaveCC, al);
346 __ mov(pc, ip);
347 }
348 } else {
349 if (needs_frame_not_call.is_bound()) {
350 __ b(&needs_frame_not_call);
351 } else {
352 __ bind(&needs_frame_not_call);
353 __ stm(db_w, sp, cp.bit() | fp.bit() | lr.bit());
354 // This variant of deopt can only be used with stubs. Since we don't
355 // have a function pointer to install in the stack frame that we're
356 // building, install a special marker there instead.
357 ASSERT(info()->IsStub());
358 __ mov(scratch0(), Operand(Smi::FromInt(StackFrame::STUB)));
359 __ push(scratch0());
360 __ add(fp, sp, Operand(2 * kPointerSize));
361 __ mov(pc, ip);
362 }
363 }
364 } else {
365 if (deopt_jump_table_[i].is_lazy_deopt) {
366 __ mov(lr, Operand(pc), LeaveCC, al);
367 __ mov(pc, Operand(ExternalReference::ForDeoptEntry(entry)));
368 } else {
369 __ mov(pc, Operand(ExternalReference::ForDeoptEntry(entry)));
370 }
371 }
372 masm()->CheckConstPool(false, false);
373 } 308 }
309 ASSERT(masm()->InstructionsGeneratedSince(&table_start) ==
310 deopt_jump_table_.length() * 2);
374 __ RecordComment("]"); 311 __ RecordComment("]");
375 312
376 // Force constant pool emission at the end of the deopt jump table to make
377 // sure that no constant pools are emitted after.
378 masm()->CheckConstPool(true, false);
379
380 // The deoptimization jump table is the last part of the instruction 313 // The deoptimization jump table is the last part of the instruction
381 // sequence. Mark the generated code as done unless we bailed out. 314 // sequence. Mark the generated code as done unless we bailed out.
382 if (!is_aborted()) status_ = DONE; 315 if (!is_aborted()) status_ = DONE;
383 return !is_aborted(); 316 return !is_aborted();
384 } 317 }
385 318
386 319
387 bool LCodeGen::GenerateSafepointTable() { 320 bool LCodeGen::GenerateSafepointTable() {
388 ASSERT(is_done()); 321 ASSERT(is_done());
389 safepoints_.Emit(masm(), GetStackSlotCount()); 322 safepoints_.Emit(masm(), GetStackSlotCount());
390 return !is_aborted(); 323 return !is_aborted();
391 } 324 }
392 325
393 326
394 Register LCodeGen::ToRegister(int index) const { 327 Register LCodeGen::ToRegister(int index) const {
395 return Register::FromAllocationIndex(index); 328 return Register::FromAllocationIndex(index);
396 } 329 }
397 330
398 331
399 DwVfpRegister LCodeGen::ToDoubleRegister(int index) const { 332 DoubleRegister LCodeGen::ToDoubleRegister(int index) const {
400 return DwVfpRegister::FromAllocationIndex(index); 333 return DoubleRegister::FromAllocationIndex(index);
401 } 334 }
402 335
403 336
404 Register LCodeGen::ToRegister(LOperand* op) const { 337 Register LCodeGen::ToRegister(LOperand* op) const {
405 ASSERT(op->IsRegister()); 338 ASSERT(op->IsRegister());
406 return ToRegister(op->index()); 339 return ToRegister(op->index());
407 } 340 }
408 341
409 342
410 Register LCodeGen::EmitLoadRegister(LOperand* op, Register scratch) { 343 Register LCodeGen::EmitLoadRegister(LOperand* op, Register scratch) {
(...skipping 20 matching lines...) Expand all
431 return scratch; 364 return scratch;
432 } else if (op->IsStackSlot() || op->IsArgument()) { 365 } else if (op->IsStackSlot() || op->IsArgument()) {
433 __ ldr(scratch, ToMemOperand(op)); 366 __ ldr(scratch, ToMemOperand(op));
434 return scratch; 367 return scratch;
435 } 368 }
436 UNREACHABLE(); 369 UNREACHABLE();
437 return scratch; 370 return scratch;
438 } 371 }
439 372
440 373
441 DwVfpRegister LCodeGen::ToDoubleRegister(LOperand* op) const { 374 DoubleRegister LCodeGen::ToDoubleRegister(LOperand* op) const {
442 ASSERT(op->IsDoubleRegister()); 375 ASSERT(op->IsDoubleRegister());
443 return ToDoubleRegister(op->index()); 376 return ToDoubleRegister(op->index());
444 } 377 }
445 378
446 379
447 DwVfpRegister LCodeGen::EmitLoadDoubleRegister(LOperand* op, 380 DoubleRegister LCodeGen::EmitLoadDoubleRegister(LOperand* op,
448 SwVfpRegister flt_scratch, 381 SwVfpRegister flt_scratch,
449 DwVfpRegister dbl_scratch) { 382 DoubleRegister dbl_scratch) {
450 if (op->IsDoubleRegister()) { 383 if (op->IsDoubleRegister()) {
451 return ToDoubleRegister(op->index()); 384 return ToDoubleRegister(op->index());
452 } else if (op->IsConstantOperand()) { 385 } else if (op->IsConstantOperand()) {
453 LConstantOperand* const_op = LConstantOperand::cast(op); 386 LConstantOperand* const_op = LConstantOperand::cast(op);
454 HConstant* constant = chunk_->LookupConstant(const_op); 387 HConstant* constant = chunk_->LookupConstant(const_op);
455 Handle<Object> literal = constant->handle(); 388 Handle<Object> literal = constant->handle();
456 Representation r = chunk_->LookupLiteralRepresentation(const_op); 389 Representation r = chunk_->LookupLiteralRepresentation(const_op);
457 if (r.IsInteger32()) { 390 if (r.IsInteger32()) {
458 ASSERT(literal->IsNumber()); 391 ASSERT(literal->IsNumber());
459 __ mov(ip, Operand(static_cast<int32_t>(literal->Number()))); 392 __ mov(ip, Operand(static_cast<int32_t>(literal->Number())));
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 // arguments index points to the first element of a sequence of tagged 508 // arguments index points to the first element of a sequence of tagged
576 // values on the stack that represent the arguments. This needs to be 509 // values on the stack that represent the arguments. This needs to be
577 // kept in sync with the LArgumentsElements implementation. 510 // kept in sync with the LArgumentsElements implementation.
578 *arguments_index = -environment->parameter_count(); 511 *arguments_index = -environment->parameter_count();
579 *arguments_count = environment->parameter_count(); 512 *arguments_count = environment->parameter_count();
580 513
581 WriteTranslation(environment->outer(), 514 WriteTranslation(environment->outer(),
582 translation, 515 translation,
583 arguments_index, 516 arguments_index,
584 arguments_count); 517 arguments_count);
585 bool has_closure_id = !info()->closure().is_null() && 518 int closure_id = *info()->closure() != *environment->closure()
586 *info()->closure() != *environment->closure();
587 int closure_id = has_closure_id
588 ? DefineDeoptimizationLiteral(environment->closure()) 519 ? DefineDeoptimizationLiteral(environment->closure())
589 : Translation::kSelfLiteralId; 520 : Translation::kSelfLiteralId;
590 521
591 switch (environment->frame_type()) { 522 switch (environment->frame_type()) {
592 case JS_FUNCTION: 523 case JS_FUNCTION:
593 translation->BeginJSFrame(environment->ast_id(), closure_id, height); 524 translation->BeginJSFrame(environment->ast_id(), closure_id, height);
594 break; 525 break;
595 case JS_CONSTRUCT: 526 case JS_CONSTRUCT:
596 translation->BeginConstructStubFrame(closure_id, translation_size); 527 translation->BeginConstructStubFrame(closure_id, translation_size);
597 break; 528 break;
598 case JS_GETTER: 529 case JS_GETTER:
599 ASSERT(translation_size == 1); 530 ASSERT(translation_size == 1);
600 ASSERT(height == 0); 531 ASSERT(height == 0);
601 translation->BeginGetterStubFrame(closure_id); 532 translation->BeginGetterStubFrame(closure_id);
602 break; 533 break;
603 case JS_SETTER: 534 case JS_SETTER:
604 ASSERT(translation_size == 2); 535 ASSERT(translation_size == 2);
605 ASSERT(height == 0); 536 ASSERT(height == 0);
606 translation->BeginSetterStubFrame(closure_id); 537 translation->BeginSetterStubFrame(closure_id);
607 break; 538 break;
608 case STUB:
609 translation->BeginCompiledStubFrame();
610 break;
611 case ARGUMENTS_ADAPTOR: 539 case ARGUMENTS_ADAPTOR:
612 translation->BeginArgumentsAdaptorFrame(closure_id, translation_size); 540 translation->BeginArgumentsAdaptorFrame(closure_id, translation_size);
613 break; 541 break;
614 } 542 }
615 543
616 // Inlined frames which push their arguments cause the index to be 544 // Inlined frames which push their arguments cause the index to be
617 // bumped and a new stack area to be used for materialization. 545 // bumped and a new stack area to be used for materialization.
618 if (environment->entry() != NULL && 546 if (environment->entry() != NULL &&
619 environment->entry()->arguments_pushed()) { 547 environment->entry()->arguments_pushed()) {
620 *arguments_index = *arguments_index < 0 548 *arguments_index = *arguments_index < 0
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
796 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); 724 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1);
797 deoptimizations_.Add(environment, zone()); 725 deoptimizations_.Add(environment, zone());
798 } 726 }
799 } 727 }
800 728
801 729
802 void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) { 730 void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) {
803 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 731 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
804 ASSERT(environment->HasBeenRegistered()); 732 ASSERT(environment->HasBeenRegistered());
805 int id = environment->deoptimization_index(); 733 int id = environment->deoptimization_index();
806 734 Address entry = Deoptimizer::GetDeoptimizationEntry(id, Deoptimizer::EAGER);
807 Deoptimizer::BailoutType bailout_type = info()->IsStub()
808 ? Deoptimizer::LAZY
809 : Deoptimizer::EAGER;
810 Address entry = Deoptimizer::GetDeoptimizationEntry(id, bailout_type);
811 if (entry == NULL) { 735 if (entry == NULL) {
812 Abort("bailout was not prepared"); 736 Abort("bailout was not prepared");
813 return; 737 return;
814 } 738 }
815 739
816 ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on ARM. 740 ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on ARM.
817 741
818 if (FLAG_deopt_every_n_times == 1 && 742 if (FLAG_deopt_every_n_times == 1 &&
819 info_->shared_info()->opt_count() == id) { 743 info_->shared_info()->opt_count() == id) {
820 __ Jump(entry, RelocInfo::RUNTIME_ENTRY); 744 __ Jump(entry, RelocInfo::RUNTIME_ENTRY);
821 return; 745 return;
822 } 746 }
823 747
824 if (FLAG_trap_on_deopt) __ stop("trap_on_deopt", cc); 748 if (FLAG_trap_on_deopt) __ stop("trap_on_deopt", cc);
825 749
826 bool needs_lazy_deopt = info()->IsStub(); 750 if (cc == al) {
827 ASSERT(info()->IsStub() || frame_is_built_);
828 if (cc == al && !needs_lazy_deopt) {
829 __ Jump(entry, RelocInfo::RUNTIME_ENTRY); 751 __ Jump(entry, RelocInfo::RUNTIME_ENTRY);
830 } else { 752 } else {
831 // We often have several deopts to the same entry, reuse the last 753 // We often have several deopts to the same entry, reuse the last
832 // jump entry if this is the case. 754 // jump entry if this is the case.
833 if (deopt_jump_table_.is_empty() || 755 if (deopt_jump_table_.is_empty() ||
834 (deopt_jump_table_.last().address != entry) || 756 (deopt_jump_table_.last().address != entry)) {
835 (deopt_jump_table_.last().is_lazy_deopt != needs_lazy_deopt) || 757 deopt_jump_table_.Add(JumpTableEntry(entry), zone());
836 (deopt_jump_table_.last().needs_frame != !frame_is_built_)) {
837 JumpTableEntry table_entry(entry, !frame_is_built_, needs_lazy_deopt);
838 deopt_jump_table_.Add(table_entry, zone());
839 } 758 }
840 __ b(cc, &deopt_jump_table_.last().label); 759 __ b(cc, &deopt_jump_table_.last().label);
841 } 760 }
842 } 761 }
843 762
844 763
845 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { 764 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
846 int length = deoptimizations_.length(); 765 int length = deoptimizations_.length();
847 if (length == 0) return; 766 if (length == 0) return;
848 Handle<DeoptimizationInputData> data = 767 Handle<DeoptimizationInputData> data =
(...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after
1437 __ cmp(remainder, Operand(0)); 1356 __ cmp(remainder, Operand(0));
1438 __ teq(remainder, Operand(divisor), ne); 1357 __ teq(remainder, Operand(divisor), ne);
1439 __ sub(result, result, Operand(1), LeaveCC, mi); 1358 __ sub(result, result, Operand(1), LeaveCC, mi);
1440 } 1359 }
1441 1360
1442 1361
1443 void LCodeGen::DoDeferredBinaryOpStub(LPointerMap* pointer_map, 1362 void LCodeGen::DoDeferredBinaryOpStub(LPointerMap* pointer_map,
1444 LOperand* left_argument, 1363 LOperand* left_argument,
1445 LOperand* right_argument, 1364 LOperand* right_argument,
1446 Token::Value op) { 1365 Token::Value op) {
1447 CpuFeatures::Scope vfp_scope(VFP2);
1448 Register left = ToRegister(left_argument); 1366 Register left = ToRegister(left_argument);
1449 Register right = ToRegister(right_argument); 1367 Register right = ToRegister(right_argument);
1450 1368
1451 PushSafepointRegistersScope scope(this, Safepoint::kWithRegistersAndDoubles); 1369 PushSafepointRegistersScope scope(this, Safepoint::kWithRegistersAndDoubles);
1452 // Move left to r1 and right to r0 for the stub call. 1370 // Move left to r1 and right to r0 for the stub call.
1453 if (left.is(r1)) { 1371 if (left.is(r1)) {
1454 __ Move(r0, right); 1372 __ Move(r0, right);
1455 } else if (left.is(r0) && right.is(r1)) { 1373 } else if (left.is(r0) && right.is(r1)) {
1456 __ Swap(r0, r1, r2); 1374 __ Swap(r0, r1, r2);
1457 } else if (left.is(r0)) { 1375 } else if (left.is(r0)) {
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
1723 1641
1724 void LCodeGen::DoConstantI(LConstantI* instr) { 1642 void LCodeGen::DoConstantI(LConstantI* instr) {
1725 ASSERT(instr->result()->IsRegister()); 1643 ASSERT(instr->result()->IsRegister());
1726 __ mov(ToRegister(instr->result()), Operand(instr->value())); 1644 __ mov(ToRegister(instr->result()), Operand(instr->value()));
1727 } 1645 }
1728 1646
1729 1647
1730 void LCodeGen::DoConstantD(LConstantD* instr) { 1648 void LCodeGen::DoConstantD(LConstantD* instr) {
1731 ASSERT(instr->result()->IsDoubleRegister()); 1649 ASSERT(instr->result()->IsDoubleRegister());
1732 DwVfpRegister result = ToDoubleRegister(instr->result()); 1650 DwVfpRegister result = ToDoubleRegister(instr->result());
1733 CpuFeatures::Scope scope(VFP2);
1734 double v = instr->value(); 1651 double v = instr->value();
1735 __ Vmov(result, v, scratch0()); 1652 __ Vmov(result, v, scratch0());
1736 } 1653 }
1737 1654
1738 1655
1739 void LCodeGen::DoConstantT(LConstantT* instr) { 1656 void LCodeGen::DoConstantT(LConstantT* instr) {
1740 Handle<Object> value = instr->value(); 1657 Handle<Object> value = instr->value();
1741 if (value->IsSmi()) { 1658 if (value->IsSmi()) {
1742 __ mov(ToRegister(instr->result()), Operand(value)); 1659 __ mov(ToRegister(instr->result()), Operand(value));
1743 } else { 1660 } else {
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
1892 ? ToOperand(right) 1809 ? ToOperand(right)
1893 : Operand(EmitLoadRegister(right, ip)); 1810 : Operand(EmitLoadRegister(right, ip));
1894 Register result_reg = ToRegister(instr->result()); 1811 Register result_reg = ToRegister(instr->result());
1895 __ cmp(left_reg, right_op); 1812 __ cmp(left_reg, right_op);
1896 if (!result_reg.is(left_reg)) { 1813 if (!result_reg.is(left_reg)) {
1897 __ mov(result_reg, left_reg, LeaveCC, condition); 1814 __ mov(result_reg, left_reg, LeaveCC, condition);
1898 } 1815 }
1899 __ mov(result_reg, right_op, LeaveCC, NegateCondition(condition)); 1816 __ mov(result_reg, right_op, LeaveCC, NegateCondition(condition));
1900 } else { 1817 } else {
1901 ASSERT(instr->hydrogen()->representation().IsDouble()); 1818 ASSERT(instr->hydrogen()->representation().IsDouble());
1902 CpuFeatures::Scope scope(VFP2); 1819 DoubleRegister left_reg = ToDoubleRegister(left);
1903 DwVfpRegister left_reg = ToDoubleRegister(left); 1820 DoubleRegister right_reg = ToDoubleRegister(right);
1904 DwVfpRegister right_reg = ToDoubleRegister(right); 1821 DoubleRegister result_reg = ToDoubleRegister(instr->result());
1905 DwVfpRegister result_reg = ToDoubleRegister(instr->result());
1906 Label check_nan_left, check_zero, return_left, return_right, done; 1822 Label check_nan_left, check_zero, return_left, return_right, done;
1907 __ VFPCompareAndSetFlags(left_reg, right_reg); 1823 __ VFPCompareAndSetFlags(left_reg, right_reg);
1908 __ b(vs, &check_nan_left); 1824 __ b(vs, &check_nan_left);
1909 __ b(eq, &check_zero); 1825 __ b(eq, &check_zero);
1910 __ b(condition, &return_left); 1826 __ b(condition, &return_left);
1911 __ b(al, &return_right); 1827 __ b(al, &return_right);
1912 1828
1913 __ bind(&check_zero); 1829 __ bind(&check_zero);
1914 __ VFPCompareAndSetFlags(left_reg, 0.0); 1830 __ VFPCompareAndSetFlags(left_reg, 0.0);
1915 __ b(ne, &return_left); // left == right != 0. 1831 __ b(ne, &return_left); // left == right != 0.
(...skipping 22 matching lines...) Expand all
1938 __ bind(&return_left); 1854 __ bind(&return_left);
1939 if (!left_reg.is(result_reg)) { 1855 if (!left_reg.is(result_reg)) {
1940 __ vmov(result_reg, left_reg); 1856 __ vmov(result_reg, left_reg);
1941 } 1857 }
1942 __ bind(&done); 1858 __ bind(&done);
1943 } 1859 }
1944 } 1860 }
1945 1861
1946 1862
1947 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { 1863 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1948 CpuFeatures::Scope scope(VFP2); 1864 DoubleRegister left = ToDoubleRegister(instr->left());
1949 DwVfpRegister left = ToDoubleRegister(instr->left()); 1865 DoubleRegister right = ToDoubleRegister(instr->right());
1950 DwVfpRegister right = ToDoubleRegister(instr->right()); 1866 DoubleRegister result = ToDoubleRegister(instr->result());
1951 DwVfpRegister result = ToDoubleRegister(instr->result());
1952 switch (instr->op()) { 1867 switch (instr->op()) {
1953 case Token::ADD: 1868 case Token::ADD:
1954 __ vadd(result, left, right); 1869 __ vadd(result, left, right);
1955 break; 1870 break;
1956 case Token::SUB: 1871 case Token::SUB:
1957 __ vsub(result, left, right); 1872 __ vsub(result, left, right);
1958 break; 1873 break;
1959 case Token::MUL: 1874 case Token::MUL:
1960 __ vmul(result, left, right); 1875 __ vmul(result, left, right);
1961 break; 1876 break;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2029 void LCodeGen::DoBranch(LBranch* instr) { 1944 void LCodeGen::DoBranch(LBranch* instr) {
2030 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1945 int true_block = chunk_->LookupDestination(instr->true_block_id());
2031 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1946 int false_block = chunk_->LookupDestination(instr->false_block_id());
2032 1947
2033 Representation r = instr->hydrogen()->value()->representation(); 1948 Representation r = instr->hydrogen()->value()->representation();
2034 if (r.IsInteger32()) { 1949 if (r.IsInteger32()) {
2035 Register reg = ToRegister(instr->value()); 1950 Register reg = ToRegister(instr->value());
2036 __ cmp(reg, Operand(0)); 1951 __ cmp(reg, Operand(0));
2037 EmitBranch(true_block, false_block, ne); 1952 EmitBranch(true_block, false_block, ne);
2038 } else if (r.IsDouble()) { 1953 } else if (r.IsDouble()) {
2039 CpuFeatures::Scope scope(VFP2); 1954 DoubleRegister reg = ToDoubleRegister(instr->value());
2040 DwVfpRegister reg = ToDoubleRegister(instr->value());
2041 Register scratch = scratch0(); 1955 Register scratch = scratch0();
2042 1956
2043 // Test the double value. Zero and NaN are false. 1957 // Test the double value. Zero and NaN are false.
2044 __ VFPCompareAndLoadFlags(reg, 0.0, scratch); 1958 __ VFPCompareAndLoadFlags(reg, 0.0, scratch);
2045 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit)); 1959 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit));
2046 EmitBranch(true_block, false_block, eq); 1960 EmitBranch(true_block, false_block, eq);
2047 } else { 1961 } else {
2048 ASSERT(r.IsTagged()); 1962 ASSERT(r.IsTagged());
2049 Register reg = ToRegister(instr->value()); 1963 Register reg = ToRegister(instr->value());
2050 HType type = instr->hydrogen()->value()->type(); 1964 HType type = instr->hydrogen()->value()->type();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2115 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); 2029 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE);
2116 __ b(ge, &not_string); 2030 __ b(ge, &not_string);
2117 __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset)); 2031 __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset));
2118 __ cmp(ip, Operand(0)); 2032 __ cmp(ip, Operand(0));
2119 __ b(ne, true_label); 2033 __ b(ne, true_label);
2120 __ b(false_label); 2034 __ b(false_label);
2121 __ bind(&not_string); 2035 __ bind(&not_string);
2122 } 2036 }
2123 2037
2124 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { 2038 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
2125 CpuFeatures::Scope scope(VFP2);
2126 // heap number -> false iff +0, -0, or NaN. 2039 // heap number -> false iff +0, -0, or NaN.
2127 DwVfpRegister dbl_scratch = double_scratch0(); 2040 DoubleRegister dbl_scratch = double_scratch0();
2128 Label not_heap_number; 2041 Label not_heap_number;
2129 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); 2042 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
2130 __ b(ne, &not_heap_number); 2043 __ b(ne, &not_heap_number);
2131 __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); 2044 __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset));
2132 __ VFPCompareAndSetFlags(dbl_scratch, 0.0); 2045 __ VFPCompareAndSetFlags(dbl_scratch, 0.0);
2133 __ b(vs, false_label); // NaN -> false. 2046 __ b(vs, false_label); // NaN -> false.
2134 __ b(eq, false_label); // +0, -0 -> false. 2047 __ b(eq, false_label); // +0, -0 -> false.
2135 __ b(true_label); 2048 __ b(true_label);
2136 __ bind(&not_heap_number); 2049 __ bind(&not_heap_number);
2137 } 2050 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2195 if (left->IsConstantOperand() && right->IsConstantOperand()) { 2108 if (left->IsConstantOperand() && right->IsConstantOperand()) {
2196 // We can statically evaluate the comparison. 2109 // We can statically evaluate the comparison.
2197 double left_val = ToDouble(LConstantOperand::cast(left)); 2110 double left_val = ToDouble(LConstantOperand::cast(left));
2198 double right_val = ToDouble(LConstantOperand::cast(right)); 2111 double right_val = ToDouble(LConstantOperand::cast(right));
2199 int next_block = 2112 int next_block =
2200 EvalComparison(instr->op(), left_val, right_val) ? true_block 2113 EvalComparison(instr->op(), left_val, right_val) ? true_block
2201 : false_block; 2114 : false_block;
2202 EmitGoto(next_block); 2115 EmitGoto(next_block);
2203 } else { 2116 } else {
2204 if (instr->is_double()) { 2117 if (instr->is_double()) {
2205 CpuFeatures::Scope scope(VFP2);
2206 // Compare left and right operands as doubles and load the 2118 // Compare left and right operands as doubles and load the
2207 // resulting flags into the normal status register. 2119 // resulting flags into the normal status register.
2208 __ VFPCompareAndSetFlags(ToDoubleRegister(left), ToDoubleRegister(right)); 2120 __ VFPCompareAndSetFlags(ToDoubleRegister(left), ToDoubleRegister(right));
2209 // If a NaN is involved, i.e. the result is unordered (V set), 2121 // If a NaN is involved, i.e. the result is unordered (V set),
2210 // jump to false block label. 2122 // jump to false block label.
2211 __ b(vs, chunk_->GetAssemblyLabel(false_block)); 2123 __ b(vs, chunk_->GetAssemblyLabel(false_block));
2212 } else { 2124 } else {
2213 if (right->IsConstantOperand()) { 2125 if (right->IsConstantOperand()) {
2214 __ cmp(ToRegister(left), 2126 __ cmp(ToRegister(left),
2215 Operand(ToInteger32(LConstantOperand::cast(right)))); 2127 Operand(ToInteger32(LConstantOperand::cast(right))));
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after
2734 __ LoadRoot(ToRegister(instr->result()), 2646 __ LoadRoot(ToRegister(instr->result()),
2735 Heap::kTrueValueRootIndex, 2647 Heap::kTrueValueRootIndex,
2736 condition); 2648 condition);
2737 __ LoadRoot(ToRegister(instr->result()), 2649 __ LoadRoot(ToRegister(instr->result()),
2738 Heap::kFalseValueRootIndex, 2650 Heap::kFalseValueRootIndex,
2739 NegateCondition(condition)); 2651 NegateCondition(condition));
2740 } 2652 }
2741 2653
2742 2654
2743 void LCodeGen::DoReturn(LReturn* instr) { 2655 void LCodeGen::DoReturn(LReturn* instr) {
2744 if (FLAG_trace && info()->IsOptimizing()) { 2656 if (FLAG_trace) {
2745 // Push the return value on the stack as the parameter. 2657 // Push the return value on the stack as the parameter.
2746 // Runtime::TraceExit returns its parameter in r0. 2658 // Runtime::TraceExit returns its parameter in r0.
2747 __ push(r0); 2659 __ push(r0);
2748 __ CallRuntime(Runtime::kTraceExit, 1); 2660 __ CallRuntime(Runtime::kTraceExit, 1);
2749 } 2661 }
2750 if (NeedsEagerFrame()) { 2662 int32_t sp_delta = (GetParameterCount() + 1) * kPointerSize;
2751 int32_t sp_delta = (GetParameterCount() + 1) * kPointerSize; 2663 __ mov(sp, fp);
2752 __ mov(sp, fp); 2664 __ ldm(ia_w, sp, fp.bit() | lr.bit());
2753 __ ldm(ia_w, sp, fp.bit() | lr.bit()); 2665 __ add(sp, sp, Operand(sp_delta));
2754 __ add(sp, sp, Operand(sp_delta));
2755 }
2756 if (info()->IsStub()) {
2757 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2758 }
2759 __ Jump(lr); 2666 __ Jump(lr);
2760 } 2667 }
2761 2668
2762 2669
2763 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { 2670 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
2764 Register result = ToRegister(instr->result()); 2671 Register result = ToRegister(instr->result());
2765 __ mov(ip, Operand(Handle<Object>(instr->hydrogen()->cell()))); 2672 __ mov(ip, Operand(Handle<Object>(instr->hydrogen()->cell())));
2766 __ ldr(result, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset)); 2673 __ ldr(result, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset));
2767 if (instr->hydrogen()->RequiresHoleCheck()) { 2674 if (instr->hydrogen()->RequiresHoleCheck()) {
2768 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 2675 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
3098 } else { 3005 } else {
3099 key = ToRegister(instr->key()); 3006 key = ToRegister(instr->key());
3100 } 3007 }
3101 int element_size_shift = ElementsKindToShiftSize(elements_kind); 3008 int element_size_shift = ElementsKindToShiftSize(elements_kind);
3102 int shift_size = (instr->hydrogen()->key()->representation().IsTagged()) 3009 int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
3103 ? (element_size_shift - kSmiTagSize) : element_size_shift; 3010 ? (element_size_shift - kSmiTagSize) : element_size_shift;
3104 int additional_offset = instr->additional_index() << element_size_shift; 3011 int additional_offset = instr->additional_index() << element_size_shift;
3105 3012
3106 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 3013 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
3107 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 3014 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3015 CpuFeatures::Scope scope(VFP3);
3108 DwVfpRegister result = ToDoubleRegister(instr->result()); 3016 DwVfpRegister result = ToDoubleRegister(instr->result());
3109 Operand operand = key_is_constant 3017 Operand operand = key_is_constant
3110 ? Operand(constant_key << element_size_shift) 3018 ? Operand(constant_key << element_size_shift)
3111 : Operand(key, LSL, shift_size); 3019 : Operand(key, LSL, shift_size);
3112 __ add(scratch0(), external_pointer, operand); 3020 __ add(scratch0(), external_pointer, operand);
3113 if (CpuFeatures::IsSupported(VFP2)) { 3021 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3114 CpuFeatures::Scope scope(VFP2); 3022 __ vldr(result.low(), scratch0(), additional_offset);
3115 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 3023 __ vcvt_f64_f32(result, result.low());
3116 __ vldr(result.low(), scratch0(), additional_offset); 3024 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
3117 __ vcvt_f64_f32(result, result.low()); 3025 __ vldr(result, scratch0(), additional_offset);
3118 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
3119 __ vldr(result, scratch0(), additional_offset);
3120 }
3121 } else {
3122 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3123 Register value = external_pointer;
3124 __ ldr(value, MemOperand(scratch0(), additional_offset));
3125 __ and_(sfpd_lo, value, Operand(kBinary32MantissaMask));
3126
3127 __ mov(scratch0(), Operand(value, LSR, kBinary32MantissaBits));
3128 __ and_(scratch0(), scratch0(),
3129 Operand(kBinary32ExponentMask >> kBinary32MantissaBits));
3130
3131 Label exponent_rebiased;
3132 __ teq(scratch0(), Operand(0x00));
3133 __ b(eq, &exponent_rebiased);
3134
3135 __ teq(scratch0(), Operand(0xff));
3136 __ mov(scratch0(), Operand(0x7ff), LeaveCC, eq);
3137 __ b(eq, &exponent_rebiased);
3138
3139 // Rebias exponent.
3140 __ add(scratch0(),
3141 scratch0(),
3142 Operand(-kBinary32ExponentBias + HeapNumber::kExponentBias));
3143
3144 __ bind(&exponent_rebiased);
3145 __ and_(sfpd_hi, value, Operand(kBinary32SignMask));
3146 __ orr(sfpd_hi, sfpd_hi,
3147 Operand(scratch0(), LSL, HeapNumber::kMantissaBitsInTopWord));
3148
3149 // Shift mantissa.
3150 static const int kMantissaShiftForHiWord =
3151 kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord;
3152
3153 static const int kMantissaShiftForLoWord =
3154 kBitsPerInt - kMantissaShiftForHiWord;
3155
3156 __ orr(sfpd_hi, sfpd_hi,
3157 Operand(sfpd_lo, LSR, kMantissaShiftForHiWord));
3158 __ mov(sfpd_lo, Operand(sfpd_lo, LSL, kMantissaShiftForLoWord));
3159
3160 } else {
3161 __ ldr(sfpd_lo, MemOperand(scratch0(), additional_offset));
3162 __ ldr(sfpd_hi, MemOperand(scratch0(),
3163 additional_offset + kPointerSize));
3164 }
3165 } 3026 }
3166 } else { 3027 } else {
3167 Register result = ToRegister(instr->result()); 3028 Register result = ToRegister(instr->result());
3168 MemOperand mem_operand = PrepareKeyedOperand( 3029 MemOperand mem_operand = PrepareKeyedOperand(
3169 key, external_pointer, key_is_constant, constant_key, 3030 key, external_pointer, key_is_constant, constant_key,
3170 element_size_shift, shift_size, 3031 element_size_shift, shift_size,
3171 instr->additional_index(), additional_offset); 3032 instr->additional_index(), additional_offset);
3172 switch (elements_kind) { 3033 switch (elements_kind) {
3173 case EXTERNAL_BYTE_ELEMENTS: 3034 case EXTERNAL_BYTE_ELEMENTS:
3174 __ ldrsb(result, mem_operand); 3035 __ ldrsb(result, mem_operand);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3223 int constant_key = 0; 3084 int constant_key = 0;
3224 if (key_is_constant) { 3085 if (key_is_constant) {
3225 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 3086 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3226 if (constant_key & 0xF0000000) { 3087 if (constant_key & 0xF0000000) {
3227 Abort("array index constant value too big."); 3088 Abort("array index constant value too big.");
3228 } 3089 }
3229 } else { 3090 } else {
3230 key = ToRegister(instr->key()); 3091 key = ToRegister(instr->key());
3231 } 3092 }
3232 3093
3233 int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) + 3094 Operand operand = key_is_constant
3234 ((constant_key + instr->additional_index()) << element_size_shift); 3095 ? Operand(((constant_key + instr->additional_index()) <<
3096 element_size_shift) +
3097 FixedDoubleArray::kHeaderSize - kHeapObjectTag)
3098 : Operand(key, LSL, shift_size);
3099 __ add(elements, elements, operand);
3235 if (!key_is_constant) { 3100 if (!key_is_constant) {
3236 __ add(elements, elements, Operand(key, LSL, shift_size)); 3101 __ add(elements, elements,
3102 Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag) +
3103 (instr->additional_index() << element_size_shift)));
3237 } 3104 }
3238 if (CpuFeatures::IsSupported(VFP2)) { 3105
3239 CpuFeatures::Scope scope(VFP2); 3106 __ vldr(result, elements, 0);
3240 __ add(elements, elements, Operand(base_offset)); 3107 if (instr->hydrogen()->RequiresHoleCheck()) {
3241 __ vldr(result, elements, 0); 3108 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32)));
3242 if (instr->hydrogen()->RequiresHoleCheck()) { 3109 __ cmp(scratch, Operand(kHoleNanUpper32));
3243 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); 3110 DeoptimizeIf(eq, instr->environment());
3244 __ cmp(scratch, Operand(kHoleNanUpper32));
3245 DeoptimizeIf(eq, instr->environment());
3246 }
3247 } else {
3248 __ ldr(sfpd_hi, MemOperand(elements, base_offset + kPointerSize));
3249 __ ldr(sfpd_lo, MemOperand(elements, base_offset));
3250 if (instr->hydrogen()->RequiresHoleCheck()) {
3251 ASSERT(kPointerSize == sizeof(kHoleNanLower32));
3252 __ cmp(sfpd_hi, Operand(kHoleNanUpper32));
3253 DeoptimizeIf(eq, instr->environment());
3254 }
3255 } 3111 }
3256 } 3112 }
3257 3113
3258 3114
3259 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 3115 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3260 Register elements = ToRegister(instr->elements()); 3116 Register elements = ToRegister(instr->elements());
3261 Register result = ToRegister(instr->result()); 3117 Register result = ToRegister(instr->result());
3262 Register scratch = scratch0(); 3118 Register scratch = scratch0();
3263 Register store_base = scratch; 3119 Register store_base = scratch;
3264 int offset = 0; 3120 int offset = 0;
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
3680 // We can make rsb conditional because the previous cmp instruction 3536 // We can make rsb conditional because the previous cmp instruction
3681 // will clear the V (overflow) flag and rsb won't set this flag 3537 // will clear the V (overflow) flag and rsb won't set this flag
3682 // if input is positive. 3538 // if input is positive.
3683 __ rsb(result, input, Operand(0), SetCC, mi); 3539 __ rsb(result, input, Operand(0), SetCC, mi);
3684 // Deoptimize on overflow. 3540 // Deoptimize on overflow.
3685 DeoptimizeIf(vs, instr->environment()); 3541 DeoptimizeIf(vs, instr->environment());
3686 } 3542 }
3687 3543
3688 3544
3689 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { 3545 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
3690 CpuFeatures::Scope scope(VFP2);
3691 // Class for deferred case. 3546 // Class for deferred case.
3692 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 3547 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
3693 public: 3548 public:
3694 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 3549 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
3695 LUnaryMathOperation* instr) 3550 LUnaryMathOperation* instr)
3696 : LDeferredCode(codegen), instr_(instr) { } 3551 : LDeferredCode(codegen), instr_(instr) { }
3697 virtual void Generate() { 3552 virtual void Generate() {
3698 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 3553 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
3699 } 3554 }
3700 virtual LInstruction* instr() { return instr_; } 3555 virtual LInstruction* instr() { return instr_; }
(...skipping 16 matching lines...) Expand all
3717 // Smi check. 3572 // Smi check.
3718 __ JumpIfNotSmi(input, deferred->entry()); 3573 __ JumpIfNotSmi(input, deferred->entry());
3719 // If smi, handle it directly. 3574 // If smi, handle it directly.
3720 EmitIntegerMathAbs(instr); 3575 EmitIntegerMathAbs(instr);
3721 __ bind(deferred->exit()); 3576 __ bind(deferred->exit());
3722 } 3577 }
3723 } 3578 }
3724 3579
3725 3580
3726 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { 3581 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
3727 CpuFeatures::Scope scope(VFP2); 3582 DoubleRegister input = ToDoubleRegister(instr->value());
3728 DwVfpRegister input = ToDoubleRegister(instr->value());
3729 Register result = ToRegister(instr->result()); 3583 Register result = ToRegister(instr->result());
3730 Register scratch = scratch0(); 3584 Register scratch = scratch0();
3731 3585
3732 __ EmitVFPTruncate(kRoundToMinusInf, 3586 __ EmitVFPTruncate(kRoundToMinusInf,
3733 result, 3587 result,
3734 input, 3588 input,
3735 scratch, 3589 scratch,
3736 double_scratch0()); 3590 double_scratch0());
3737 DeoptimizeIf(ne, instr->environment()); 3591 DeoptimizeIf(ne, instr->environment());
3738 3592
3739 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3593 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3740 // Test for -0. 3594 // Test for -0.
3741 Label done; 3595 Label done;
3742 __ cmp(result, Operand(0)); 3596 __ cmp(result, Operand(0));
3743 __ b(ne, &done); 3597 __ b(ne, &done);
3744 __ vmov(scratch, input.high()); 3598 __ vmov(scratch, input.high());
3745 __ tst(scratch, Operand(HeapNumber::kSignMask)); 3599 __ tst(scratch, Operand(HeapNumber::kSignMask));
3746 DeoptimizeIf(ne, instr->environment()); 3600 DeoptimizeIf(ne, instr->environment());
3747 __ bind(&done); 3601 __ bind(&done);
3748 } 3602 }
3749 } 3603 }
3750 3604
3751 3605
3752 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { 3606 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
3753 CpuFeatures::Scope scope(VFP2); 3607 DoubleRegister input = ToDoubleRegister(instr->value());
3754 DwVfpRegister input = ToDoubleRegister(instr->value());
3755 Register result = ToRegister(instr->result()); 3608 Register result = ToRegister(instr->result());
3756 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->temp()); 3609 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->temp());
3757 Register scratch = scratch0(); 3610 Register scratch = scratch0();
3758 Label done, check_sign_on_zero; 3611 Label done, check_sign_on_zero;
3759 3612
3760 // Extract exponent bits. 3613 // Extract exponent bits.
3761 __ vmov(result, input.high()); 3614 __ vmov(result, input.high());
3762 __ ubfx(scratch, 3615 __ ubfx(scratch,
3763 result, 3616 result,
3764 HeapNumber::kExponentShift, 3617 HeapNumber::kExponentShift,
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3809 __ bind(&check_sign_on_zero); 3662 __ bind(&check_sign_on_zero);
3810 __ vmov(scratch, input.high()); 3663 __ vmov(scratch, input.high());
3811 __ tst(scratch, Operand(HeapNumber::kSignMask)); 3664 __ tst(scratch, Operand(HeapNumber::kSignMask));
3812 DeoptimizeIf(ne, instr->environment()); 3665 DeoptimizeIf(ne, instr->environment());
3813 } 3666 }
3814 __ bind(&done); 3667 __ bind(&done);
3815 } 3668 }
3816 3669
3817 3670
3818 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 3671 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
3819 CpuFeatures::Scope scope(VFP2); 3672 DoubleRegister input = ToDoubleRegister(instr->value());
3820 DwVfpRegister input = ToDoubleRegister(instr->value()); 3673 DoubleRegister result = ToDoubleRegister(instr->result());
3821 DwVfpRegister result = ToDoubleRegister(instr->result());
3822 __ vsqrt(result, input); 3674 __ vsqrt(result, input);
3823 } 3675 }
3824 3676
3825 3677
3826 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { 3678 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
3827 CpuFeatures::Scope scope(VFP2); 3679 DoubleRegister input = ToDoubleRegister(instr->value());
3828 DwVfpRegister input = ToDoubleRegister(instr->value()); 3680 DoubleRegister result = ToDoubleRegister(instr->result());
3829 DwVfpRegister result = ToDoubleRegister(instr->result()); 3681 DoubleRegister temp = ToDoubleRegister(instr->temp());
3830 DwVfpRegister temp = ToDoubleRegister(instr->temp());
3831 3682
3832 // Note that according to ECMA-262 15.8.2.13: 3683 // Note that according to ECMA-262 15.8.2.13:
3833 // Math.pow(-Infinity, 0.5) == Infinity 3684 // Math.pow(-Infinity, 0.5) == Infinity
3834 // Math.sqrt(-Infinity) == NaN 3685 // Math.sqrt(-Infinity) == NaN
3835 Label done; 3686 Label done;
3836 __ vmov(temp, -V8_INFINITY, scratch0()); 3687 __ vmov(temp, -V8_INFINITY, scratch0());
3837 __ VFPCompareAndSetFlags(input, temp); 3688 __ VFPCompareAndSetFlags(input, temp);
3838 __ vneg(result, temp, eq); 3689 __ vneg(result, temp, eq);
3839 __ b(&done, eq); 3690 __ b(&done, eq);
3840 3691
3841 // Add +0 to convert -0 to +0. 3692 // Add +0 to convert -0 to +0.
3842 __ vadd(result, input, kDoubleRegZero); 3693 __ vadd(result, input, kDoubleRegZero);
3843 __ vsqrt(result, result); 3694 __ vsqrt(result, result);
3844 __ bind(&done); 3695 __ bind(&done);
3845 } 3696 }
3846 3697
3847 3698
3848 void LCodeGen::DoPower(LPower* instr) { 3699 void LCodeGen::DoPower(LPower* instr) {
3849 CpuFeatures::Scope scope(VFP2);
3850 Representation exponent_type = instr->hydrogen()->right()->representation(); 3700 Representation exponent_type = instr->hydrogen()->right()->representation();
3851 // Having marked this as a call, we can use any registers. 3701 // Having marked this as a call, we can use any registers.
3852 // Just make sure that the input/output registers are the expected ones. 3702 // Just make sure that the input/output registers are the expected ones.
3853 ASSERT(!instr->right()->IsDoubleRegister() || 3703 ASSERT(!instr->right()->IsDoubleRegister() ||
3854 ToDoubleRegister(instr->right()).is(d2)); 3704 ToDoubleRegister(instr->right()).is(d2));
3855 ASSERT(!instr->right()->IsRegister() || 3705 ASSERT(!instr->right()->IsRegister() ||
3856 ToRegister(instr->right()).is(r2)); 3706 ToRegister(instr->right()).is(r2));
3857 ASSERT(ToDoubleRegister(instr->left()).is(d1)); 3707 ASSERT(ToDoubleRegister(instr->left()).is(d1));
3858 ASSERT(ToDoubleRegister(instr->result()).is(d3)); 3708 ASSERT(ToDoubleRegister(instr->result()).is(d3));
3859 3709
(...skipping 12 matching lines...) Expand all
3872 __ CallStub(&stub); 3722 __ CallStub(&stub);
3873 } else { 3723 } else {
3874 ASSERT(exponent_type.IsDouble()); 3724 ASSERT(exponent_type.IsDouble());
3875 MathPowStub stub(MathPowStub::DOUBLE); 3725 MathPowStub stub(MathPowStub::DOUBLE);
3876 __ CallStub(&stub); 3726 __ CallStub(&stub);
3877 } 3727 }
3878 } 3728 }
3879 3729
3880 3730
3881 void LCodeGen::DoRandom(LRandom* instr) { 3731 void LCodeGen::DoRandom(LRandom* instr) {
3882 CpuFeatures::Scope scope(VFP2);
3883 class DeferredDoRandom: public LDeferredCode { 3732 class DeferredDoRandom: public LDeferredCode {
3884 public: 3733 public:
3885 DeferredDoRandom(LCodeGen* codegen, LRandom* instr) 3734 DeferredDoRandom(LCodeGen* codegen, LRandom* instr)
3886 : LDeferredCode(codegen), instr_(instr) { } 3735 : LDeferredCode(codegen), instr_(instr) { }
3887 virtual void Generate() { codegen()->DoDeferredRandom(instr_); } 3736 virtual void Generate() { codegen()->DoDeferredRandom(instr_); }
3888 virtual LInstruction* instr() { return instr_; } 3737 virtual LInstruction* instr() { return instr_; }
3889 private: 3738 private:
3890 LRandom* instr_; 3739 LRandom* instr_;
3891 }; 3740 };
3892 3741
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
3951 3800
3952 3801
3953 void LCodeGen::DoDeferredRandom(LRandom* instr) { 3802 void LCodeGen::DoDeferredRandom(LRandom* instr) {
3954 __ PrepareCallCFunction(1, scratch0()); 3803 __ PrepareCallCFunction(1, scratch0());
3955 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); 3804 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
3956 // Return value is in r0. 3805 // Return value is in r0.
3957 } 3806 }
3958 3807
3959 3808
3960 void LCodeGen::DoMathExp(LMathExp* instr) { 3809 void LCodeGen::DoMathExp(LMathExp* instr) {
3961 CpuFeatures::Scope scope(VFP2); 3810 DoubleRegister input = ToDoubleRegister(instr->value());
3962 DwVfpRegister input = ToDoubleRegister(instr->value()); 3811 DoubleRegister result = ToDoubleRegister(instr->result());
3963 DwVfpRegister result = ToDoubleRegister(instr->result()); 3812 DoubleRegister double_scratch1 = ToDoubleRegister(instr->double_temp());
3964 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->double_temp()); 3813 DoubleRegister double_scratch2 = double_scratch0();
3965 DwVfpRegister double_scratch2 = double_scratch0();
3966 Register temp1 = ToRegister(instr->temp1()); 3814 Register temp1 = ToRegister(instr->temp1());
3967 Register temp2 = ToRegister(instr->temp2()); 3815 Register temp2 = ToRegister(instr->temp2());
3968 3816
3969 MathExpGenerator::EmitMathExp( 3817 MathExpGenerator::EmitMathExp(
3970 masm(), input, result, double_scratch1, double_scratch2, 3818 masm(), input, result, double_scratch1, double_scratch2,
3971 temp1, temp2, scratch0()); 3819 temp1, temp2, scratch0());
3972 } 3820 }
3973 3821
3974 3822
3975 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { 3823 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
4241 } 4089 }
4242 __ cmp(ip, ToRegister(instr->length())); 4090 __ cmp(ip, ToRegister(instr->length()));
4243 } else { 4091 } else {
4244 __ cmp(ToRegister(instr->index()), ToRegister(instr->length())); 4092 __ cmp(ToRegister(instr->index()), ToRegister(instr->length()));
4245 } 4093 }
4246 DeoptimizeIf(hs, instr->environment()); 4094 DeoptimizeIf(hs, instr->environment());
4247 } 4095 }
4248 4096
4249 4097
4250 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { 4098 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4251 CpuFeatures::Scope scope(VFP2);
4252 Register external_pointer = ToRegister(instr->elements()); 4099 Register external_pointer = ToRegister(instr->elements());
4253 Register key = no_reg; 4100 Register key = no_reg;
4254 ElementsKind elements_kind = instr->elements_kind(); 4101 ElementsKind elements_kind = instr->elements_kind();
4255 bool key_is_constant = instr->key()->IsConstantOperand(); 4102 bool key_is_constant = instr->key()->IsConstantOperand();
4256 int constant_key = 0; 4103 int constant_key = 0;
4257 if (key_is_constant) { 4104 if (key_is_constant) {
4258 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 4105 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
4259 if (constant_key & 0xF0000000) { 4106 if (constant_key & 0xF0000000) {
4260 Abort("array index constant value too big."); 4107 Abort("array index constant value too big.");
4261 } 4108 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
4312 case DICTIONARY_ELEMENTS: 4159 case DICTIONARY_ELEMENTS:
4313 case NON_STRICT_ARGUMENTS_ELEMENTS: 4160 case NON_STRICT_ARGUMENTS_ELEMENTS:
4314 UNREACHABLE(); 4161 UNREACHABLE();
4315 break; 4162 break;
4316 } 4163 }
4317 } 4164 }
4318 } 4165 }
4319 4166
4320 4167
4321 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { 4168 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
4322 CpuFeatures::Scope scope(VFP2);
4323 DwVfpRegister value = ToDoubleRegister(instr->value()); 4169 DwVfpRegister value = ToDoubleRegister(instr->value());
4324 Register elements = ToRegister(instr->elements()); 4170 Register elements = ToRegister(instr->elements());
4325 Register key = no_reg; 4171 Register key = no_reg;
4326 Register scratch = scratch0(); 4172 Register scratch = scratch0();
4327 bool key_is_constant = instr->key()->IsConstantOperand(); 4173 bool key_is_constant = instr->key()->IsConstantOperand();
4328 int constant_key = 0; 4174 int constant_key = 0;
4329 4175
4330 // Calculate the effective address of the slot in the array to store the 4176 // Calculate the effective address of the slot in the array to store the
4331 // double value. 4177 // double value.
4332 if (key_is_constant) { 4178 if (key_is_constant) {
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
4589 4435
4590 4436
4591 void LCodeGen::DoStringLength(LStringLength* instr) { 4437 void LCodeGen::DoStringLength(LStringLength* instr) {
4592 Register string = ToRegister(instr->string()); 4438 Register string = ToRegister(instr->string());
4593 Register result = ToRegister(instr->result()); 4439 Register result = ToRegister(instr->result());
4594 __ ldr(result, FieldMemOperand(string, String::kLengthOffset)); 4440 __ ldr(result, FieldMemOperand(string, String::kLengthOffset));
4595 } 4441 }
4596 4442
4597 4443
4598 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 4444 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4599 CpuFeatures::Scope scope(VFP2);
4600 LOperand* input = instr->value(); 4445 LOperand* input = instr->value();
4601 ASSERT(input->IsRegister() || input->IsStackSlot()); 4446 ASSERT(input->IsRegister() || input->IsStackSlot());
4602 LOperand* output = instr->result(); 4447 LOperand* output = instr->result();
4603 ASSERT(output->IsDoubleRegister()); 4448 ASSERT(output->IsDoubleRegister());
4604 SwVfpRegister single_scratch = double_scratch0().low(); 4449 SwVfpRegister single_scratch = double_scratch0().low();
4605 if (input->IsStackSlot()) { 4450 if (input->IsStackSlot()) {
4606 Register scratch = scratch0(); 4451 Register scratch = scratch0();
4607 __ ldr(scratch, ToMemOperand(input)); 4452 __ ldr(scratch, ToMemOperand(input));
4608 __ vmov(single_scratch, scratch); 4453 __ vmov(single_scratch, scratch);
4609 } else { 4454 } else {
4610 __ vmov(single_scratch, ToRegister(input)); 4455 __ vmov(single_scratch, ToRegister(input));
4611 } 4456 }
4612 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch); 4457 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch);
4613 } 4458 }
4614 4459
4615 4460
4616 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { 4461 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4617 CpuFeatures::Scope scope(VFP2);
4618 LOperand* input = instr->value(); 4462 LOperand* input = instr->value();
4619 LOperand* output = instr->result(); 4463 LOperand* output = instr->result();
4620 4464
4621 SwVfpRegister flt_scratch = double_scratch0().low(); 4465 SwVfpRegister flt_scratch = double_scratch0().low();
4622 __ vmov(flt_scratch, ToRegister(input)); 4466 __ vmov(flt_scratch, ToRegister(input));
4623 __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch); 4467 __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch);
4624 } 4468 }
4625 4469
4626 4470
4627 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4471 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
4669 Register reg = ToRegister(input); 4513 Register reg = ToRegister(input);
4670 4514
4671 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); 4515 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4672 __ cmp(reg, Operand(Smi::kMaxValue)); 4516 __ cmp(reg, Operand(Smi::kMaxValue));
4673 __ b(hi, deferred->entry()); 4517 __ b(hi, deferred->entry());
4674 __ SmiTag(reg, reg); 4518 __ SmiTag(reg, reg);
4675 __ bind(deferred->exit()); 4519 __ bind(deferred->exit());
4676 } 4520 }
4677 4521
4678 4522
4679 // Convert unsigned integer with specified number of leading zeroes in binary
4680 // representation to IEEE 754 double.
4681 // Integer to convert is passed in register hiword.
4682 // Resulting double is returned in registers hiword:loword.
4683 // This functions does not work correctly for 0.
4684 static void GenerateUInt2Double(MacroAssembler* masm,
4685 Register hiword,
4686 Register loword,
4687 Register scratch,
4688 int leading_zeroes) {
4689 const int meaningful_bits = kBitsPerInt - leading_zeroes - 1;
4690 const int biased_exponent = HeapNumber::kExponentBias + meaningful_bits;
4691
4692 const int mantissa_shift_for_hi_word =
4693 meaningful_bits - HeapNumber::kMantissaBitsInTopWord;
4694 const int mantissa_shift_for_lo_word =
4695 kBitsPerInt - mantissa_shift_for_hi_word;
4696 masm->mov(scratch, Operand(biased_exponent << HeapNumber::kExponentShift));
4697 if (mantissa_shift_for_hi_word > 0) {
4698 masm->mov(loword, Operand(hiword, LSL, mantissa_shift_for_lo_word));
4699 masm->orr(hiword, scratch,
4700 Operand(hiword, LSR, mantissa_shift_for_hi_word));
4701 } else {
4702 masm->mov(loword, Operand(0, RelocInfo::NONE));
4703 masm->orr(hiword, scratch,
4704 Operand(hiword, LSL, -mantissa_shift_for_hi_word));
4705 }
4706
4707 // If least significant bit of biased exponent was not 1 it was corrupted
4708 // by most significant bit of mantissa so we should fix that.
4709 if (!(biased_exponent & 1)) {
4710 masm->bic(hiword, hiword, Operand(1 << HeapNumber::kExponentShift));
4711 }
4712 }
4713
4714
4715 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, 4523 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
4716 LOperand* value, 4524 LOperand* value,
4717 IntegerSignedness signedness) { 4525 IntegerSignedness signedness) {
4718 Label slow; 4526 Label slow;
4719 Register src = ToRegister(value); 4527 Register src = ToRegister(value);
4720 Register dst = ToRegister(instr->result()); 4528 Register dst = ToRegister(instr->result());
4721 DwVfpRegister dbl_scratch = double_scratch0(); 4529 DoubleRegister dbl_scratch = double_scratch0();
4722 SwVfpRegister flt_scratch = dbl_scratch.low(); 4530 SwVfpRegister flt_scratch = dbl_scratch.low();
4723 4531
4724 // Preserve the value of all registers. 4532 // Preserve the value of all registers.
4725 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 4533 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
4726 4534
4727 Label done; 4535 Label done;
4728 if (signedness == SIGNED_INT32) { 4536 if (signedness == SIGNED_INT32) {
4729 // There was overflow, so bits 30 and 31 of the original integer 4537 // There was overflow, so bits 30 and 31 of the original integer
4730 // disagree. Try to allocate a heap number in new space and store 4538 // disagree. Try to allocate a heap number in new space and store
4731 // the value in there. If that fails, call the runtime system. 4539 // the value in there. If that fails, call the runtime system.
4732 if (dst.is(src)) { 4540 if (dst.is(src)) {
4733 __ SmiUntag(src, dst); 4541 __ SmiUntag(src, dst);
4734 __ eor(src, src, Operand(0x80000000)); 4542 __ eor(src, src, Operand(0x80000000));
4735 } 4543 }
4736 if (CpuFeatures::IsSupported(VFP2)) { 4544 __ vmov(flt_scratch, src);
4737 CpuFeatures::Scope scope(VFP2); 4545 __ vcvt_f64_s32(dbl_scratch, flt_scratch);
4738 __ vmov(flt_scratch, src);
4739 __ vcvt_f64_s32(dbl_scratch, flt_scratch);
4740 } else {
4741 FloatingPointHelper::Destination dest =
4742 FloatingPointHelper::kCoreRegisters;
4743 FloatingPointHelper::ConvertIntToDouble(masm(), src, dest, d0,
4744 sfpd_lo, sfpd_hi,
4745 scratch0(), s0);
4746 }
4747 } else { 4546 } else {
4748 if (CpuFeatures::IsSupported(VFP2)) { 4547 __ vmov(flt_scratch, src);
4749 CpuFeatures::Scope scope(VFP2); 4548 __ vcvt_f64_u32(dbl_scratch, flt_scratch);
4750 __ vmov(flt_scratch, src);
4751 __ vcvt_f64_u32(dbl_scratch, flt_scratch);
4752 } else {
4753 Label no_leading_zero, done;
4754 __ tst(src, Operand(0x80000000));
4755 __ b(ne, &no_leading_zero);
4756
4757 // Integer has one leading zeros.
4758 GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, r9, 1);
4759 __ b(&done);
4760
4761 __ bind(&no_leading_zero);
4762 GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, r9, 0);
4763 __ b(&done);
4764 }
4765 } 4549 }
4766 4550
4767 if (FLAG_inline_new) { 4551 if (FLAG_inline_new) {
4768 __ LoadRoot(scratch0(), Heap::kHeapNumberMapRootIndex); 4552 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
4769 __ AllocateHeapNumber(r5, r3, r4, scratch0(), &slow, DONT_TAG_RESULT); 4553 __ AllocateHeapNumber(r5, r3, r4, r6, &slow, DONT_TAG_RESULT);
4770 __ Move(dst, r5); 4554 __ Move(dst, r5);
4771 __ b(&done); 4555 __ b(&done);
4772 } 4556 }
4773 4557
4774 // Slow case: Call the runtime system to do the number allocation. 4558 // Slow case: Call the runtime system to do the number allocation.
4775 __ bind(&slow); 4559 __ bind(&slow);
4776 4560
4777 // TODO(3095996): Put a valid pointer value in the stack slot where the result 4561 // TODO(3095996): Put a valid pointer value in the stack slot where the result
4778 // register is stored, as this register is in the pointer map, but contains an 4562 // register is stored, as this register is in the pointer map, but contains an
4779 // integer value. 4563 // integer value.
4780 __ mov(ip, Operand(0)); 4564 __ mov(ip, Operand(0));
4781 __ StoreToSafepointRegisterSlot(ip, dst); 4565 __ StoreToSafepointRegisterSlot(ip, dst);
4782 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); 4566 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
4783 __ Move(dst, r0); 4567 __ Move(dst, r0);
4784 __ sub(dst, dst, Operand(kHeapObjectTag)); 4568 __ sub(dst, dst, Operand(kHeapObjectTag));
4785 4569
4786 // Done. Put the value in dbl_scratch into the value of the allocated heap 4570 // Done. Put the value in dbl_scratch into the value of the allocated heap
4787 // number. 4571 // number.
4788 __ bind(&done); 4572 __ bind(&done);
4789 if (CpuFeatures::IsSupported(VFP2)) { 4573 __ vstr(dbl_scratch, dst, HeapNumber::kValueOffset);
4790 CpuFeatures::Scope scope(VFP2);
4791 __ vstr(dbl_scratch, dst, HeapNumber::kValueOffset);
4792 } else {
4793 __ str(sfpd_lo, MemOperand(dst, HeapNumber::kMantissaOffset));
4794 __ str(sfpd_hi, MemOperand(dst, HeapNumber::kExponentOffset));
4795 }
4796 __ add(dst, dst, Operand(kHeapObjectTag)); 4574 __ add(dst, dst, Operand(kHeapObjectTag));
4797 __ StoreToSafepointRegisterSlot(dst, dst); 4575 __ StoreToSafepointRegisterSlot(dst, dst);
4798 } 4576 }
4799 4577
4800 4578
4801 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { 4579 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
4802 class DeferredNumberTagD: public LDeferredCode { 4580 class DeferredNumberTagD: public LDeferredCode {
4803 public: 4581 public:
4804 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 4582 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4805 : LDeferredCode(codegen), instr_(instr) { } 4583 : LDeferredCode(codegen), instr_(instr) { }
4806 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 4584 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); }
4807 virtual LInstruction* instr() { return instr_; } 4585 virtual LInstruction* instr() { return instr_; }
4808 private: 4586 private:
4809 LNumberTagD* instr_; 4587 LNumberTagD* instr_;
4810 }; 4588 };
4811 4589
4812 DwVfpRegister input_reg = ToDoubleRegister(instr->value()); 4590 DoubleRegister input_reg = ToDoubleRegister(instr->value());
4813 Register scratch = scratch0(); 4591 Register scratch = scratch0();
4814 Register reg = ToRegister(instr->result()); 4592 Register reg = ToRegister(instr->result());
4815 Register temp1 = ToRegister(instr->temp()); 4593 Register temp1 = ToRegister(instr->temp());
4816 Register temp2 = ToRegister(instr->temp2()); 4594 Register temp2 = ToRegister(instr->temp2());
4817 4595
4818 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); 4596 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4819 if (FLAG_inline_new) { 4597 if (FLAG_inline_new) {
4820 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); 4598 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex);
4821 // We want the untagged address first for performance 4599 // We want the untagged address first for performance
4822 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(), 4600 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(),
4823 DONT_TAG_RESULT); 4601 DONT_TAG_RESULT);
4824 } else { 4602 } else {
4825 __ jmp(deferred->entry()); 4603 __ jmp(deferred->entry());
4826 } 4604 }
4827 __ bind(deferred->exit()); 4605 __ bind(deferred->exit());
4828 if (CpuFeatures::IsSupported(VFP2)) { 4606 __ vstr(input_reg, reg, HeapNumber::kValueOffset);
4829 CpuFeatures::Scope scope(VFP2);
4830 __ vstr(input_reg, reg, HeapNumber::kValueOffset);
4831 } else {
4832 __ str(sfpd_lo, MemOperand(reg, HeapNumber::kValueOffset));
4833 __ str(sfpd_hi, MemOperand(reg, HeapNumber::kValueOffset + kPointerSize));
4834 }
4835 // Now that we have finished with the object's real address tag it 4607 // Now that we have finished with the object's real address tag it
4836 __ add(reg, reg, Operand(kHeapObjectTag)); 4608 __ add(reg, reg, Operand(kHeapObjectTag));
4837 } 4609 }
4838 4610
4839 4611
4840 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 4612 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
4841 // TODO(3095996): Get rid of this. For now, we need to make the 4613 // TODO(3095996): Get rid of this. For now, we need to make the
4842 // result register contain a valid pointer because it is already 4614 // result register contain a valid pointer because it is already
4843 // contained in the register pointer map. 4615 // contained in the register pointer map.
4844 Register reg = ToRegister(instr->result()); 4616 Register reg = ToRegister(instr->result());
(...skipping 20 matching lines...) Expand all
4865 // If the input is a HeapObject, SmiUntag will set the carry flag. 4637 // If the input is a HeapObject, SmiUntag will set the carry flag.
4866 __ SmiUntag(result, input, SetCC); 4638 __ SmiUntag(result, input, SetCC);
4867 DeoptimizeIf(cs, instr->environment()); 4639 DeoptimizeIf(cs, instr->environment());
4868 } else { 4640 } else {
4869 __ SmiUntag(result, input); 4641 __ SmiUntag(result, input);
4870 } 4642 }
4871 } 4643 }
4872 4644
4873 4645
4874 void LCodeGen::EmitNumberUntagD(Register input_reg, 4646 void LCodeGen::EmitNumberUntagD(Register input_reg,
4875 DwVfpRegister result_reg, 4647 DoubleRegister result_reg,
4876 bool deoptimize_on_undefined, 4648 bool deoptimize_on_undefined,
4877 bool deoptimize_on_minus_zero, 4649 bool deoptimize_on_minus_zero,
4878 LEnvironment* env) { 4650 LEnvironment* env) {
4879 Register scratch = scratch0(); 4651 Register scratch = scratch0();
4880 SwVfpRegister flt_scratch = double_scratch0().low(); 4652 SwVfpRegister flt_scratch = double_scratch0().low();
4881 ASSERT(!result_reg.is(double_scratch0())); 4653 ASSERT(!result_reg.is(double_scratch0()));
4882 CpuFeatures::Scope scope(VFP2);
4883 4654
4884 Label load_smi, heap_number, done; 4655 Label load_smi, heap_number, done;
4885 4656
4886 // Smi check. 4657 // Smi check.
4887 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); 4658 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi);
4888 4659
4889 // Heap number map check. 4660 // Heap number map check.
4890 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4661 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
4891 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 4662 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
4892 __ cmp(scratch, Operand(ip)); 4663 __ cmp(scratch, Operand(ip));
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
4947 // SmiUntag(heap_object, SetCC) 4718 // SmiUntag(heap_object, SetCC)
4948 STATIC_ASSERT(kHeapObjectTag == 1); 4719 STATIC_ASSERT(kHeapObjectTag == 1);
4949 __ adc(input_reg, input_reg, Operand(input_reg)); 4720 __ adc(input_reg, input_reg, Operand(input_reg));
4950 4721
4951 // Heap number map check. 4722 // Heap number map check.
4952 __ ldr(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4723 __ ldr(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset));
4953 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 4724 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
4954 __ cmp(scratch1, Operand(ip)); 4725 __ cmp(scratch1, Operand(ip));
4955 4726
4956 if (instr->truncating()) { 4727 if (instr->truncating()) {
4957 CpuFeatures::Scope scope(VFP2);
4958 Register scratch3 = ToRegister(instr->temp2()); 4728 Register scratch3 = ToRegister(instr->temp2());
4959 SwVfpRegister single_scratch = double_scratch.low(); 4729 SwVfpRegister single_scratch = double_scratch.low();
4960 ASSERT(!scratch3.is(input_reg) && 4730 ASSERT(!scratch3.is(input_reg) &&
4961 !scratch3.is(scratch1) && 4731 !scratch3.is(scratch1) &&
4962 !scratch3.is(scratch2)); 4732 !scratch3.is(scratch2));
4963 // Performs a truncating conversion of a floating point number as used by 4733 // Performs a truncating conversion of a floating point number as used by
4964 // the JS bitwise operations. 4734 // the JS bitwise operations.
4965 Label heap_number; 4735 Label heap_number;
4966 __ b(eq, &heap_number); 4736 __ b(eq, &heap_number);
4967 // Check for undefined. Undefined is converted to zero for truncating 4737 // Check for undefined. Undefined is converted to zero for truncating
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
5039 } 4809 }
5040 4810
5041 4811
5042 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 4812 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
5043 LOperand* input = instr->value(); 4813 LOperand* input = instr->value();
5044 ASSERT(input->IsRegister()); 4814 ASSERT(input->IsRegister());
5045 LOperand* result = instr->result(); 4815 LOperand* result = instr->result();
5046 ASSERT(result->IsDoubleRegister()); 4816 ASSERT(result->IsDoubleRegister());
5047 4817
5048 Register input_reg = ToRegister(input); 4818 Register input_reg = ToRegister(input);
5049 DwVfpRegister result_reg = ToDoubleRegister(result); 4819 DoubleRegister result_reg = ToDoubleRegister(result);
5050 4820
5051 EmitNumberUntagD(input_reg, result_reg, 4821 EmitNumberUntagD(input_reg, result_reg,
5052 instr->hydrogen()->deoptimize_on_undefined(), 4822 instr->hydrogen()->deoptimize_on_undefined(),
5053 instr->hydrogen()->deoptimize_on_minus_zero(), 4823 instr->hydrogen()->deoptimize_on_minus_zero(),
5054 instr->environment()); 4824 instr->environment());
5055 } 4825 }
5056 4826
5057 4827
5058 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 4828 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
5059 Register result_reg = ToRegister(instr->result()); 4829 Register result_reg = ToRegister(instr->result());
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
5188 __ CompareMap(reg, scratch, map, &success, REQUIRE_EXACT_MAP); 4958 __ CompareMap(reg, scratch, map, &success, REQUIRE_EXACT_MAP);
5189 __ b(eq, &success); 4959 __ b(eq, &success);
5190 } 4960 }
5191 Handle<Map> map = map_set->last(); 4961 Handle<Map> map = map_set->last();
5192 DoCheckMapCommon(reg, scratch, map, REQUIRE_EXACT_MAP, instr->environment()); 4962 DoCheckMapCommon(reg, scratch, map, REQUIRE_EXACT_MAP, instr->environment());
5193 __ bind(&success); 4963 __ bind(&success);
5194 } 4964 }
5195 4965
5196 4966
5197 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 4967 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
5198 CpuFeatures::Scope vfp_scope(VFP2); 4968 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped());
5199 DwVfpRegister value_reg = ToDoubleRegister(instr->unclamped());
5200 Register result_reg = ToRegister(instr->result()); 4969 Register result_reg = ToRegister(instr->result());
5201 DwVfpRegister temp_reg = ToDoubleRegister(instr->temp()); 4970 DoubleRegister temp_reg = ToDoubleRegister(instr->temp());
5202 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg); 4971 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg);
5203 } 4972 }
5204 4973
5205 4974
5206 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { 4975 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
5207 CpuFeatures::Scope scope(VFP2);
5208 Register unclamped_reg = ToRegister(instr->unclamped()); 4976 Register unclamped_reg = ToRegister(instr->unclamped());
5209 Register result_reg = ToRegister(instr->result()); 4977 Register result_reg = ToRegister(instr->result());
5210 __ ClampUint8(result_reg, unclamped_reg); 4978 __ ClampUint8(result_reg, unclamped_reg);
5211 } 4979 }
5212 4980
5213 4981
5214 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { 4982 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
5215 CpuFeatures::Scope scope(VFP2);
5216 Register scratch = scratch0(); 4983 Register scratch = scratch0();
5217 Register input_reg = ToRegister(instr->unclamped()); 4984 Register input_reg = ToRegister(instr->unclamped());
5218 Register result_reg = ToRegister(instr->result()); 4985 Register result_reg = ToRegister(instr->result());
5219 DwVfpRegister temp_reg = ToDoubleRegister(instr->temp()); 4986 DoubleRegister temp_reg = ToDoubleRegister(instr->temp());
5220 Label is_smi, done, heap_number; 4987 Label is_smi, done, heap_number;
5221 4988
5222 // Both smi and heap number cases are handled. 4989 // Both smi and heap number cases are handled.
5223 __ UntagAndJumpIfSmi(result_reg, input_reg, &is_smi); 4990 __ UntagAndJumpIfSmi(result_reg, input_reg, &is_smi);
5224 4991
5225 // Check for heap number 4992 // Check for heap number
5226 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4993 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
5227 __ cmp(scratch, Operand(factory()->heap_number_map())); 4994 __ cmp(scratch, Operand(factory()->heap_number_map()));
5228 __ b(eq, &heap_number); 4995 __ b(eq, &heap_number);
5229 4996
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after
5786 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset)); 5553 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset));
5787 5554
5788 // Check the marker in the calling frame. 5555 // Check the marker in the calling frame.
5789 __ bind(&check_frame_marker); 5556 __ bind(&check_frame_marker);
5790 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset)); 5557 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset));
5791 __ cmp(temp1, Operand(Smi::FromInt(StackFrame::CONSTRUCT))); 5558 __ cmp(temp1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
5792 } 5559 }
5793 5560
5794 5561
5795 void LCodeGen::EnsureSpaceForLazyDeopt() { 5562 void LCodeGen::EnsureSpaceForLazyDeopt() {
5796 if (info()->IsStub()) return;
5797 // Ensure that we have enough space after the previous lazy-bailout 5563 // Ensure that we have enough space after the previous lazy-bailout
5798 // instruction for patching the code here. 5564 // instruction for patching the code here.
5799 int current_pc = masm()->pc_offset(); 5565 int current_pc = masm()->pc_offset();
5800 int patch_size = Deoptimizer::patch_size(); 5566 int patch_size = Deoptimizer::patch_size();
5801 if (current_pc < last_lazy_deopt_pc_ + patch_size) { 5567 if (current_pc < last_lazy_deopt_pc_ + patch_size) {
5802 // Block literal pool emission for duration of padding. 5568 // Block literal pool emission for duration of padding.
5803 Assembler::BlockConstPoolScope block_const_pool(masm()); 5569 Assembler::BlockConstPoolScope block_const_pool(masm());
5804 int padding_size = last_lazy_deopt_pc_ + patch_size - current_pc; 5570 int padding_size = last_lazy_deopt_pc_ + patch_size - current_pc;
5805 ASSERT_EQ(0, padding_size % Assembler::kInstrSize); 5571 ASSERT_EQ(0, padding_size % Assembler::kInstrSize);
5806 while (padding_size > 0) { 5572 while (padding_size > 0) {
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
6018 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); 5784 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize));
6019 __ ldr(result, FieldMemOperand(scratch, 5785 __ ldr(result, FieldMemOperand(scratch,
6020 FixedArray::kHeaderSize - kPointerSize)); 5786 FixedArray::kHeaderSize - kPointerSize));
6021 __ bind(&done); 5787 __ bind(&done);
6022 } 5788 }
6023 5789
6024 5790
6025 #undef __ 5791 #undef __
6026 5792
6027 } } // namespace v8::internal 5793 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/lithium-codegen-arm.h ('k') | src/arm/lithium-gap-resolver-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698