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

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

Issue 11498006: Revert 13157, 13145 and 13140: Crankshaft code stubs. (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 {
151 PredictableCodeSizeScope predictible_code_size_scope( 152 PredictableCodeSizeScope predictible_code_size_scope(
152 masm_, kNoCodeAgeSequenceLength * Assembler::kInstrSize); 153 masm_, kNoCodeAgeSequenceLength * Assembler::kInstrSize);
153 // The following three instructions must remain together and unmodified 154 // The following three instructions must remain together and unmodified
154 // for code aging to work properly. 155 // for code aging to work properly.
155 __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit()); 156 __ stm(db_w, sp, r1.bit() | cp.bit() | fp.bit() | lr.bit());
156 // Load undefined value here, so the value is ready for the loop 157 // Load undefined value here, so the value is ready for the loop
157 // below. 158 // below.
158 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 159 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
159 // Adjust FP to point to saved FP. 160 // Adjust FP to point to saved FP.
160 __ add(fp, sp, Operand(2 * kPointerSize)); 161 __ add(fp, sp, Operand(2 * kPointerSize));
161 frame_is_built_ = true;
162 } 162 }
163 163
164 // Reserve space for the stack slots needed by the code. 164 // Reserve space for the stack slots needed by the code.
165 int slots = GetStackSlotCount(); 165 int slots = GetStackSlotCount();
166 if (slots > 0) { 166 if (slots > 0) {
167 if (FLAG_debug_code) { 167 if (FLAG_debug_code) {
168 __ mov(r0, Operand(slots)); 168 __ mov(r0, Operand(slots));
169 __ mov(r2, Operand(kSlotsZapValue)); 169 __ mov(r2, Operand(kSlotsZapValue));
170 Label loop; 170 Label loop;
171 __ bind(&loop); 171 __ bind(&loop);
172 __ push(r2); 172 __ push(r2);
173 __ sub(r0, r0, Operand(1), SetCC); 173 __ sub(r0, r0, Operand(1), SetCC);
174 __ b(ne, &loop); 174 __ b(ne, &loop);
175 } else { 175 } else {
176 __ sub(sp, sp, Operand(slots * kPointerSize)); 176 __ sub(sp, sp, Operand(slots * kPointerSize));
177 } 177 }
178 } 178 }
179 179
180 // Possibly allocate a local context. 180 // Possibly allocate a local context.
181 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 181 int heap_slots = scope()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
182 if (heap_slots > 0) { 182 if (heap_slots > 0) {
183 Comment(";;; Allocate local context"); 183 Comment(";;; Allocate local context");
184 // Argument to NewContext is the function, which is in r1. 184 // Argument to NewContext is the function, which is in r1.
185 __ push(r1); 185 __ push(r1);
186 if (heap_slots <= FastNewContextStub::kMaximumSlots) { 186 if (heap_slots <= FastNewContextStub::kMaximumSlots) {
187 FastNewContextStub stub(heap_slots); 187 FastNewContextStub stub(heap_slots);
188 __ CallStub(&stub); 188 __ CallStub(&stub);
189 } else { 189 } else {
190 __ CallRuntime(Runtime::kNewFunctionContext, 1); 190 __ CallRuntime(Runtime::kNewFunctionContext, 1);
191 } 191 }
(...skipping 15 matching lines...) Expand all
207 __ str(r0, target); 207 __ str(r0, target);
208 // Update the write barrier. This clobbers r3 and r0. 208 // Update the write barrier. This clobbers r3 and r0.
209 __ RecordWriteContextSlot( 209 __ RecordWriteContextSlot(
210 cp, target.offset(), r0, r3, kLRHasBeenSaved, kSaveFPRegs); 210 cp, target.offset(), r0, r3, kLRHasBeenSaved, kSaveFPRegs);
211 } 211 }
212 } 212 }
213 Comment(";;; End allocate local context"); 213 Comment(";;; End allocate local context");
214 } 214 }
215 215
216 // Trace the call. 216 // Trace the call.
217 if (FLAG_trace && info()->IsOptimizing()) { 217 if (FLAG_trace) {
218 __ CallRuntime(Runtime::kTraceEnter, 0); 218 __ CallRuntime(Runtime::kTraceEnter, 0);
219 } 219 }
220 return !is_aborted(); 220 return !is_aborted();
221 } 221 }
222 222
223 223
224 bool LCodeGen::GenerateBody() { 224 bool LCodeGen::GenerateBody() {
225 ASSERT(is_generating()); 225 ASSERT(is_generating());
226 bool emit_instructions = true; 226 bool emit_instructions = true;
227 for (current_instruction_ = 0; 227 for (current_instruction_ = 0;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 return !is_aborted(); 265 return !is_aborted();
266 } 266 }
267 267
268 268
269 bool LCodeGen::GenerateDeferredCode() { 269 bool LCodeGen::GenerateDeferredCode() {
270 ASSERT(is_generating()); 270 ASSERT(is_generating());
271 if (deferred_.length() > 0) { 271 if (deferred_.length() > 0) {
272 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) { 272 for (int i = 0; !is_aborted() && i < deferred_.length(); i++) {
273 LDeferredCode* code = deferred_[i]; 273 LDeferredCode* code = deferred_[i];
274 __ bind(code->entry()); 274 __ bind(code->entry());
275 if (NeedsDeferredFrame()) {
276 Comment(";;; Deferred build frame",
277 code->instruction_index(),
278 code->instr()->Mnemonic());
279 ASSERT(!frame_is_built_);
280 ASSERT(info()->IsStub());
281 frame_is_built_ = true;
282 __ stm(db_w, sp, cp.bit() | fp.bit() | lr.bit());
283 __ mov(scratch0(), Operand(Smi::FromInt(StackFrame::STUB)));
284 __ push(scratch0());
285 __ add(fp, sp, Operand(2 * kPointerSize));
286 }
287 Comment(";;; Deferred code @%d: %s.", 275 Comment(";;; Deferred code @%d: %s.",
288 code->instruction_index(), 276 code->instruction_index(),
289 code->instr()->Mnemonic()); 277 code->instr()->Mnemonic());
290 code->Generate(); 278 code->Generate();
291 if (NeedsDeferredFrame()) {
292 Comment(";;; Deferred destroy frame",
293 code->instruction_index(),
294 code->instr()->Mnemonic());
295 ASSERT(frame_is_built_);
296 __ pop(ip);
297 __ ldm(ia_w, sp, cp.bit() | fp.bit() | lr.bit());
298 frame_is_built_ = false;
299 }
300 __ jmp(code->exit()); 279 __ jmp(code->exit());
301 } 280 }
302 } 281 }
303 282
304 // Force constant pool emission at the end of the deferred code to make 283 // Force constant pool emission at the end of the deferred code to make
305 // sure that no constant pools are emitted after. 284 // sure that no constant pools are emitted after.
306 masm()->CheckConstPool(true, false); 285 masm()->CheckConstPool(true, false);
307 286
308 return !is_aborted(); 287 return !is_aborted();
309 } 288 }
310 289
311 290
312 bool LCodeGen::GenerateDeoptJumpTable() { 291 bool LCodeGen::GenerateDeoptJumpTable() {
313 // Check that the jump table is accessible from everywhere in the function 292 // Check that the jump table is accessible from everywhere in the function
314 // code, i.e. that offsets to the table can be encoded in the 24bit signed 293 // code, i.e. that offsets to the table can be encoded in the 24bit signed
315 // immediate of a branch instruction. 294 // immediate of a branch instruction.
316 // To simplify we consider the code size from the first instruction to the 295 // To simplify we consider the code size from the first instruction to the
317 // end of the jump table. We also don't consider the pc load delta. 296 // end of the jump table. We also don't consider the pc load delta.
318 // Each entry in the jump table generates one instruction and inlines one 297 // Each entry in the jump table generates one instruction and inlines one
319 // 32bit data after it. 298 // 32bit data after it.
320 if (!is_int24((masm()->pc_offset() / Assembler::kInstrSize) + 299 if (!is_int24((masm()->pc_offset() / Assembler::kInstrSize) +
321 deopt_jump_table_.length() * 7)) { 300 deopt_jump_table_.length() * 2)) {
322 Abort("Generated code is too large"); 301 Abort("Generated code is too large");
323 } 302 }
324 303
304 // Block the constant pool emission during the jump table emission.
305 __ BlockConstPoolFor(deopt_jump_table_.length());
325 __ RecordComment("[ Deoptimisation jump table"); 306 __ RecordComment("[ Deoptimisation jump table");
326 Label table_start; 307 Label table_start;
327 __ bind(&table_start); 308 __ bind(&table_start);
328 Label needs_frame_not_call;
329 Label needs_frame_is_call;
330 for (int i = 0; i < deopt_jump_table_.length(); i++) { 309 for (int i = 0; i < deopt_jump_table_.length(); i++) {
331 __ bind(&deopt_jump_table_[i].label); 310 __ bind(&deopt_jump_table_[i].label);
332 Address entry = deopt_jump_table_[i].address; 311 __ ldr(pc, MemOperand(pc, Assembler::kInstrSize - Assembler::kPcLoadDelta));
333 if (deopt_jump_table_[i].needs_frame) { 312 __ dd(reinterpret_cast<uint32_t>(deopt_jump_table_[i].address));
334 __ mov(ip, Operand(ExternalReference::ForDeoptEntry(entry)));
335 if (deopt_jump_table_[i].is_lazy_deopt) {
336 if (needs_frame_is_call.is_bound()) {
337 __ b(&needs_frame_is_call);
338 } else {
339 __ bind(&needs_frame_is_call);
340 __ stm(db_w, sp, cp.bit() | fp.bit() | lr.bit());
341 // This variant of deopt can only be used with stubs. Since we don't
342 // have a function pointer to install in the stack frame that we're
343 // building, install a special marker there instead.
344 ASSERT(info()->IsStub());
345 __ mov(scratch0(), Operand(Smi::FromInt(StackFrame::STUB)));
346 __ push(scratch0());
347 __ add(fp, sp, Operand(2 * kPointerSize));
348 __ mov(lr, Operand(pc), LeaveCC, al);
349 __ mov(pc, ip);
350 }
351 } else {
352 if (needs_frame_not_call.is_bound()) {
353 __ b(&needs_frame_not_call);
354 } else {
355 __ bind(&needs_frame_not_call);
356 __ stm(db_w, sp, cp.bit() | fp.bit() | lr.bit());
357 // This variant of deopt can only be used with stubs. Since we don't
358 // have a function pointer to install in the stack frame that we're
359 // building, install a special marker there instead.
360 ASSERT(info()->IsStub());
361 __ mov(scratch0(), Operand(Smi::FromInt(StackFrame::STUB)));
362 __ push(scratch0());
363 __ add(fp, sp, Operand(2 * kPointerSize));
364 __ mov(pc, ip);
365 }
366 }
367 } else {
368 if (deopt_jump_table_[i].is_lazy_deopt) {
369 __ mov(lr, Operand(pc), LeaveCC, al);
370 __ mov(pc, Operand(ExternalReference::ForDeoptEntry(entry)));
371 } else {
372 __ mov(pc, Operand(ExternalReference::ForDeoptEntry(entry)));
373 }
374 }
375 masm()->CheckConstPool(false, false);
376 } 313 }
314 ASSERT(masm()->InstructionsGeneratedSince(&table_start) ==
315 deopt_jump_table_.length() * 2);
377 __ RecordComment("]"); 316 __ RecordComment("]");
378 317
379 // Force constant pool emission at the end of the deopt jump table to make
380 // sure that no constant pools are emitted after.
381 masm()->CheckConstPool(true, false);
382
383 // The deoptimization jump table is the last part of the instruction 318 // The deoptimization jump table is the last part of the instruction
384 // sequence. Mark the generated code as done unless we bailed out. 319 // sequence. Mark the generated code as done unless we bailed out.
385 if (!is_aborted()) status_ = DONE; 320 if (!is_aborted()) status_ = DONE;
386 return !is_aborted(); 321 return !is_aborted();
387 } 322 }
388 323
389 324
390 bool LCodeGen::GenerateSafepointTable() { 325 bool LCodeGen::GenerateSafepointTable() {
391 ASSERT(is_done()); 326 ASSERT(is_done());
392 safepoints_.Emit(masm(), GetStackSlotCount()); 327 safepoints_.Emit(masm(), GetStackSlotCount());
393 return !is_aborted(); 328 return !is_aborted();
394 } 329 }
395 330
396 331
397 Register LCodeGen::ToRegister(int index) const { 332 Register LCodeGen::ToRegister(int index) const {
398 return Register::FromAllocationIndex(index); 333 return Register::FromAllocationIndex(index);
399 } 334 }
400 335
401 336
402 DwVfpRegister LCodeGen::ToDoubleRegister(int index) const { 337 DoubleRegister LCodeGen::ToDoubleRegister(int index) const {
403 return DwVfpRegister::FromAllocationIndex(index); 338 return DoubleRegister::FromAllocationIndex(index);
404 } 339 }
405 340
406 341
407 Register LCodeGen::ToRegister(LOperand* op) const { 342 Register LCodeGen::ToRegister(LOperand* op) const {
408 ASSERT(op->IsRegister()); 343 ASSERT(op->IsRegister());
409 return ToRegister(op->index()); 344 return ToRegister(op->index());
410 } 345 }
411 346
412 347
413 Register LCodeGen::EmitLoadRegister(LOperand* op, Register scratch) { 348 Register LCodeGen::EmitLoadRegister(LOperand* op, Register scratch) {
(...skipping 20 matching lines...) Expand all
434 return scratch; 369 return scratch;
435 } else if (op->IsStackSlot() || op->IsArgument()) { 370 } else if (op->IsStackSlot() || op->IsArgument()) {
436 __ ldr(scratch, ToMemOperand(op)); 371 __ ldr(scratch, ToMemOperand(op));
437 return scratch; 372 return scratch;
438 } 373 }
439 UNREACHABLE(); 374 UNREACHABLE();
440 return scratch; 375 return scratch;
441 } 376 }
442 377
443 378
444 DwVfpRegister LCodeGen::ToDoubleRegister(LOperand* op) const { 379 DoubleRegister LCodeGen::ToDoubleRegister(LOperand* op) const {
445 ASSERT(op->IsDoubleRegister()); 380 ASSERT(op->IsDoubleRegister());
446 return ToDoubleRegister(op->index()); 381 return ToDoubleRegister(op->index());
447 } 382 }
448 383
449 384
450 DwVfpRegister LCodeGen::EmitLoadDoubleRegister(LOperand* op, 385 DoubleRegister LCodeGen::EmitLoadDoubleRegister(LOperand* op,
451 SwVfpRegister flt_scratch, 386 SwVfpRegister flt_scratch,
452 DwVfpRegister dbl_scratch) { 387 DoubleRegister dbl_scratch) {
453 if (op->IsDoubleRegister()) { 388 if (op->IsDoubleRegister()) {
454 return ToDoubleRegister(op->index()); 389 return ToDoubleRegister(op->index());
455 } else if (op->IsConstantOperand()) { 390 } else if (op->IsConstantOperand()) {
456 LConstantOperand* const_op = LConstantOperand::cast(op); 391 LConstantOperand* const_op = LConstantOperand::cast(op);
457 HConstant* constant = chunk_->LookupConstant(const_op); 392 HConstant* constant = chunk_->LookupConstant(const_op);
458 Handle<Object> literal = constant->handle(); 393 Handle<Object> literal = constant->handle();
459 Representation r = chunk_->LookupLiteralRepresentation(const_op); 394 Representation r = chunk_->LookupLiteralRepresentation(const_op);
460 if (r.IsInteger32()) { 395 if (r.IsInteger32()) {
461 ASSERT(literal->IsNumber()); 396 ASSERT(literal->IsNumber());
462 __ mov(ip, Operand(static_cast<int32_t>(literal->Number()))); 397 __ mov(ip, Operand(static_cast<int32_t>(literal->Number())));
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 // arguments index points to the first element of a sequence of tagged 513 // arguments index points to the first element of a sequence of tagged
579 // values on the stack that represent the arguments. This needs to be 514 // values on the stack that represent the arguments. This needs to be
580 // kept in sync with the LArgumentsElements implementation. 515 // kept in sync with the LArgumentsElements implementation.
581 *arguments_index = -environment->parameter_count(); 516 *arguments_index = -environment->parameter_count();
582 *arguments_count = environment->parameter_count(); 517 *arguments_count = environment->parameter_count();
583 518
584 WriteTranslation(environment->outer(), 519 WriteTranslation(environment->outer(),
585 translation, 520 translation,
586 arguments_index, 521 arguments_index,
587 arguments_count); 522 arguments_count);
588 bool has_closure_id = !info()->closure().is_null() && 523 int closure_id = *info()->closure() != *environment->closure()
589 *info()->closure() != *environment->closure();
590 int closure_id = has_closure_id
591 ? DefineDeoptimizationLiteral(environment->closure()) 524 ? DefineDeoptimizationLiteral(environment->closure())
592 : Translation::kSelfLiteralId; 525 : Translation::kSelfLiteralId;
593 526
594 switch (environment->frame_type()) { 527 switch (environment->frame_type()) {
595 case JS_FUNCTION: 528 case JS_FUNCTION:
596 translation->BeginJSFrame(environment->ast_id(), closure_id, height); 529 translation->BeginJSFrame(environment->ast_id(), closure_id, height);
597 break; 530 break;
598 case JS_CONSTRUCT: 531 case JS_CONSTRUCT:
599 translation->BeginConstructStubFrame(closure_id, translation_size); 532 translation->BeginConstructStubFrame(closure_id, translation_size);
600 break; 533 break;
601 case JS_GETTER: 534 case JS_GETTER:
602 ASSERT(translation_size == 1); 535 ASSERT(translation_size == 1);
603 ASSERT(height == 0); 536 ASSERT(height == 0);
604 translation->BeginGetterStubFrame(closure_id); 537 translation->BeginGetterStubFrame(closure_id);
605 break; 538 break;
606 case JS_SETTER: 539 case JS_SETTER:
607 ASSERT(translation_size == 2); 540 ASSERT(translation_size == 2);
608 ASSERT(height == 0); 541 ASSERT(height == 0);
609 translation->BeginSetterStubFrame(closure_id); 542 translation->BeginSetterStubFrame(closure_id);
610 break; 543 break;
611 case STUB:
612 translation->BeginCompiledStubFrame();
613 break;
614 case ARGUMENTS_ADAPTOR: 544 case ARGUMENTS_ADAPTOR:
615 translation->BeginArgumentsAdaptorFrame(closure_id, translation_size); 545 translation->BeginArgumentsAdaptorFrame(closure_id, translation_size);
616 break; 546 break;
617 } 547 }
618 548
619 // Inlined frames which push their arguments cause the index to be 549 // Inlined frames which push their arguments cause the index to be
620 // bumped and a new stack area to be used for materialization. 550 // bumped and a new stack area to be used for materialization.
621 if (environment->entry() != NULL && 551 if (environment->entry() != NULL &&
622 environment->entry()->arguments_pushed()) { 552 environment->entry()->arguments_pushed()) {
623 *arguments_index = *arguments_index < 0 553 *arguments_index = *arguments_index < 0
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
799 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1); 729 (mode == Safepoint::kLazyDeopt) ? pc_offset : -1);
800 deoptimizations_.Add(environment, zone()); 730 deoptimizations_.Add(environment, zone());
801 } 731 }
802 } 732 }
803 733
804 734
805 void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) { 735 void LCodeGen::DeoptimizeIf(Condition cc, LEnvironment* environment) {
806 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt); 736 RegisterEnvironmentForDeoptimization(environment, Safepoint::kNoLazyDeopt);
807 ASSERT(environment->HasBeenRegistered()); 737 ASSERT(environment->HasBeenRegistered());
808 int id = environment->deoptimization_index(); 738 int id = environment->deoptimization_index();
809 739 Address entry = Deoptimizer::GetDeoptimizationEntry(id, Deoptimizer::EAGER);
810 Deoptimizer::BailoutType bailout_type = info()->IsStub()
811 ? Deoptimizer::LAZY
812 : Deoptimizer::EAGER;
813 Address entry = Deoptimizer::GetDeoptimizationEntry(id, bailout_type);
814 if (entry == NULL) { 740 if (entry == NULL) {
815 Abort("bailout was not prepared"); 741 Abort("bailout was not prepared");
816 return; 742 return;
817 } 743 }
818 744
819 ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on ARM. 745 ASSERT(FLAG_deopt_every_n_times < 2); // Other values not supported on ARM.
820 746
821 if (FLAG_deopt_every_n_times == 1 && 747 if (FLAG_deopt_every_n_times == 1 &&
822 info_->shared_info()->opt_count() == id) { 748 info_->shared_info()->opt_count() == id) {
823 __ Jump(entry, RelocInfo::RUNTIME_ENTRY); 749 __ Jump(entry, RelocInfo::RUNTIME_ENTRY);
824 return; 750 return;
825 } 751 }
826 752
827 if (FLAG_trap_on_deopt) __ stop("trap_on_deopt", cc); 753 if (FLAG_trap_on_deopt) __ stop("trap_on_deopt", cc);
828 754
829 bool needs_lazy_deopt = info()->IsStub(); 755 if (cc == al) {
830 ASSERT(info()->IsStub() || frame_is_built_);
831 if (cc == al && !needs_lazy_deopt) {
832 __ Jump(entry, RelocInfo::RUNTIME_ENTRY); 756 __ Jump(entry, RelocInfo::RUNTIME_ENTRY);
833 } else { 757 } else {
834 // We often have several deopts to the same entry, reuse the last 758 // We often have several deopts to the same entry, reuse the last
835 // jump entry if this is the case. 759 // jump entry if this is the case.
836 if (deopt_jump_table_.is_empty() || 760 if (deopt_jump_table_.is_empty() ||
837 (deopt_jump_table_.last().address != entry) || 761 (deopt_jump_table_.last().address != entry)) {
838 (deopt_jump_table_.last().is_lazy_deopt != needs_lazy_deopt) || 762 deopt_jump_table_.Add(JumpTableEntry(entry), zone());
839 (deopt_jump_table_.last().needs_frame != !frame_is_built_)) {
840 JumpTableEntry table_entry(entry, !frame_is_built_, needs_lazy_deopt);
841 deopt_jump_table_.Add(table_entry, zone());
842 } 763 }
843 __ b(cc, &deopt_jump_table_.last().label); 764 __ b(cc, &deopt_jump_table_.last().label);
844 } 765 }
845 } 766 }
846 767
847 768
848 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) { 769 void LCodeGen::PopulateDeoptimizationData(Handle<Code> code) {
849 int length = deoptimizations_.length(); 770 int length = deoptimizations_.length();
850 if (length == 0) return; 771 if (length == 0) return;
851 Handle<DeoptimizationInputData> data = 772 Handle<DeoptimizationInputData> data =
(...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after
1440 __ cmp(remainder, Operand(0)); 1361 __ cmp(remainder, Operand(0));
1441 __ teq(remainder, Operand(divisor), ne); 1362 __ teq(remainder, Operand(divisor), ne);
1442 __ sub(result, result, Operand(1), LeaveCC, mi); 1363 __ sub(result, result, Operand(1), LeaveCC, mi);
1443 } 1364 }
1444 1365
1445 1366
1446 void LCodeGen::DoDeferredBinaryOpStub(LPointerMap* pointer_map, 1367 void LCodeGen::DoDeferredBinaryOpStub(LPointerMap* pointer_map,
1447 LOperand* left_argument, 1368 LOperand* left_argument,
1448 LOperand* right_argument, 1369 LOperand* right_argument,
1449 Token::Value op) { 1370 Token::Value op) {
1450 CpuFeatures::Scope vfp_scope(VFP2);
1451 Register left = ToRegister(left_argument); 1371 Register left = ToRegister(left_argument);
1452 Register right = ToRegister(right_argument); 1372 Register right = ToRegister(right_argument);
1453 1373
1454 PushSafepointRegistersScope scope(this, Safepoint::kWithRegistersAndDoubles); 1374 PushSafepointRegistersScope scope(this, Safepoint::kWithRegistersAndDoubles);
1455 // Move left to r1 and right to r0 for the stub call. 1375 // Move left to r1 and right to r0 for the stub call.
1456 if (left.is(r1)) { 1376 if (left.is(r1)) {
1457 __ Move(r0, right); 1377 __ Move(r0, right);
1458 } else if (left.is(r0) && right.is(r1)) { 1378 } else if (left.is(r0) && right.is(r1)) {
1459 __ Swap(r0, r1, r2); 1379 __ Swap(r0, r1, r2);
1460 } else if (left.is(r0)) { 1380 } else if (left.is(r0)) {
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
1726 1646
1727 void LCodeGen::DoConstantI(LConstantI* instr) { 1647 void LCodeGen::DoConstantI(LConstantI* instr) {
1728 ASSERT(instr->result()->IsRegister()); 1648 ASSERT(instr->result()->IsRegister());
1729 __ mov(ToRegister(instr->result()), Operand(instr->value())); 1649 __ mov(ToRegister(instr->result()), Operand(instr->value()));
1730 } 1650 }
1731 1651
1732 1652
1733 void LCodeGen::DoConstantD(LConstantD* instr) { 1653 void LCodeGen::DoConstantD(LConstantD* instr) {
1734 ASSERT(instr->result()->IsDoubleRegister()); 1654 ASSERT(instr->result()->IsDoubleRegister());
1735 DwVfpRegister result = ToDoubleRegister(instr->result()); 1655 DwVfpRegister result = ToDoubleRegister(instr->result());
1736 CpuFeatures::Scope scope(VFP2);
1737 double v = instr->value(); 1656 double v = instr->value();
1738 __ Vmov(result, v, scratch0()); 1657 __ Vmov(result, v, scratch0());
1739 } 1658 }
1740 1659
1741 1660
1742 void LCodeGen::DoConstantT(LConstantT* instr) { 1661 void LCodeGen::DoConstantT(LConstantT* instr) {
1743 Handle<Object> value = instr->value(); 1662 Handle<Object> value = instr->value();
1744 if (value->IsSmi()) { 1663 if (value->IsSmi()) {
1745 __ mov(ToRegister(instr->result()), Operand(value)); 1664 __ mov(ToRegister(instr->result()), Operand(value));
1746 } else { 1665 } else {
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1904 ? ToOperand(right) 1823 ? ToOperand(right)
1905 : Operand(EmitLoadRegister(right, ip)); 1824 : Operand(EmitLoadRegister(right, ip));
1906 Register result_reg = ToRegister(instr->result()); 1825 Register result_reg = ToRegister(instr->result());
1907 __ cmp(left_reg, right_op); 1826 __ cmp(left_reg, right_op);
1908 if (!result_reg.is(left_reg)) { 1827 if (!result_reg.is(left_reg)) {
1909 __ mov(result_reg, left_reg, LeaveCC, condition); 1828 __ mov(result_reg, left_reg, LeaveCC, condition);
1910 } 1829 }
1911 __ mov(result_reg, right_op, LeaveCC, NegateCondition(condition)); 1830 __ mov(result_reg, right_op, LeaveCC, NegateCondition(condition));
1912 } else { 1831 } else {
1913 ASSERT(instr->hydrogen()->representation().IsDouble()); 1832 ASSERT(instr->hydrogen()->representation().IsDouble());
1914 CpuFeatures::Scope scope(VFP2); 1833 DoubleRegister left_reg = ToDoubleRegister(left);
1915 DwVfpRegister left_reg = ToDoubleRegister(left); 1834 DoubleRegister right_reg = ToDoubleRegister(right);
1916 DwVfpRegister right_reg = ToDoubleRegister(right); 1835 DoubleRegister result_reg = ToDoubleRegister(instr->result());
1917 DwVfpRegister result_reg = ToDoubleRegister(instr->result());
1918 Label check_nan_left, check_zero, return_left, return_right, done; 1836 Label check_nan_left, check_zero, return_left, return_right, done;
1919 __ VFPCompareAndSetFlags(left_reg, right_reg); 1837 __ VFPCompareAndSetFlags(left_reg, right_reg);
1920 __ b(vs, &check_nan_left); 1838 __ b(vs, &check_nan_left);
1921 __ b(eq, &check_zero); 1839 __ b(eq, &check_zero);
1922 __ b(condition, &return_left); 1840 __ b(condition, &return_left);
1923 __ b(al, &return_right); 1841 __ b(al, &return_right);
1924 1842
1925 __ bind(&check_zero); 1843 __ bind(&check_zero);
1926 __ VFPCompareAndSetFlags(left_reg, 0.0); 1844 __ VFPCompareAndSetFlags(left_reg, 0.0);
1927 __ b(ne, &return_left); // left == right != 0. 1845 __ b(ne, &return_left); // left == right != 0.
(...skipping 22 matching lines...) Expand all
1950 __ bind(&return_left); 1868 __ bind(&return_left);
1951 if (!left_reg.is(result_reg)) { 1869 if (!left_reg.is(result_reg)) {
1952 __ vmov(result_reg, left_reg); 1870 __ vmov(result_reg, left_reg);
1953 } 1871 }
1954 __ bind(&done); 1872 __ bind(&done);
1955 } 1873 }
1956 } 1874 }
1957 1875
1958 1876
1959 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { 1877 void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
1960 CpuFeatures::Scope scope(VFP2); 1878 DoubleRegister left = ToDoubleRegister(instr->left());
1961 DwVfpRegister left = ToDoubleRegister(instr->left()); 1879 DoubleRegister right = ToDoubleRegister(instr->right());
1962 DwVfpRegister right = ToDoubleRegister(instr->right()); 1880 DoubleRegister result = ToDoubleRegister(instr->result());
1963 DwVfpRegister result = ToDoubleRegister(instr->result());
1964 switch (instr->op()) { 1881 switch (instr->op()) {
1965 case Token::ADD: 1882 case Token::ADD:
1966 __ vadd(result, left, right); 1883 __ vadd(result, left, right);
1967 break; 1884 break;
1968 case Token::SUB: 1885 case Token::SUB:
1969 __ vsub(result, left, right); 1886 __ vsub(result, left, right);
1970 break; 1887 break;
1971 case Token::MUL: 1888 case Token::MUL:
1972 __ vmul(result, left, right); 1889 __ vmul(result, left, right);
1973 break; 1890 break;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
2041 void LCodeGen::DoBranch(LBranch* instr) { 1958 void LCodeGen::DoBranch(LBranch* instr) {
2042 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1959 int true_block = chunk_->LookupDestination(instr->true_block_id());
2043 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1960 int false_block = chunk_->LookupDestination(instr->false_block_id());
2044 1961
2045 Representation r = instr->hydrogen()->value()->representation(); 1962 Representation r = instr->hydrogen()->value()->representation();
2046 if (r.IsInteger32()) { 1963 if (r.IsInteger32()) {
2047 Register reg = ToRegister(instr->value()); 1964 Register reg = ToRegister(instr->value());
2048 __ cmp(reg, Operand(0)); 1965 __ cmp(reg, Operand(0));
2049 EmitBranch(true_block, false_block, ne); 1966 EmitBranch(true_block, false_block, ne);
2050 } else if (r.IsDouble()) { 1967 } else if (r.IsDouble()) {
2051 CpuFeatures::Scope scope(VFP2); 1968 DoubleRegister reg = ToDoubleRegister(instr->value());
2052 DwVfpRegister reg = ToDoubleRegister(instr->value());
2053 Register scratch = scratch0(); 1969 Register scratch = scratch0();
2054 1970
2055 // Test the double value. Zero and NaN are false. 1971 // Test the double value. Zero and NaN are false.
2056 __ VFPCompareAndLoadFlags(reg, 0.0, scratch); 1972 __ VFPCompareAndLoadFlags(reg, 0.0, scratch);
2057 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit)); 1973 __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit));
2058 EmitBranch(true_block, false_block, eq); 1974 EmitBranch(true_block, false_block, eq);
2059 } else { 1975 } else {
2060 ASSERT(r.IsTagged()); 1976 ASSERT(r.IsTagged());
2061 Register reg = ToRegister(instr->value()); 1977 Register reg = ToRegister(instr->value());
2062 HType type = instr->hydrogen()->value()->type(); 1978 HType type = instr->hydrogen()->value()->type();
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
2127 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE); 2043 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE);
2128 __ b(ge, &not_string); 2044 __ b(ge, &not_string);
2129 __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset)); 2045 __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset));
2130 __ cmp(ip, Operand(0)); 2046 __ cmp(ip, Operand(0));
2131 __ b(ne, true_label); 2047 __ b(ne, true_label);
2132 __ b(false_label); 2048 __ b(false_label);
2133 __ bind(&not_string); 2049 __ bind(&not_string);
2134 } 2050 }
2135 2051
2136 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { 2052 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
2137 CpuFeatures::Scope scope(VFP2);
2138 // heap number -> false iff +0, -0, or NaN. 2053 // heap number -> false iff +0, -0, or NaN.
2139 DwVfpRegister dbl_scratch = double_scratch0(); 2054 DoubleRegister dbl_scratch = double_scratch0();
2140 Label not_heap_number; 2055 Label not_heap_number;
2141 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); 2056 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
2142 __ b(ne, &not_heap_number); 2057 __ b(ne, &not_heap_number);
2143 __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); 2058 __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset));
2144 __ VFPCompareAndSetFlags(dbl_scratch, 0.0); 2059 __ VFPCompareAndSetFlags(dbl_scratch, 0.0);
2145 __ b(vs, false_label); // NaN -> false. 2060 __ b(vs, false_label); // NaN -> false.
2146 __ b(eq, false_label); // +0, -0 -> false. 2061 __ b(eq, false_label); // +0, -0 -> false.
2147 __ b(true_label); 2062 __ b(true_label);
2148 __ bind(&not_heap_number); 2063 __ bind(&not_heap_number);
2149 } 2064 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2207 if (left->IsConstantOperand() && right->IsConstantOperand()) { 2122 if (left->IsConstantOperand() && right->IsConstantOperand()) {
2208 // We can statically evaluate the comparison. 2123 // We can statically evaluate the comparison.
2209 double left_val = ToDouble(LConstantOperand::cast(left)); 2124 double left_val = ToDouble(LConstantOperand::cast(left));
2210 double right_val = ToDouble(LConstantOperand::cast(right)); 2125 double right_val = ToDouble(LConstantOperand::cast(right));
2211 int next_block = 2126 int next_block =
2212 EvalComparison(instr->op(), left_val, right_val) ? true_block 2127 EvalComparison(instr->op(), left_val, right_val) ? true_block
2213 : false_block; 2128 : false_block;
2214 EmitGoto(next_block); 2129 EmitGoto(next_block);
2215 } else { 2130 } else {
2216 if (instr->is_double()) { 2131 if (instr->is_double()) {
2217 CpuFeatures::Scope scope(VFP2);
2218 // Compare left and right operands as doubles and load the 2132 // Compare left and right operands as doubles and load the
2219 // resulting flags into the normal status register. 2133 // resulting flags into the normal status register.
2220 __ VFPCompareAndSetFlags(ToDoubleRegister(left), ToDoubleRegister(right)); 2134 __ VFPCompareAndSetFlags(ToDoubleRegister(left), ToDoubleRegister(right));
2221 // If a NaN is involved, i.e. the result is unordered (V set), 2135 // If a NaN is involved, i.e. the result is unordered (V set),
2222 // jump to false block label. 2136 // jump to false block label.
2223 __ b(vs, chunk_->GetAssemblyLabel(false_block)); 2137 __ b(vs, chunk_->GetAssemblyLabel(false_block));
2224 } else { 2138 } else {
2225 if (right->IsConstantOperand()) { 2139 if (right->IsConstantOperand()) {
2226 __ cmp(ToRegister(left), 2140 __ cmp(ToRegister(left),
2227 Operand(ToInteger32(LConstantOperand::cast(right)))); 2141 Operand(ToInteger32(LConstantOperand::cast(right))));
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after
2746 __ LoadRoot(ToRegister(instr->result()), 2660 __ LoadRoot(ToRegister(instr->result()),
2747 Heap::kTrueValueRootIndex, 2661 Heap::kTrueValueRootIndex,
2748 condition); 2662 condition);
2749 __ LoadRoot(ToRegister(instr->result()), 2663 __ LoadRoot(ToRegister(instr->result()),
2750 Heap::kFalseValueRootIndex, 2664 Heap::kFalseValueRootIndex,
2751 NegateCondition(condition)); 2665 NegateCondition(condition));
2752 } 2666 }
2753 2667
2754 2668
2755 void LCodeGen::DoReturn(LReturn* instr) { 2669 void LCodeGen::DoReturn(LReturn* instr) {
2756 if (FLAG_trace && info()->IsOptimizing()) { 2670 if (FLAG_trace) {
2757 // Push the return value on the stack as the parameter. 2671 // Push the return value on the stack as the parameter.
2758 // Runtime::TraceExit returns its parameter in r0. 2672 // Runtime::TraceExit returns its parameter in r0.
2759 __ push(r0); 2673 __ push(r0);
2760 __ CallRuntime(Runtime::kTraceExit, 1); 2674 __ CallRuntime(Runtime::kTraceExit, 1);
2761 } 2675 }
2762 if (NeedsEagerFrame()) { 2676 int32_t sp_delta = (GetParameterCount() + 1) * kPointerSize;
2763 int32_t sp_delta = (GetParameterCount() + 1) * kPointerSize; 2677 __ mov(sp, fp);
2764 __ mov(sp, fp); 2678 __ ldm(ia_w, sp, fp.bit() | lr.bit());
2765 __ ldm(ia_w, sp, fp.bit() | lr.bit()); 2679 __ add(sp, sp, Operand(sp_delta));
2766 __ add(sp, sp, Operand(sp_delta));
2767 }
2768 if (info()->IsStub()) {
2769 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
2770 }
2771 __ Jump(lr); 2680 __ Jump(lr);
2772 } 2681 }
2773 2682
2774 2683
2775 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { 2684 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
2776 Register result = ToRegister(instr->result()); 2685 Register result = ToRegister(instr->result());
2777 __ mov(ip, Operand(Handle<Object>(instr->hydrogen()->cell()))); 2686 __ mov(ip, Operand(Handle<Object>(instr->hydrogen()->cell())));
2778 __ ldr(result, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset)); 2687 __ ldr(result, FieldMemOperand(ip, JSGlobalPropertyCell::kValueOffset));
2779 if (instr->hydrogen()->RequiresHoleCheck()) { 2688 if (instr->hydrogen()->RequiresHoleCheck()) {
2780 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 2689 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
3110 } else { 3019 } else {
3111 key = ToRegister(instr->key()); 3020 key = ToRegister(instr->key());
3112 } 3021 }
3113 int element_size_shift = ElementsKindToShiftSize(elements_kind); 3022 int element_size_shift = ElementsKindToShiftSize(elements_kind);
3114 int shift_size = (instr->hydrogen()->key()->representation().IsTagged()) 3023 int shift_size = (instr->hydrogen()->key()->representation().IsTagged())
3115 ? (element_size_shift - kSmiTagSize) : element_size_shift; 3024 ? (element_size_shift - kSmiTagSize) : element_size_shift;
3116 int additional_offset = instr->additional_index() << element_size_shift; 3025 int additional_offset = instr->additional_index() << element_size_shift;
3117 3026
3118 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || 3027 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
3119 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { 3028 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3029 CpuFeatures::Scope scope(VFP3);
3120 DwVfpRegister result = ToDoubleRegister(instr->result()); 3030 DwVfpRegister result = ToDoubleRegister(instr->result());
3121 Operand operand = key_is_constant 3031 Operand operand = key_is_constant
3122 ? Operand(constant_key << element_size_shift) 3032 ? Operand(constant_key << element_size_shift)
3123 : Operand(key, LSL, shift_size); 3033 : Operand(key, LSL, shift_size);
3124 __ add(scratch0(), external_pointer, operand); 3034 __ add(scratch0(), external_pointer, operand);
3125 if (CpuFeatures::IsSupported(VFP2)) { 3035 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3126 CpuFeatures::Scope scope(VFP2); 3036 __ vldr(result.low(), scratch0(), additional_offset);
3127 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { 3037 __ vcvt_f64_f32(result, result.low());
3128 __ vldr(result.low(), scratch0(), additional_offset); 3038 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
3129 __ vcvt_f64_f32(result, result.low()); 3039 __ vldr(result, scratch0(), additional_offset);
3130 } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
3131 __ vldr(result, scratch0(), additional_offset);
3132 }
3133 } else {
3134 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3135 Register value = external_pointer;
3136 __ ldr(value, MemOperand(scratch0(), additional_offset));
3137 __ and_(sfpd_lo, value, Operand(kBinary32MantissaMask));
3138
3139 __ mov(scratch0(), Operand(value, LSR, kBinary32MantissaBits));
3140 __ and_(scratch0(), scratch0(),
3141 Operand(kBinary32ExponentMask >> kBinary32MantissaBits));
3142
3143 Label exponent_rebiased;
3144 __ teq(scratch0(), Operand(0x00));
3145 __ b(eq, &exponent_rebiased);
3146
3147 __ teq(scratch0(), Operand(0xff));
3148 __ mov(scratch0(), Operand(0x7ff), LeaveCC, eq);
3149 __ b(eq, &exponent_rebiased);
3150
3151 // Rebias exponent.
3152 __ add(scratch0(),
3153 scratch0(),
3154 Operand(-kBinary32ExponentBias + HeapNumber::kExponentBias));
3155
3156 __ bind(&exponent_rebiased);
3157 __ and_(sfpd_hi, value, Operand(kBinary32SignMask));
3158 __ orr(sfpd_hi, sfpd_hi,
3159 Operand(scratch0(), LSL, HeapNumber::kMantissaBitsInTopWord));
3160
3161 // Shift mantissa.
3162 static const int kMantissaShiftForHiWord =
3163 kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord;
3164
3165 static const int kMantissaShiftForLoWord =
3166 kBitsPerInt - kMantissaShiftForHiWord;
3167
3168 __ orr(sfpd_hi, sfpd_hi,
3169 Operand(sfpd_lo, LSR, kMantissaShiftForHiWord));
3170 __ mov(sfpd_lo, Operand(sfpd_lo, LSL, kMantissaShiftForLoWord));
3171
3172 } else {
3173 __ ldr(sfpd_lo, MemOperand(scratch0(), additional_offset));
3174 __ ldr(sfpd_hi, MemOperand(scratch0(),
3175 additional_offset + kPointerSize));
3176 }
3177 } 3040 }
3178 } else { 3041 } else {
3179 Register result = ToRegister(instr->result()); 3042 Register result = ToRegister(instr->result());
3180 MemOperand mem_operand = PrepareKeyedOperand( 3043 MemOperand mem_operand = PrepareKeyedOperand(
3181 key, external_pointer, key_is_constant, constant_key, 3044 key, external_pointer, key_is_constant, constant_key,
3182 element_size_shift, shift_size, 3045 element_size_shift, shift_size,
3183 instr->additional_index(), additional_offset); 3046 instr->additional_index(), additional_offset);
3184 switch (elements_kind) { 3047 switch (elements_kind) {
3185 case EXTERNAL_BYTE_ELEMENTS: 3048 case EXTERNAL_BYTE_ELEMENTS:
3186 __ ldrsb(result, mem_operand); 3049 __ ldrsb(result, mem_operand);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3235 int constant_key = 0; 3098 int constant_key = 0;
3236 if (key_is_constant) { 3099 if (key_is_constant) {
3237 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 3100 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
3238 if (constant_key & 0xF0000000) { 3101 if (constant_key & 0xF0000000) {
3239 Abort("array index constant value too big."); 3102 Abort("array index constant value too big.");
3240 } 3103 }
3241 } else { 3104 } else {
3242 key = ToRegister(instr->key()); 3105 key = ToRegister(instr->key());
3243 } 3106 }
3244 3107
3245 int base_offset = (FixedDoubleArray::kHeaderSize - kHeapObjectTag) + 3108 Operand operand = key_is_constant
3246 ((constant_key + instr->additional_index()) << element_size_shift); 3109 ? Operand(((constant_key + instr->additional_index()) <<
3110 element_size_shift) +
3111 FixedDoubleArray::kHeaderSize - kHeapObjectTag)
3112 : Operand(key, LSL, shift_size);
3113 __ add(elements, elements, operand);
3247 if (!key_is_constant) { 3114 if (!key_is_constant) {
3248 __ add(elements, elements, Operand(key, LSL, shift_size)); 3115 __ add(elements, elements,
3116 Operand((FixedDoubleArray::kHeaderSize - kHeapObjectTag) +
3117 (instr->additional_index() << element_size_shift)));
3249 } 3118 }
3250 if (CpuFeatures::IsSupported(VFP2)) { 3119
3251 CpuFeatures::Scope scope(VFP2); 3120 __ vldr(result, elements, 0);
3252 __ add(elements, elements, Operand(base_offset)); 3121 if (instr->hydrogen()->RequiresHoleCheck()) {
3253 __ vldr(result, elements, 0); 3122 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32)));
3254 if (instr->hydrogen()->RequiresHoleCheck()) { 3123 __ cmp(scratch, Operand(kHoleNanUpper32));
3255 __ ldr(scratch, MemOperand(elements, sizeof(kHoleNanLower32))); 3124 DeoptimizeIf(eq, instr->environment());
3256 __ cmp(scratch, Operand(kHoleNanUpper32));
3257 DeoptimizeIf(eq, instr->environment());
3258 }
3259 } else {
3260 __ ldr(sfpd_hi, MemOperand(elements, base_offset + kPointerSize));
3261 __ ldr(sfpd_lo, MemOperand(elements, base_offset));
3262 if (instr->hydrogen()->RequiresHoleCheck()) {
3263 ASSERT(kPointerSize == sizeof(kHoleNanLower32));
3264 __ cmp(sfpd_hi, Operand(kHoleNanUpper32));
3265 DeoptimizeIf(eq, instr->environment());
3266 }
3267 } 3125 }
3268 } 3126 }
3269 3127
3270 3128
3271 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 3129 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3272 Register elements = ToRegister(instr->elements()); 3130 Register elements = ToRegister(instr->elements());
3273 Register result = ToRegister(instr->result()); 3131 Register result = ToRegister(instr->result());
3274 Register scratch = scratch0(); 3132 Register scratch = scratch0();
3275 Register store_base = scratch; 3133 Register store_base = scratch;
3276 int offset = 0; 3134 int offset = 0;
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
3692 // We can make rsb conditional because the previous cmp instruction 3550 // We can make rsb conditional because the previous cmp instruction
3693 // will clear the V (overflow) flag and rsb won't set this flag 3551 // will clear the V (overflow) flag and rsb won't set this flag
3694 // if input is positive. 3552 // if input is positive.
3695 __ rsb(result, input, Operand(0), SetCC, mi); 3553 __ rsb(result, input, Operand(0), SetCC, mi);
3696 // Deoptimize on overflow. 3554 // Deoptimize on overflow.
3697 DeoptimizeIf(vs, instr->environment()); 3555 DeoptimizeIf(vs, instr->environment());
3698 } 3556 }
3699 3557
3700 3558
3701 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { 3559 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) {
3702 CpuFeatures::Scope scope(VFP2);
3703 // Class for deferred case. 3560 // Class for deferred case.
3704 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { 3561 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode {
3705 public: 3562 public:
3706 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, 3563 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen,
3707 LUnaryMathOperation* instr) 3564 LUnaryMathOperation* instr)
3708 : LDeferredCode(codegen), instr_(instr) { } 3565 : LDeferredCode(codegen), instr_(instr) { }
3709 virtual void Generate() { 3566 virtual void Generate() {
3710 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); 3567 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_);
3711 } 3568 }
3712 virtual LInstruction* instr() { return instr_; } 3569 virtual LInstruction* instr() { return instr_; }
(...skipping 16 matching lines...) Expand all
3729 // Smi check. 3586 // Smi check.
3730 __ JumpIfNotSmi(input, deferred->entry()); 3587 __ JumpIfNotSmi(input, deferred->entry());
3731 // If smi, handle it directly. 3588 // If smi, handle it directly.
3732 EmitIntegerMathAbs(instr); 3589 EmitIntegerMathAbs(instr);
3733 __ bind(deferred->exit()); 3590 __ bind(deferred->exit());
3734 } 3591 }
3735 } 3592 }
3736 3593
3737 3594
3738 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { 3595 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
3739 CpuFeatures::Scope scope(VFP2); 3596 DoubleRegister input = ToDoubleRegister(instr->value());
3740 DwVfpRegister input = ToDoubleRegister(instr->value());
3741 Register result = ToRegister(instr->result()); 3597 Register result = ToRegister(instr->result());
3742 Register scratch = scratch0(); 3598 Register scratch = scratch0();
3743 3599
3744 __ EmitVFPTruncate(kRoundToMinusInf, 3600 __ EmitVFPTruncate(kRoundToMinusInf,
3745 result, 3601 result,
3746 input, 3602 input,
3747 scratch, 3603 scratch,
3748 double_scratch0()); 3604 double_scratch0());
3749 DeoptimizeIf(ne, instr->environment()); 3605 DeoptimizeIf(ne, instr->environment());
3750 3606
3751 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3607 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3752 // Test for -0. 3608 // Test for -0.
3753 Label done; 3609 Label done;
3754 __ cmp(result, Operand(0)); 3610 __ cmp(result, Operand(0));
3755 __ b(ne, &done); 3611 __ b(ne, &done);
3756 __ vmov(scratch, input.high()); 3612 __ vmov(scratch, input.high());
3757 __ tst(scratch, Operand(HeapNumber::kSignMask)); 3613 __ tst(scratch, Operand(HeapNumber::kSignMask));
3758 DeoptimizeIf(ne, instr->environment()); 3614 DeoptimizeIf(ne, instr->environment());
3759 __ bind(&done); 3615 __ bind(&done);
3760 } 3616 }
3761 } 3617 }
3762 3618
3763 3619
3764 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { 3620 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
3765 CpuFeatures::Scope scope(VFP2); 3621 DoubleRegister input = ToDoubleRegister(instr->value());
3766 DwVfpRegister input = ToDoubleRegister(instr->value());
3767 Register result = ToRegister(instr->result()); 3622 Register result = ToRegister(instr->result());
3768 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->temp()); 3623 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->temp());
3769 Register scratch = scratch0(); 3624 Register scratch = scratch0();
3770 Label done, check_sign_on_zero; 3625 Label done, check_sign_on_zero;
3771 3626
3772 // Extract exponent bits. 3627 // Extract exponent bits.
3773 __ vmov(result, input.high()); 3628 __ vmov(result, input.high());
3774 __ ubfx(scratch, 3629 __ ubfx(scratch,
3775 result, 3630 result,
3776 HeapNumber::kExponentShift, 3631 HeapNumber::kExponentShift,
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3821 __ bind(&check_sign_on_zero); 3676 __ bind(&check_sign_on_zero);
3822 __ vmov(scratch, input.high()); 3677 __ vmov(scratch, input.high());
3823 __ tst(scratch, Operand(HeapNumber::kSignMask)); 3678 __ tst(scratch, Operand(HeapNumber::kSignMask));
3824 DeoptimizeIf(ne, instr->environment()); 3679 DeoptimizeIf(ne, instr->environment());
3825 } 3680 }
3826 __ bind(&done); 3681 __ bind(&done);
3827 } 3682 }
3828 3683
3829 3684
3830 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { 3685 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) {
3831 CpuFeatures::Scope scope(VFP2); 3686 DoubleRegister input = ToDoubleRegister(instr->value());
3832 DwVfpRegister input = ToDoubleRegister(instr->value()); 3687 DoubleRegister result = ToDoubleRegister(instr->result());
3833 DwVfpRegister result = ToDoubleRegister(instr->result());
3834 __ vsqrt(result, input); 3688 __ vsqrt(result, input);
3835 } 3689 }
3836 3690
3837 3691
3838 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { 3692 void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
3839 CpuFeatures::Scope scope(VFP2); 3693 DoubleRegister input = ToDoubleRegister(instr->value());
3840 DwVfpRegister input = ToDoubleRegister(instr->value()); 3694 DoubleRegister result = ToDoubleRegister(instr->result());
3841 DwVfpRegister result = ToDoubleRegister(instr->result()); 3695 DoubleRegister temp = ToDoubleRegister(instr->temp());
3842 DwVfpRegister temp = ToDoubleRegister(instr->temp());
3843 3696
3844 // Note that according to ECMA-262 15.8.2.13: 3697 // Note that according to ECMA-262 15.8.2.13:
3845 // Math.pow(-Infinity, 0.5) == Infinity 3698 // Math.pow(-Infinity, 0.5) == Infinity
3846 // Math.sqrt(-Infinity) == NaN 3699 // Math.sqrt(-Infinity) == NaN
3847 Label done; 3700 Label done;
3848 __ vmov(temp, -V8_INFINITY, scratch0()); 3701 __ vmov(temp, -V8_INFINITY, scratch0());
3849 __ VFPCompareAndSetFlags(input, temp); 3702 __ VFPCompareAndSetFlags(input, temp);
3850 __ vneg(result, temp, eq); 3703 __ vneg(result, temp, eq);
3851 __ b(&done, eq); 3704 __ b(&done, eq);
3852 3705
3853 // Add +0 to convert -0 to +0. 3706 // Add +0 to convert -0 to +0.
3854 __ vadd(result, input, kDoubleRegZero); 3707 __ vadd(result, input, kDoubleRegZero);
3855 __ vsqrt(result, result); 3708 __ vsqrt(result, result);
3856 __ bind(&done); 3709 __ bind(&done);
3857 } 3710 }
3858 3711
3859 3712
3860 void LCodeGen::DoPower(LPower* instr) { 3713 void LCodeGen::DoPower(LPower* instr) {
3861 CpuFeatures::Scope scope(VFP2);
3862 Representation exponent_type = instr->hydrogen()->right()->representation(); 3714 Representation exponent_type = instr->hydrogen()->right()->representation();
3863 // Having marked this as a call, we can use any registers. 3715 // Having marked this as a call, we can use any registers.
3864 // Just make sure that the input/output registers are the expected ones. 3716 // Just make sure that the input/output registers are the expected ones.
3865 ASSERT(!instr->right()->IsDoubleRegister() || 3717 ASSERT(!instr->right()->IsDoubleRegister() ||
3866 ToDoubleRegister(instr->right()).is(d2)); 3718 ToDoubleRegister(instr->right()).is(d2));
3867 ASSERT(!instr->right()->IsRegister() || 3719 ASSERT(!instr->right()->IsRegister() ||
3868 ToRegister(instr->right()).is(r2)); 3720 ToRegister(instr->right()).is(r2));
3869 ASSERT(ToDoubleRegister(instr->left()).is(d1)); 3721 ASSERT(ToDoubleRegister(instr->left()).is(d1));
3870 ASSERT(ToDoubleRegister(instr->result()).is(d3)); 3722 ASSERT(ToDoubleRegister(instr->result()).is(d3));
3871 3723
(...skipping 12 matching lines...) Expand all
3884 __ CallStub(&stub); 3736 __ CallStub(&stub);
3885 } else { 3737 } else {
3886 ASSERT(exponent_type.IsDouble()); 3738 ASSERT(exponent_type.IsDouble());
3887 MathPowStub stub(MathPowStub::DOUBLE); 3739 MathPowStub stub(MathPowStub::DOUBLE);
3888 __ CallStub(&stub); 3740 __ CallStub(&stub);
3889 } 3741 }
3890 } 3742 }
3891 3743
3892 3744
3893 void LCodeGen::DoRandom(LRandom* instr) { 3745 void LCodeGen::DoRandom(LRandom* instr) {
3894 CpuFeatures::Scope scope(VFP2);
3895 class DeferredDoRandom: public LDeferredCode { 3746 class DeferredDoRandom: public LDeferredCode {
3896 public: 3747 public:
3897 DeferredDoRandom(LCodeGen* codegen, LRandom* instr) 3748 DeferredDoRandom(LCodeGen* codegen, LRandom* instr)
3898 : LDeferredCode(codegen), instr_(instr) { } 3749 : LDeferredCode(codegen), instr_(instr) { }
3899 virtual void Generate() { codegen()->DoDeferredRandom(instr_); } 3750 virtual void Generate() { codegen()->DoDeferredRandom(instr_); }
3900 virtual LInstruction* instr() { return instr_; } 3751 virtual LInstruction* instr() { return instr_; }
3901 private: 3752 private:
3902 LRandom* instr_; 3753 LRandom* instr_;
3903 }; 3754 };
3904 3755
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
3963 3814
3964 3815
3965 void LCodeGen::DoDeferredRandom(LRandom* instr) { 3816 void LCodeGen::DoDeferredRandom(LRandom* instr) {
3966 __ PrepareCallCFunction(1, scratch0()); 3817 __ PrepareCallCFunction(1, scratch0());
3967 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); 3818 __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1);
3968 // Return value is in r0. 3819 // Return value is in r0.
3969 } 3820 }
3970 3821
3971 3822
3972 void LCodeGen::DoMathExp(LMathExp* instr) { 3823 void LCodeGen::DoMathExp(LMathExp* instr) {
3973 CpuFeatures::Scope scope(VFP2); 3824 DoubleRegister input = ToDoubleRegister(instr->value());
3974 DwVfpRegister input = ToDoubleRegister(instr->value()); 3825 DoubleRegister result = ToDoubleRegister(instr->result());
3975 DwVfpRegister result = ToDoubleRegister(instr->result()); 3826 DoubleRegister double_scratch1 = ToDoubleRegister(instr->double_temp());
3976 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->double_temp()); 3827 DoubleRegister double_scratch2 = double_scratch0();
3977 DwVfpRegister double_scratch2 = double_scratch0();
3978 Register temp1 = ToRegister(instr->temp1()); 3828 Register temp1 = ToRegister(instr->temp1());
3979 Register temp2 = ToRegister(instr->temp2()); 3829 Register temp2 = ToRegister(instr->temp2());
3980 3830
3981 MathExpGenerator::EmitMathExp( 3831 MathExpGenerator::EmitMathExp(
3982 masm(), input, result, double_scratch1, double_scratch2, 3832 masm(), input, result, double_scratch1, double_scratch2,
3983 temp1, temp2, scratch0()); 3833 temp1, temp2, scratch0());
3984 } 3834 }
3985 3835
3986 3836
3987 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { 3837 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after
4253 } 4103 }
4254 __ cmp(ip, ToRegister(instr->length())); 4104 __ cmp(ip, ToRegister(instr->length()));
4255 } else { 4105 } else {
4256 __ cmp(ToRegister(instr->index()), ToRegister(instr->length())); 4106 __ cmp(ToRegister(instr->index()), ToRegister(instr->length()));
4257 } 4107 }
4258 DeoptimizeIf(hs, instr->environment()); 4108 DeoptimizeIf(hs, instr->environment());
4259 } 4109 }
4260 4110
4261 4111
4262 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { 4112 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4263 CpuFeatures::Scope scope(VFP2);
4264 Register external_pointer = ToRegister(instr->elements()); 4113 Register external_pointer = ToRegister(instr->elements());
4265 Register key = no_reg; 4114 Register key = no_reg;
4266 ElementsKind elements_kind = instr->elements_kind(); 4115 ElementsKind elements_kind = instr->elements_kind();
4267 bool key_is_constant = instr->key()->IsConstantOperand(); 4116 bool key_is_constant = instr->key()->IsConstantOperand();
4268 int constant_key = 0; 4117 int constant_key = 0;
4269 if (key_is_constant) { 4118 if (key_is_constant) {
4270 constant_key = ToInteger32(LConstantOperand::cast(instr->key())); 4119 constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
4271 if (constant_key & 0xF0000000) { 4120 if (constant_key & 0xF0000000) {
4272 Abort("array index constant value too big."); 4121 Abort("array index constant value too big.");
4273 } 4122 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
4324 case DICTIONARY_ELEMENTS: 4173 case DICTIONARY_ELEMENTS:
4325 case NON_STRICT_ARGUMENTS_ELEMENTS: 4174 case NON_STRICT_ARGUMENTS_ELEMENTS:
4326 UNREACHABLE(); 4175 UNREACHABLE();
4327 break; 4176 break;
4328 } 4177 }
4329 } 4178 }
4330 } 4179 }
4331 4180
4332 4181
4333 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) { 4182 void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
4334 CpuFeatures::Scope scope(VFP2);
4335 DwVfpRegister value = ToDoubleRegister(instr->value()); 4183 DwVfpRegister value = ToDoubleRegister(instr->value());
4336 Register elements = ToRegister(instr->elements()); 4184 Register elements = ToRegister(instr->elements());
4337 Register key = no_reg; 4185 Register key = no_reg;
4338 Register scratch = scratch0(); 4186 Register scratch = scratch0();
4339 bool key_is_constant = instr->key()->IsConstantOperand(); 4187 bool key_is_constant = instr->key()->IsConstantOperand();
4340 int constant_key = 0; 4188 int constant_key = 0;
4341 4189
4342 // Calculate the effective address of the slot in the array to store the 4190 // Calculate the effective address of the slot in the array to store the
4343 // double value. 4191 // double value.
4344 if (key_is_constant) { 4192 if (key_is_constant) {
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
4601 4449
4602 4450
4603 void LCodeGen::DoStringLength(LStringLength* instr) { 4451 void LCodeGen::DoStringLength(LStringLength* instr) {
4604 Register string = ToRegister(instr->string()); 4452 Register string = ToRegister(instr->string());
4605 Register result = ToRegister(instr->result()); 4453 Register result = ToRegister(instr->result());
4606 __ ldr(result, FieldMemOperand(string, String::kLengthOffset)); 4454 __ ldr(result, FieldMemOperand(string, String::kLengthOffset));
4607 } 4455 }
4608 4456
4609 4457
4610 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 4458 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4611 CpuFeatures::Scope scope(VFP2);
4612 LOperand* input = instr->value(); 4459 LOperand* input = instr->value();
4613 ASSERT(input->IsRegister() || input->IsStackSlot()); 4460 ASSERT(input->IsRegister() || input->IsStackSlot());
4614 LOperand* output = instr->result(); 4461 LOperand* output = instr->result();
4615 ASSERT(output->IsDoubleRegister()); 4462 ASSERT(output->IsDoubleRegister());
4616 SwVfpRegister single_scratch = double_scratch0().low(); 4463 SwVfpRegister single_scratch = double_scratch0().low();
4617 if (input->IsStackSlot()) { 4464 if (input->IsStackSlot()) {
4618 Register scratch = scratch0(); 4465 Register scratch = scratch0();
4619 __ ldr(scratch, ToMemOperand(input)); 4466 __ ldr(scratch, ToMemOperand(input));
4620 __ vmov(single_scratch, scratch); 4467 __ vmov(single_scratch, scratch);
4621 } else { 4468 } else {
4622 __ vmov(single_scratch, ToRegister(input)); 4469 __ vmov(single_scratch, ToRegister(input));
4623 } 4470 }
4624 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch); 4471 __ vcvt_f64_s32(ToDoubleRegister(output), single_scratch);
4625 } 4472 }
4626 4473
4627 4474
4628 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { 4475 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) {
4629 CpuFeatures::Scope scope(VFP2);
4630 LOperand* input = instr->value(); 4476 LOperand* input = instr->value();
4631 LOperand* output = instr->result(); 4477 LOperand* output = instr->result();
4632 4478
4633 SwVfpRegister flt_scratch = double_scratch0().low(); 4479 SwVfpRegister flt_scratch = double_scratch0().low();
4634 __ vmov(flt_scratch, ToRegister(input)); 4480 __ vmov(flt_scratch, ToRegister(input));
4635 __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch); 4481 __ vcvt_f64_u32(ToDoubleRegister(output), flt_scratch);
4636 } 4482 }
4637 4483
4638 4484
4639 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 4485 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
4681 Register reg = ToRegister(input); 4527 Register reg = ToRegister(input);
4682 4528
4683 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr); 4529 DeferredNumberTagU* deferred = new(zone()) DeferredNumberTagU(this, instr);
4684 __ cmp(reg, Operand(Smi::kMaxValue)); 4530 __ cmp(reg, Operand(Smi::kMaxValue));
4685 __ b(hi, deferred->entry()); 4531 __ b(hi, deferred->entry());
4686 __ SmiTag(reg, reg); 4532 __ SmiTag(reg, reg);
4687 __ bind(deferred->exit()); 4533 __ bind(deferred->exit());
4688 } 4534 }
4689 4535
4690 4536
4691 // Convert unsigned integer with specified number of leading zeroes in binary
4692 // representation to IEEE 754 double.
4693 // Integer to convert is passed in register hiword.
4694 // Resulting double is returned in registers hiword:loword.
4695 // This functions does not work correctly for 0.
4696 static void GenerateUInt2Double(MacroAssembler* masm,
4697 Register hiword,
4698 Register loword,
4699 Register scratch,
4700 int leading_zeroes) {
4701 const int meaningful_bits = kBitsPerInt - leading_zeroes - 1;
4702 const int biased_exponent = HeapNumber::kExponentBias + meaningful_bits;
4703
4704 const int mantissa_shift_for_hi_word =
4705 meaningful_bits - HeapNumber::kMantissaBitsInTopWord;
4706 const int mantissa_shift_for_lo_word =
4707 kBitsPerInt - mantissa_shift_for_hi_word;
4708 masm->mov(scratch, Operand(biased_exponent << HeapNumber::kExponentShift));
4709 if (mantissa_shift_for_hi_word > 0) {
4710 masm->mov(loword, Operand(hiword, LSL, mantissa_shift_for_lo_word));
4711 masm->orr(hiword, scratch,
4712 Operand(hiword, LSR, mantissa_shift_for_hi_word));
4713 } else {
4714 masm->mov(loword, Operand(0, RelocInfo::NONE));
4715 masm->orr(hiword, scratch,
4716 Operand(hiword, LSL, -mantissa_shift_for_hi_word));
4717 }
4718
4719 // If least significant bit of biased exponent was not 1 it was corrupted
4720 // by most significant bit of mantissa so we should fix that.
4721 if (!(biased_exponent & 1)) {
4722 masm->bic(hiword, hiword, Operand(1 << HeapNumber::kExponentShift));
4723 }
4724 }
4725
4726
4727 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, 4537 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr,
4728 LOperand* value, 4538 LOperand* value,
4729 IntegerSignedness signedness) { 4539 IntegerSignedness signedness) {
4730 Label slow; 4540 Label slow;
4731 Register src = ToRegister(value); 4541 Register src = ToRegister(value);
4732 Register dst = ToRegister(instr->result()); 4542 Register dst = ToRegister(instr->result());
4733 DwVfpRegister dbl_scratch = double_scratch0(); 4543 DoubleRegister dbl_scratch = double_scratch0();
4734 SwVfpRegister flt_scratch = dbl_scratch.low(); 4544 SwVfpRegister flt_scratch = dbl_scratch.low();
4735 4545
4736 // Preserve the value of all registers. 4546 // Preserve the value of all registers.
4737 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); 4547 PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters);
4738 4548
4739 Label done; 4549 Label done;
4740 if (signedness == SIGNED_INT32) { 4550 if (signedness == SIGNED_INT32) {
4741 // There was overflow, so bits 30 and 31 of the original integer 4551 // There was overflow, so bits 30 and 31 of the original integer
4742 // disagree. Try to allocate a heap number in new space and store 4552 // disagree. Try to allocate a heap number in new space and store
4743 // the value in there. If that fails, call the runtime system. 4553 // the value in there. If that fails, call the runtime system.
4744 if (dst.is(src)) { 4554 if (dst.is(src)) {
4745 __ SmiUntag(src, dst); 4555 __ SmiUntag(src, dst);
4746 __ eor(src, src, Operand(0x80000000)); 4556 __ eor(src, src, Operand(0x80000000));
4747 } 4557 }
4748 if (CpuFeatures::IsSupported(VFP2)) { 4558 __ vmov(flt_scratch, src);
4749 CpuFeatures::Scope scope(VFP2); 4559 __ vcvt_f64_s32(dbl_scratch, flt_scratch);
4750 __ vmov(flt_scratch, src);
4751 __ vcvt_f64_s32(dbl_scratch, flt_scratch);
4752 } else {
4753 FloatingPointHelper::Destination dest =
4754 FloatingPointHelper::kCoreRegisters;
4755 FloatingPointHelper::ConvertIntToDouble(masm(), src, dest, d0,
4756 sfpd_lo, sfpd_hi,
4757 scratch0(), s0);
4758 }
4759 } else { 4560 } else {
4760 if (CpuFeatures::IsSupported(VFP2)) { 4561 __ vmov(flt_scratch, src);
4761 CpuFeatures::Scope scope(VFP2); 4562 __ vcvt_f64_u32(dbl_scratch, flt_scratch);
4762 __ vmov(flt_scratch, src);
4763 __ vcvt_f64_u32(dbl_scratch, flt_scratch);
4764 } else {
4765 Label no_leading_zero, done;
4766 __ tst(src, Operand(0x80000000));
4767 __ b(ne, &no_leading_zero);
4768
4769 // Integer has one leading zeros.
4770 GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, r9, 1);
4771 __ b(&done);
4772
4773 __ bind(&no_leading_zero);
4774 GenerateUInt2Double(masm(), sfpd_hi, sfpd_lo, r9, 0);
4775 __ b(&done);
4776 }
4777 } 4563 }
4778 4564
4779 if (FLAG_inline_new) { 4565 if (FLAG_inline_new) {
4780 __ LoadRoot(scratch0(), Heap::kHeapNumberMapRootIndex); 4566 __ LoadRoot(r6, Heap::kHeapNumberMapRootIndex);
4781 __ AllocateHeapNumber(r5, r3, r4, scratch0(), &slow, DONT_TAG_RESULT); 4567 __ AllocateHeapNumber(r5, r3, r4, r6, &slow, DONT_TAG_RESULT);
4782 __ Move(dst, r5); 4568 __ Move(dst, r5);
4783 __ b(&done); 4569 __ b(&done);
4784 } 4570 }
4785 4571
4786 // Slow case: Call the runtime system to do the number allocation. 4572 // Slow case: Call the runtime system to do the number allocation.
4787 __ bind(&slow); 4573 __ bind(&slow);
4788 4574
4789 // TODO(3095996): Put a valid pointer value in the stack slot where the result 4575 // TODO(3095996): Put a valid pointer value in the stack slot where the result
4790 // register is stored, as this register is in the pointer map, but contains an 4576 // register is stored, as this register is in the pointer map, but contains an
4791 // integer value. 4577 // integer value.
4792 __ mov(ip, Operand(0)); 4578 __ mov(ip, Operand(0));
4793 __ StoreToSafepointRegisterSlot(ip, dst); 4579 __ StoreToSafepointRegisterSlot(ip, dst);
4794 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr); 4580 CallRuntimeFromDeferred(Runtime::kAllocateHeapNumber, 0, instr);
4795 __ Move(dst, r0); 4581 __ Move(dst, r0);
4796 __ sub(dst, dst, Operand(kHeapObjectTag)); 4582 __ sub(dst, dst, Operand(kHeapObjectTag));
4797 4583
4798 // Done. Put the value in dbl_scratch into the value of the allocated heap 4584 // Done. Put the value in dbl_scratch into the value of the allocated heap
4799 // number. 4585 // number.
4800 __ bind(&done); 4586 __ bind(&done);
4801 if (CpuFeatures::IsSupported(VFP2)) { 4587 __ vstr(dbl_scratch, dst, HeapNumber::kValueOffset);
4802 CpuFeatures::Scope scope(VFP2);
4803 __ vstr(dbl_scratch, dst, HeapNumber::kValueOffset);
4804 } else {
4805 __ str(sfpd_lo, MemOperand(dst, HeapNumber::kMantissaOffset));
4806 __ str(sfpd_hi, MemOperand(dst, HeapNumber::kExponentOffset));
4807 }
4808 __ add(dst, dst, Operand(kHeapObjectTag)); 4588 __ add(dst, dst, Operand(kHeapObjectTag));
4809 __ StoreToSafepointRegisterSlot(dst, dst); 4589 __ StoreToSafepointRegisterSlot(dst, dst);
4810 } 4590 }
4811 4591
4812 4592
4813 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { 4593 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
4814 class DeferredNumberTagD: public LDeferredCode { 4594 class DeferredNumberTagD: public LDeferredCode {
4815 public: 4595 public:
4816 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr) 4596 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
4817 : LDeferredCode(codegen), instr_(instr) { } 4597 : LDeferredCode(codegen), instr_(instr) { }
4818 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); } 4598 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); }
4819 virtual LInstruction* instr() { return instr_; } 4599 virtual LInstruction* instr() { return instr_; }
4820 private: 4600 private:
4821 LNumberTagD* instr_; 4601 LNumberTagD* instr_;
4822 }; 4602 };
4823 4603
4824 DwVfpRegister input_reg = ToDoubleRegister(instr->value()); 4604 DoubleRegister input_reg = ToDoubleRegister(instr->value());
4825 Register scratch = scratch0(); 4605 Register scratch = scratch0();
4826 Register reg = ToRegister(instr->result()); 4606 Register reg = ToRegister(instr->result());
4827 Register temp1 = ToRegister(instr->temp()); 4607 Register temp1 = ToRegister(instr->temp());
4828 Register temp2 = ToRegister(instr->temp2()); 4608 Register temp2 = ToRegister(instr->temp2());
4829 4609
4830 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr); 4610 DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
4831 if (FLAG_inline_new) { 4611 if (FLAG_inline_new) {
4832 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); 4612 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex);
4833 // We want the untagged address first for performance 4613 // We want the untagged address first for performance
4834 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(), 4614 __ AllocateHeapNumber(reg, temp1, temp2, scratch, deferred->entry(),
4835 DONT_TAG_RESULT); 4615 DONT_TAG_RESULT);
4836 } else { 4616 } else {
4837 __ jmp(deferred->entry()); 4617 __ jmp(deferred->entry());
4838 } 4618 }
4839 __ bind(deferred->exit()); 4619 __ bind(deferred->exit());
4840 if (CpuFeatures::IsSupported(VFP2)) { 4620 __ vstr(input_reg, reg, HeapNumber::kValueOffset);
4841 CpuFeatures::Scope scope(VFP2);
4842 __ vstr(input_reg, reg, HeapNumber::kValueOffset);
4843 } else {
4844 __ str(sfpd_lo, MemOperand(reg, HeapNumber::kValueOffset));
4845 __ str(sfpd_hi, MemOperand(reg, HeapNumber::kValueOffset + kPointerSize));
4846 }
4847 // Now that we have finished with the object's real address tag it 4621 // Now that we have finished with the object's real address tag it
4848 __ add(reg, reg, Operand(kHeapObjectTag)); 4622 __ add(reg, reg, Operand(kHeapObjectTag));
4849 } 4623 }
4850 4624
4851 4625
4852 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 4626 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
4853 // TODO(3095996): Get rid of this. For now, we need to make the 4627 // TODO(3095996): Get rid of this. For now, we need to make the
4854 // result register contain a valid pointer because it is already 4628 // result register contain a valid pointer because it is already
4855 // contained in the register pointer map. 4629 // contained in the register pointer map.
4856 Register reg = ToRegister(instr->result()); 4630 Register reg = ToRegister(instr->result());
(...skipping 20 matching lines...) Expand all
4877 // If the input is a HeapObject, SmiUntag will set the carry flag. 4651 // If the input is a HeapObject, SmiUntag will set the carry flag.
4878 __ SmiUntag(result, input, SetCC); 4652 __ SmiUntag(result, input, SetCC);
4879 DeoptimizeIf(cs, instr->environment()); 4653 DeoptimizeIf(cs, instr->environment());
4880 } else { 4654 } else {
4881 __ SmiUntag(result, input); 4655 __ SmiUntag(result, input);
4882 } 4656 }
4883 } 4657 }
4884 4658
4885 4659
4886 void LCodeGen::EmitNumberUntagD(Register input_reg, 4660 void LCodeGen::EmitNumberUntagD(Register input_reg,
4887 DwVfpRegister result_reg, 4661 DoubleRegister result_reg,
4888 bool deoptimize_on_undefined, 4662 bool deoptimize_on_undefined,
4889 bool deoptimize_on_minus_zero, 4663 bool deoptimize_on_minus_zero,
4890 LEnvironment* env) { 4664 LEnvironment* env) {
4891 Register scratch = scratch0(); 4665 Register scratch = scratch0();
4892 SwVfpRegister flt_scratch = double_scratch0().low(); 4666 SwVfpRegister flt_scratch = double_scratch0().low();
4893 ASSERT(!result_reg.is(double_scratch0())); 4667 ASSERT(!result_reg.is(double_scratch0()));
4894 CpuFeatures::Scope scope(VFP2);
4895 4668
4896 Label load_smi, heap_number, done; 4669 Label load_smi, heap_number, done;
4897 4670
4898 // Smi check. 4671 // Smi check.
4899 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi); 4672 __ UntagAndJumpIfSmi(scratch, input_reg, &load_smi);
4900 4673
4901 // Heap number map check. 4674 // Heap number map check.
4902 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4675 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
4903 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 4676 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
4904 __ cmp(scratch, Operand(ip)); 4677 __ cmp(scratch, Operand(ip));
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
4959 // SmiUntag(heap_object, SetCC) 4732 // SmiUntag(heap_object, SetCC)
4960 STATIC_ASSERT(kHeapObjectTag == 1); 4733 STATIC_ASSERT(kHeapObjectTag == 1);
4961 __ adc(input_reg, input_reg, Operand(input_reg)); 4734 __ adc(input_reg, input_reg, Operand(input_reg));
4962 4735
4963 // Heap number map check. 4736 // Heap number map check.
4964 __ ldr(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 4737 __ ldr(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset));
4965 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 4738 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
4966 __ cmp(scratch1, Operand(ip)); 4739 __ cmp(scratch1, Operand(ip));
4967 4740
4968 if (instr->truncating()) { 4741 if (instr->truncating()) {
4969 CpuFeatures::Scope scope(VFP2);
4970 Register scratch3 = ToRegister(instr->temp2()); 4742 Register scratch3 = ToRegister(instr->temp2());
4971 ASSERT(!scratch3.is(input_reg) && 4743 ASSERT(!scratch3.is(input_reg) &&
4972 !scratch3.is(scratch1) && 4744 !scratch3.is(scratch1) &&
4973 !scratch3.is(scratch2)); 4745 !scratch3.is(scratch2));
4974 // Performs a truncating conversion of a floating point number as used by 4746 // Performs a truncating conversion of a floating point number as used by
4975 // the JS bitwise operations. 4747 // the JS bitwise operations.
4976 Label heap_number; 4748 Label heap_number;
4977 __ b(eq, &heap_number); 4749 __ b(eq, &heap_number);
4978 // Check for undefined. Undefined is converted to zero for truncating 4750 // Check for undefined. Undefined is converted to zero for truncating
4979 // conversions. 4751 // conversions.
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
5050 } 4822 }
5051 4823
5052 4824
5053 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { 4825 void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
5054 LOperand* input = instr->value(); 4826 LOperand* input = instr->value();
5055 ASSERT(input->IsRegister()); 4827 ASSERT(input->IsRegister());
5056 LOperand* result = instr->result(); 4828 LOperand* result = instr->result();
5057 ASSERT(result->IsDoubleRegister()); 4829 ASSERT(result->IsDoubleRegister());
5058 4830
5059 Register input_reg = ToRegister(input); 4831 Register input_reg = ToRegister(input);
5060 DwVfpRegister result_reg = ToDoubleRegister(result); 4832 DoubleRegister result_reg = ToDoubleRegister(result);
5061 4833
5062 EmitNumberUntagD(input_reg, result_reg, 4834 EmitNumberUntagD(input_reg, result_reg,
5063 instr->hydrogen()->deoptimize_on_undefined(), 4835 instr->hydrogen()->deoptimize_on_undefined(),
5064 instr->hydrogen()->deoptimize_on_minus_zero(), 4836 instr->hydrogen()->deoptimize_on_minus_zero(),
5065 instr->environment()); 4837 instr->environment());
5066 } 4838 }
5067 4839
5068 4840
5069 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 4841 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
5070 Register result_reg = ToRegister(instr->result()); 4842 Register result_reg = ToRegister(instr->result());
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
5198 __ CompareMap(reg, scratch, map, &success, REQUIRE_EXACT_MAP); 4970 __ CompareMap(reg, scratch, map, &success, REQUIRE_EXACT_MAP);
5199 __ b(eq, &success); 4971 __ b(eq, &success);
5200 } 4972 }
5201 Handle<Map> map = map_set->last(); 4973 Handle<Map> map = map_set->last();
5202 DoCheckMapCommon(reg, scratch, map, REQUIRE_EXACT_MAP, instr->environment()); 4974 DoCheckMapCommon(reg, scratch, map, REQUIRE_EXACT_MAP, instr->environment());
5203 __ bind(&success); 4975 __ bind(&success);
5204 } 4976 }
5205 4977
5206 4978
5207 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { 4979 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) {
5208 CpuFeatures::Scope vfp_scope(VFP2); 4980 DoubleRegister value_reg = ToDoubleRegister(instr->unclamped());
5209 DwVfpRegister value_reg = ToDoubleRegister(instr->unclamped());
5210 Register result_reg = ToRegister(instr->result()); 4981 Register result_reg = ToRegister(instr->result());
5211 DwVfpRegister temp_reg = ToDoubleRegister(instr->temp()); 4982 DoubleRegister temp_reg = ToDoubleRegister(instr->temp());
5212 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg); 4983 __ ClampDoubleToUint8(result_reg, value_reg, temp_reg);
5213 } 4984 }
5214 4985
5215 4986
5216 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { 4987 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) {
5217 CpuFeatures::Scope scope(VFP2);
5218 Register unclamped_reg = ToRegister(instr->unclamped()); 4988 Register unclamped_reg = ToRegister(instr->unclamped());
5219 Register result_reg = ToRegister(instr->result()); 4989 Register result_reg = ToRegister(instr->result());
5220 __ ClampUint8(result_reg, unclamped_reg); 4990 __ ClampUint8(result_reg, unclamped_reg);
5221 } 4991 }
5222 4992
5223 4993
5224 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { 4994 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) {
5225 CpuFeatures::Scope scope(VFP2);
5226 Register scratch = scratch0(); 4995 Register scratch = scratch0();
5227 Register input_reg = ToRegister(instr->unclamped()); 4996 Register input_reg = ToRegister(instr->unclamped());
5228 Register result_reg = ToRegister(instr->result()); 4997 Register result_reg = ToRegister(instr->result());
5229 DwVfpRegister temp_reg = ToDoubleRegister(instr->temp()); 4998 DoubleRegister temp_reg = ToDoubleRegister(instr->temp());
5230 Label is_smi, done, heap_number; 4999 Label is_smi, done, heap_number;
5231 5000
5232 // Both smi and heap number cases are handled. 5001 // Both smi and heap number cases are handled.
5233 __ UntagAndJumpIfSmi(result_reg, input_reg, &is_smi); 5002 __ UntagAndJumpIfSmi(result_reg, input_reg, &is_smi);
5234 5003
5235 // Check for heap number 5004 // Check for heap number
5236 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset)); 5005 __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
5237 __ cmp(scratch, Operand(factory()->heap_number_map())); 5006 __ cmp(scratch, Operand(factory()->heap_number_map()));
5238 __ b(eq, &heap_number); 5007 __ b(eq, &heap_number);
5239 5008
(...skipping 556 matching lines...) Expand 10 before | Expand all | Expand 10 after
5796 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset)); 5565 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kCallerFPOffset));
5797 5566
5798 // Check the marker in the calling frame. 5567 // Check the marker in the calling frame.
5799 __ bind(&check_frame_marker); 5568 __ bind(&check_frame_marker);
5800 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset)); 5569 __ ldr(temp1, MemOperand(temp1, StandardFrameConstants::kMarkerOffset));
5801 __ cmp(temp1, Operand(Smi::FromInt(StackFrame::CONSTRUCT))); 5570 __ cmp(temp1, Operand(Smi::FromInt(StackFrame::CONSTRUCT)));
5802 } 5571 }
5803 5572
5804 5573
5805 void LCodeGen::EnsureSpaceForLazyDeopt() { 5574 void LCodeGen::EnsureSpaceForLazyDeopt() {
5806 if (info()->IsStub()) return;
5807 // Ensure that we have enough space after the previous lazy-bailout 5575 // Ensure that we have enough space after the previous lazy-bailout
5808 // instruction for patching the code here. 5576 // instruction for patching the code here.
5809 int current_pc = masm()->pc_offset(); 5577 int current_pc = masm()->pc_offset();
5810 int patch_size = Deoptimizer::patch_size(); 5578 int patch_size = Deoptimizer::patch_size();
5811 if (current_pc < last_lazy_deopt_pc_ + patch_size) { 5579 if (current_pc < last_lazy_deopt_pc_ + patch_size) {
5812 // Block literal pool emission for duration of padding. 5580 // Block literal pool emission for duration of padding.
5813 Assembler::BlockConstPoolScope block_const_pool(masm()); 5581 Assembler::BlockConstPoolScope block_const_pool(masm());
5814 int padding_size = last_lazy_deopt_pc_ + patch_size - current_pc; 5582 int padding_size = last_lazy_deopt_pc_ + patch_size - current_pc;
5815 ASSERT_EQ(0, padding_size % Assembler::kInstrSize); 5583 ASSERT_EQ(0, padding_size % Assembler::kInstrSize);
5816 while (padding_size > 0) { 5584 while (padding_size > 0) {
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
6028 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); 5796 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize));
6029 __ ldr(result, FieldMemOperand(scratch, 5797 __ ldr(result, FieldMemOperand(scratch,
6030 FixedArray::kHeaderSize - kPointerSize)); 5798 FixedArray::kHeaderSize - kPointerSize));
6031 __ bind(&done); 5799 __ bind(&done);
6032 } 5800 }
6033 5801
6034 5802
6035 #undef __ 5803 #undef __
6036 5804
6037 } } // namespace v8::internal 5805 } } // 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