OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
8 | 8 |
9 #include "ia32/lithium-codegen-ia32.h" | 9 #include "ia32/lithium-codegen-ia32.h" |
10 #include "ic.h" | 10 #include "ic.h" |
11 #include "code-stubs.h" | 11 #include "code-stubs.h" |
12 #include "deoptimizer.h" | 12 #include "deoptimizer.h" |
13 #include "stub-cache.h" | 13 #include "stub-cache.h" |
14 #include "codegen.h" | 14 #include "codegen.h" |
15 #include "hydrogen-osr.h" | 15 #include "hydrogen-osr.h" |
16 | 16 |
17 namespace v8 { | 17 namespace v8 { |
18 namespace internal { | 18 namespace internal { |
19 | 19 |
20 | 20 |
21 static SaveFPRegsMode GetSaveFPRegsMode() { | 21 static SaveFPRegsMode GetSaveFPRegsMode(Isolate* isolate) { |
22 // We don't need to save floating point regs when generating the snapshot | 22 // We don't need to save floating point regs when generating the snapshot |
23 return CpuFeatures::IsSafeForSnapshot(SSE2) ? kSaveFPRegs : kDontSaveFPRegs; | 23 return CpuFeatures::IsSafeForSnapshot(isolate, SSE2) ? kSaveFPRegs |
| 24 : kDontSaveFPRegs; |
24 } | 25 } |
25 | 26 |
26 | 27 |
27 // When invoking builtins, we need to record the safepoint in the middle of | 28 // When invoking builtins, we need to record the safepoint in the middle of |
28 // the invoke instruction sequence generated by the macro assembler. | 29 // the invoke instruction sequence generated by the macro assembler. |
29 class SafepointGenerator V8_FINAL : public CallWrapper { | 30 class SafepointGenerator V8_FINAL : public CallWrapper { |
30 public: | 31 public: |
31 SafepointGenerator(LCodeGen* codegen, | 32 SafepointGenerator(LCodeGen* codegen, |
32 LPointerMap* pointers, | 33 LPointerMap* pointers, |
33 Safepoint::DeoptMode mode) | 34 Safepoint::DeoptMode mode) |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 if (!CpuFeatures::IsSupported(SSE2)) FlushX87StackIfNecessary(instr); | 377 if (!CpuFeatures::IsSupported(SSE2)) FlushX87StackIfNecessary(instr); |
377 } | 378 } |
378 | 379 |
379 | 380 |
380 void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) { | 381 void LCodeGen::GenerateBodyInstructionPost(LInstruction* instr) { |
381 if (!CpuFeatures::IsSupported(SSE2)) { | 382 if (!CpuFeatures::IsSupported(SSE2)) { |
382 if (instr->IsGoto()) { | 383 if (instr->IsGoto()) { |
383 x87_stack_.LeavingBlock(current_block_, LGoto::cast(instr)); | 384 x87_stack_.LeavingBlock(current_block_, LGoto::cast(instr)); |
384 } else if (FLAG_debug_code && FLAG_enable_slow_asserts && | 385 } else if (FLAG_debug_code && FLAG_enable_slow_asserts && |
385 !instr->IsGap() && !instr->IsReturn()) { | 386 !instr->IsGap() && !instr->IsReturn()) { |
386 if (instr->ClobbersDoubleRegisters()) { | 387 if (instr->ClobbersDoubleRegisters(isolate())) { |
387 if (instr->HasDoubleRegisterResult()) { | 388 if (instr->HasDoubleRegisterResult()) { |
388 ASSERT_EQ(1, x87_stack_.depth()); | 389 ASSERT_EQ(1, x87_stack_.depth()); |
389 } else { | 390 } else { |
390 ASSERT_EQ(0, x87_stack_.depth()); | 391 ASSERT_EQ(0, x87_stack_.depth()); |
391 } | 392 } |
392 } | 393 } |
393 __ VerifyX87StackDepth(x87_stack_.depth()); | 394 __ VerifyX87StackDepth(x87_stack_.depth()); |
394 } | 395 } |
395 } | 396 } |
396 } | 397 } |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
675 void LCodeGen::X87PrepareBinaryOp( | 676 void LCodeGen::X87PrepareBinaryOp( |
676 X87Register left, X87Register right, X87Register result) { | 677 X87Register left, X87Register right, X87Register result) { |
677 // You need to use DefineSameAsFirst for x87 instructions | 678 // You need to use DefineSameAsFirst for x87 instructions |
678 ASSERT(result.is(left)); | 679 ASSERT(result.is(left)); |
679 x87_stack_.Fxch(right, 1); | 680 x87_stack_.Fxch(right, 1); |
680 x87_stack_.Fxch(left); | 681 x87_stack_.Fxch(left); |
681 } | 682 } |
682 | 683 |
683 | 684 |
684 void LCodeGen::X87Stack::FlushIfNecessary(LInstruction* instr, LCodeGen* cgen) { | 685 void LCodeGen::X87Stack::FlushIfNecessary(LInstruction* instr, LCodeGen* cgen) { |
685 if (stack_depth_ > 0 && instr->ClobbersDoubleRegisters()) { | 686 if (stack_depth_ > 0 && instr->ClobbersDoubleRegisters(isolate())) { |
686 bool double_inputs = instr->HasDoubleRegisterInput(); | 687 bool double_inputs = instr->HasDoubleRegisterInput(); |
687 | 688 |
688 // Flush stack from tos down, since FreeX87() will mess with tos | 689 // Flush stack from tos down, since FreeX87() will mess with tos |
689 for (int i = stack_depth_-1; i >= 0; i--) { | 690 for (int i = stack_depth_-1; i >= 0; i--) { |
690 X87Register reg = stack_[i]; | 691 X87Register reg = stack_[i]; |
691 // Skip registers which contain the inputs for the next instruction | 692 // Skip registers which contain the inputs for the next instruction |
692 // when flushing the stack | 693 // when flushing the stack |
693 if (double_inputs && instr->IsDoubleInput(reg, cgen)) { | 694 if (double_inputs && instr->IsDoubleInput(reg, cgen)) { |
694 continue; | 695 continue; |
695 } | 696 } |
(...skipping 1266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1962 } | 1963 } |
1963 | 1964 |
1964 | 1965 |
1965 void LCodeGen::DoConstantD(LConstantD* instr) { | 1966 void LCodeGen::DoConstantD(LConstantD* instr) { |
1966 double v = instr->value(); | 1967 double v = instr->value(); |
1967 uint64_t int_val = BitCast<uint64_t, double>(v); | 1968 uint64_t int_val = BitCast<uint64_t, double>(v); |
1968 int32_t lower = static_cast<int32_t>(int_val); | 1969 int32_t lower = static_cast<int32_t>(int_val); |
1969 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); | 1970 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); |
1970 ASSERT(instr->result()->IsDoubleRegister()); | 1971 ASSERT(instr->result()->IsDoubleRegister()); |
1971 | 1972 |
1972 if (!CpuFeatures::IsSafeForSnapshot(SSE2)) { | 1973 if (!CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) { |
1973 __ push(Immediate(upper)); | 1974 __ push(Immediate(upper)); |
1974 __ push(Immediate(lower)); | 1975 __ push(Immediate(lower)); |
1975 X87Register reg = ToX87Register(instr->result()); | 1976 X87Register reg = ToX87Register(instr->result()); |
1976 X87Mov(reg, Operand(esp, 0)); | 1977 X87Mov(reg, Operand(esp, 0)); |
1977 __ add(Operand(esp), Immediate(kDoubleSize)); | 1978 __ add(Operand(esp), Immediate(kDoubleSize)); |
1978 } else { | 1979 } else { |
1979 CpuFeatureScope scope1(masm(), SSE2); | 1980 CpuFeatureScope scope1(masm(), SSE2); |
1980 XMMRegister res = ToDoubleRegister(instr->result()); | 1981 XMMRegister res = ToDoubleRegister(instr->result()); |
1981 if (int_val == 0) { | 1982 if (int_val == 0) { |
1982 __ xorps(res, res); | 1983 __ xorps(res, res); |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2235 __ j(parity_even, &return_left, Label::kNear); // left == NaN. | 2236 __ j(parity_even, &return_left, Label::kNear); // left == NaN. |
2236 __ bind(&return_right); | 2237 __ bind(&return_right); |
2237 __ movaps(left_reg, right_reg); | 2238 __ movaps(left_reg, right_reg); |
2238 | 2239 |
2239 __ bind(&return_left); | 2240 __ bind(&return_left); |
2240 } | 2241 } |
2241 } | 2242 } |
2242 | 2243 |
2243 | 2244 |
2244 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { | 2245 void LCodeGen::DoArithmeticD(LArithmeticD* instr) { |
2245 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { | 2246 if (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) { |
2246 CpuFeatureScope scope(masm(), SSE2); | 2247 CpuFeatureScope scope(masm(), SSE2); |
2247 XMMRegister left = ToDoubleRegister(instr->left()); | 2248 XMMRegister left = ToDoubleRegister(instr->left()); |
2248 XMMRegister right = ToDoubleRegister(instr->right()); | 2249 XMMRegister right = ToDoubleRegister(instr->right()); |
2249 XMMRegister result = ToDoubleRegister(instr->result()); | 2250 XMMRegister result = ToDoubleRegister(instr->result()); |
2250 switch (instr->op()) { | 2251 switch (instr->op()) { |
2251 case Token::ADD: | 2252 case Token::ADD: |
2252 __ addsd(left, right); | 2253 __ addsd(left, right); |
2253 break; | 2254 break; |
2254 case Token::SUB: | 2255 case Token::SUB: |
2255 __ subsd(left, right); | 2256 __ subsd(left, right); |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2480 __ CmpInstanceType(map, SYMBOL_TYPE); | 2481 __ CmpInstanceType(map, SYMBOL_TYPE); |
2481 __ j(equal, instr->TrueLabel(chunk_)); | 2482 __ j(equal, instr->TrueLabel(chunk_)); |
2482 } | 2483 } |
2483 | 2484 |
2484 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { | 2485 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { |
2485 // heap number -> false iff +0, -0, or NaN. | 2486 // heap number -> false iff +0, -0, or NaN. |
2486 Label not_heap_number; | 2487 Label not_heap_number; |
2487 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), | 2488 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), |
2488 factory()->heap_number_map()); | 2489 factory()->heap_number_map()); |
2489 __ j(not_equal, ¬_heap_number, Label::kNear); | 2490 __ j(not_equal, ¬_heap_number, Label::kNear); |
2490 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { | 2491 if (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) { |
2491 CpuFeatureScope scope(masm(), SSE2); | 2492 CpuFeatureScope scope(masm(), SSE2); |
2492 XMMRegister xmm_scratch = double_scratch0(); | 2493 XMMRegister xmm_scratch = double_scratch0(); |
2493 __ xorps(xmm_scratch, xmm_scratch); | 2494 __ xorps(xmm_scratch, xmm_scratch); |
2494 __ ucomisd(xmm_scratch, FieldOperand(reg, HeapNumber::kValueOffset)); | 2495 __ ucomisd(xmm_scratch, FieldOperand(reg, HeapNumber::kValueOffset)); |
2495 } else { | 2496 } else { |
2496 __ fldz(); | 2497 __ fldz(); |
2497 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset)); | 2498 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset)); |
2498 __ FCmp(); | 2499 __ FCmp(); |
2499 } | 2500 } |
2500 __ j(zero, instr->FalseLabel(chunk_)); | 2501 __ j(zero, instr->FalseLabel(chunk_)); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2567 | 2568 |
2568 if (left->IsConstantOperand() && right->IsConstantOperand()) { | 2569 if (left->IsConstantOperand() && right->IsConstantOperand()) { |
2569 // We can statically evaluate the comparison. | 2570 // We can statically evaluate the comparison. |
2570 double left_val = ToDouble(LConstantOperand::cast(left)); | 2571 double left_val = ToDouble(LConstantOperand::cast(left)); |
2571 double right_val = ToDouble(LConstantOperand::cast(right)); | 2572 double right_val = ToDouble(LConstantOperand::cast(right)); |
2572 int next_block = EvalComparison(instr->op(), left_val, right_val) ? | 2573 int next_block = EvalComparison(instr->op(), left_val, right_val) ? |
2573 instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_); | 2574 instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_); |
2574 EmitGoto(next_block); | 2575 EmitGoto(next_block); |
2575 } else { | 2576 } else { |
2576 if (instr->is_double()) { | 2577 if (instr->is_double()) { |
2577 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { | 2578 if (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) { |
2578 CpuFeatureScope scope(masm(), SSE2); | 2579 CpuFeatureScope scope(masm(), SSE2); |
2579 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); | 2580 __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); |
2580 } else { | 2581 } else { |
2581 X87LoadForUsage(ToX87Register(right), ToX87Register(left)); | 2582 X87LoadForUsage(ToX87Register(right), ToX87Register(left)); |
2582 __ FCmp(); | 2583 __ FCmp(); |
2583 } | 2584 } |
2584 // Don't base result on EFLAGS when a NaN is involved. Instead | 2585 // Don't base result on EFLAGS when a NaN is involved. Instead |
2585 // jump to the false block. | 2586 // jump to the false block. |
2586 __ j(parity_even, instr->FalseLabel(chunk_)); | 2587 __ j(parity_even, instr->FalseLabel(chunk_)); |
2587 } else { | 2588 } else { |
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3243 if (instr->hydrogen()->NeedsWriteBarrier()) { | 3244 if (instr->hydrogen()->NeedsWriteBarrier()) { |
3244 SmiCheck check_needed = | 3245 SmiCheck check_needed = |
3245 instr->hydrogen()->value()->IsHeapObject() | 3246 instr->hydrogen()->value()->IsHeapObject() |
3246 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 3247 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
3247 Register temp = ToRegister(instr->temp()); | 3248 Register temp = ToRegister(instr->temp()); |
3248 int offset = Context::SlotOffset(instr->slot_index()); | 3249 int offset = Context::SlotOffset(instr->slot_index()); |
3249 __ RecordWriteContextSlot(context, | 3250 __ RecordWriteContextSlot(context, |
3250 offset, | 3251 offset, |
3251 value, | 3252 value, |
3252 temp, | 3253 temp, |
3253 GetSaveFPRegsMode(), | 3254 GetSaveFPRegsMode(isolate()), |
3254 EMIT_REMEMBERED_SET, | 3255 EMIT_REMEMBERED_SET, |
3255 check_needed); | 3256 check_needed); |
3256 } | 3257 } |
3257 | 3258 |
3258 __ bind(&skip_assignment); | 3259 __ bind(&skip_assignment); |
3259 } | 3260 } |
3260 | 3261 |
3261 | 3262 |
3262 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { | 3263 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { |
3263 HObjectAccess access = instr->hydrogen()->access(); | 3264 HObjectAccess access = instr->hydrogen()->access(); |
(...skipping 1146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4410 } else { | 4411 } else { |
4411 Register temp = ToRegister(instr->temp()); | 4412 Register temp = ToRegister(instr->temp()); |
4412 Register temp_map = ToRegister(instr->temp_map()); | 4413 Register temp_map = ToRegister(instr->temp_map()); |
4413 __ mov(temp_map, transition); | 4414 __ mov(temp_map, transition); |
4414 __ mov(FieldOperand(object, HeapObject::kMapOffset), temp_map); | 4415 __ mov(FieldOperand(object, HeapObject::kMapOffset), temp_map); |
4415 // Update the write barrier for the map field. | 4416 // Update the write barrier for the map field. |
4416 __ RecordWriteField(object, | 4417 __ RecordWriteField(object, |
4417 HeapObject::kMapOffset, | 4418 HeapObject::kMapOffset, |
4418 temp_map, | 4419 temp_map, |
4419 temp, | 4420 temp, |
4420 GetSaveFPRegsMode(), | 4421 GetSaveFPRegsMode(isolate()), |
4421 OMIT_REMEMBERED_SET, | 4422 OMIT_REMEMBERED_SET, |
4422 OMIT_SMI_CHECK); | 4423 OMIT_SMI_CHECK); |
4423 } | 4424 } |
4424 } | 4425 } |
4425 | 4426 |
4426 // Do the store. | 4427 // Do the store. |
4427 Register write_register = object; | 4428 Register write_register = object; |
4428 if (!access.IsInobject()) { | 4429 if (!access.IsInobject()) { |
4429 write_register = ToRegister(instr->temp()); | 4430 write_register = ToRegister(instr->temp()); |
4430 __ mov(write_register, FieldOperand(object, JSObject::kPropertiesOffset)); | 4431 __ mov(write_register, FieldOperand(object, JSObject::kPropertiesOffset)); |
(...skipping 20 matching lines...) Expand all Loading... |
4451 } | 4452 } |
4452 | 4453 |
4453 if (instr->hydrogen()->NeedsWriteBarrier()) { | 4454 if (instr->hydrogen()->NeedsWriteBarrier()) { |
4454 Register value = ToRegister(instr->value()); | 4455 Register value = ToRegister(instr->value()); |
4455 Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object; | 4456 Register temp = access.IsInobject() ? ToRegister(instr->temp()) : object; |
4456 // Update the write barrier for the object for in-object properties. | 4457 // Update the write barrier for the object for in-object properties. |
4457 __ RecordWriteField(write_register, | 4458 __ RecordWriteField(write_register, |
4458 offset, | 4459 offset, |
4459 value, | 4460 value, |
4460 temp, | 4461 temp, |
4461 GetSaveFPRegsMode(), | 4462 GetSaveFPRegsMode(isolate()), |
4462 EMIT_REMEMBERED_SET, | 4463 EMIT_REMEMBERED_SET, |
4463 check_needed); | 4464 check_needed); |
4464 } | 4465 } |
4465 } | 4466 } |
4466 | 4467 |
4467 | 4468 |
4468 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { | 4469 void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { |
4469 ASSERT(ToRegister(instr->context()).is(esi)); | 4470 ASSERT(ToRegister(instr->context()).is(esi)); |
4470 ASSERT(ToRegister(instr->object()).is(edx)); | 4471 ASSERT(ToRegister(instr->object()).is(edx)); |
4471 ASSERT(ToRegister(instr->value()).is(eax)); | 4472 ASSERT(ToRegister(instr->value()).is(eax)); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4511 } | 4512 } |
4512 Operand operand(BuildFastArrayOperand( | 4513 Operand operand(BuildFastArrayOperand( |
4513 instr->elements(), | 4514 instr->elements(), |
4514 key, | 4515 key, |
4515 instr->hydrogen()->key()->representation(), | 4516 instr->hydrogen()->key()->representation(), |
4516 elements_kind, | 4517 elements_kind, |
4517 0, | 4518 0, |
4518 instr->additional_index())); | 4519 instr->additional_index())); |
4519 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || | 4520 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || |
4520 elements_kind == FLOAT32_ELEMENTS) { | 4521 elements_kind == FLOAT32_ELEMENTS) { |
4521 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { | 4522 if (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) { |
4522 CpuFeatureScope scope(masm(), SSE2); | 4523 CpuFeatureScope scope(masm(), SSE2); |
4523 XMMRegister xmm_scratch = double_scratch0(); | 4524 XMMRegister xmm_scratch = double_scratch0(); |
4524 __ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value())); | 4525 __ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value())); |
4525 __ movss(operand, xmm_scratch); | 4526 __ movss(operand, xmm_scratch); |
4526 } else { | 4527 } else { |
4527 __ fld(0); | 4528 __ fld(0); |
4528 __ fstp_s(operand); | 4529 __ fstp_s(operand); |
4529 } | 4530 } |
4530 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || | 4531 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || |
4531 elements_kind == FLOAT64_ELEMENTS) { | 4532 elements_kind == FLOAT64_ELEMENTS) { |
4532 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { | 4533 if (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) { |
4533 CpuFeatureScope scope(masm(), SSE2); | 4534 CpuFeatureScope scope(masm(), SSE2); |
4534 __ movsd(operand, ToDoubleRegister(instr->value())); | 4535 __ movsd(operand, ToDoubleRegister(instr->value())); |
4535 } else { | 4536 } else { |
4536 X87Mov(operand, ToX87Register(instr->value())); | 4537 X87Mov(operand, ToX87Register(instr->value())); |
4537 } | 4538 } |
4538 } else { | 4539 } else { |
4539 Register value = ToRegister(instr->value()); | 4540 Register value = ToRegister(instr->value()); |
4540 switch (elements_kind) { | 4541 switch (elements_kind) { |
4541 case EXTERNAL_UINT8_CLAMPED_ELEMENTS: | 4542 case EXTERNAL_UINT8_CLAMPED_ELEMENTS: |
4542 case EXTERNAL_UINT8_ELEMENTS: | 4543 case EXTERNAL_UINT8_ELEMENTS: |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4581 ExternalReference canonical_nan_reference = | 4582 ExternalReference canonical_nan_reference = |
4582 ExternalReference::address_of_canonical_non_hole_nan(); | 4583 ExternalReference::address_of_canonical_non_hole_nan(); |
4583 Operand double_store_operand = BuildFastArrayOperand( | 4584 Operand double_store_operand = BuildFastArrayOperand( |
4584 instr->elements(), | 4585 instr->elements(), |
4585 instr->key(), | 4586 instr->key(), |
4586 instr->hydrogen()->key()->representation(), | 4587 instr->hydrogen()->key()->representation(), |
4587 FAST_DOUBLE_ELEMENTS, | 4588 FAST_DOUBLE_ELEMENTS, |
4588 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 4589 FixedDoubleArray::kHeaderSize - kHeapObjectTag, |
4589 instr->additional_index()); | 4590 instr->additional_index()); |
4590 | 4591 |
4591 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { | 4592 if (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) { |
4592 CpuFeatureScope scope(masm(), SSE2); | 4593 CpuFeatureScope scope(masm(), SSE2); |
4593 XMMRegister value = ToDoubleRegister(instr->value()); | 4594 XMMRegister value = ToDoubleRegister(instr->value()); |
4594 | 4595 |
4595 if (instr->NeedsCanonicalization()) { | 4596 if (instr->NeedsCanonicalization()) { |
4596 Label have_value; | 4597 Label have_value; |
4597 | 4598 |
4598 __ ucomisd(value, value); | 4599 __ ucomisd(value, value); |
4599 __ j(parity_odd, &have_value, Label::kNear); // NaN. | 4600 __ j(parity_odd, &have_value, Label::kNear); // NaN. |
4600 | 4601 |
4601 __ movsd(value, Operand::StaticVariable(canonical_nan_reference)); | 4602 __ movsd(value, Operand::StaticVariable(canonical_nan_reference)); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4683 Register value = ToRegister(instr->value()); | 4684 Register value = ToRegister(instr->value()); |
4684 ASSERT(!instr->key()->IsConstantOperand()); | 4685 ASSERT(!instr->key()->IsConstantOperand()); |
4685 SmiCheck check_needed = | 4686 SmiCheck check_needed = |
4686 instr->hydrogen()->value()->IsHeapObject() | 4687 instr->hydrogen()->value()->IsHeapObject() |
4687 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; | 4688 ? OMIT_SMI_CHECK : INLINE_SMI_CHECK; |
4688 // Compute address of modified element and store it into key register. | 4689 // Compute address of modified element and store it into key register. |
4689 __ lea(key, operand); | 4690 __ lea(key, operand); |
4690 __ RecordWrite(elements, | 4691 __ RecordWrite(elements, |
4691 key, | 4692 key, |
4692 value, | 4693 value, |
4693 GetSaveFPRegsMode(), | 4694 GetSaveFPRegsMode(isolate()), |
4694 EMIT_REMEMBERED_SET, | 4695 EMIT_REMEMBERED_SET, |
4695 check_needed); | 4696 check_needed); |
4696 } | 4697 } |
4697 } | 4698 } |
4698 | 4699 |
4699 | 4700 |
4700 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { | 4701 void LCodeGen::DoStoreKeyed(LStoreKeyed* instr) { |
4701 // By cases...external, fast-double, fast | 4702 // By cases...external, fast-double, fast |
4702 if (instr->is_typed_elements()) { | 4703 if (instr->is_typed_elements()) { |
4703 DoStoreKeyedExternalArray(instr); | 4704 DoStoreKeyedExternalArray(instr); |
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5420 | 5421 |
5421 | 5422 |
5422 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { | 5423 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { |
5423 LOperand* input = instr->value(); | 5424 LOperand* input = instr->value(); |
5424 ASSERT(input->IsDoubleRegister()); | 5425 ASSERT(input->IsDoubleRegister()); |
5425 LOperand* result = instr->result(); | 5426 LOperand* result = instr->result(); |
5426 ASSERT(result->IsRegister()); | 5427 ASSERT(result->IsRegister()); |
5427 Register result_reg = ToRegister(result); | 5428 Register result_reg = ToRegister(result); |
5428 | 5429 |
5429 if (instr->truncating()) { | 5430 if (instr->truncating()) { |
5430 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { | 5431 if (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) { |
5431 CpuFeatureScope scope(masm(), SSE2); | 5432 CpuFeatureScope scope(masm(), SSE2); |
5432 XMMRegister input_reg = ToDoubleRegister(input); | 5433 XMMRegister input_reg = ToDoubleRegister(input); |
5433 __ TruncateDoubleToI(result_reg, input_reg); | 5434 __ TruncateDoubleToI(result_reg, input_reg); |
5434 } else { | 5435 } else { |
5435 X87Register input_reg = ToX87Register(input); | 5436 X87Register input_reg = ToX87Register(input); |
5436 X87Fxch(input_reg); | 5437 X87Fxch(input_reg); |
5437 __ TruncateX87TOSToI(result_reg); | 5438 __ TruncateX87TOSToI(result_reg); |
5438 } | 5439 } |
5439 } else { | 5440 } else { |
5440 Label bailout, done; | 5441 Label bailout, done; |
5441 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { | 5442 if (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) { |
5442 CpuFeatureScope scope(masm(), SSE2); | 5443 CpuFeatureScope scope(masm(), SSE2); |
5443 XMMRegister input_reg = ToDoubleRegister(input); | 5444 XMMRegister input_reg = ToDoubleRegister(input); |
5444 XMMRegister xmm_scratch = double_scratch0(); | 5445 XMMRegister xmm_scratch = double_scratch0(); |
5445 __ DoubleToI(result_reg, input_reg, xmm_scratch, | 5446 __ DoubleToI(result_reg, input_reg, xmm_scratch, |
5446 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear); | 5447 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear); |
5447 } else { | 5448 } else { |
5448 X87Register input_reg = ToX87Register(input); | 5449 X87Register input_reg = ToX87Register(input); |
5449 X87Fxch(input_reg); | 5450 X87Fxch(input_reg); |
5450 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(), | 5451 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(), |
5451 &bailout, Label::kNear); | 5452 &bailout, Label::kNear); |
5452 } | 5453 } |
5453 __ jmp(&done, Label::kNear); | 5454 __ jmp(&done, Label::kNear); |
5454 __ bind(&bailout); | 5455 __ bind(&bailout); |
5455 DeoptimizeIf(no_condition, instr->environment()); | 5456 DeoptimizeIf(no_condition, instr->environment()); |
5456 __ bind(&done); | 5457 __ bind(&done); |
5457 } | 5458 } |
5458 } | 5459 } |
5459 | 5460 |
5460 | 5461 |
5461 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { | 5462 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { |
5462 LOperand* input = instr->value(); | 5463 LOperand* input = instr->value(); |
5463 ASSERT(input->IsDoubleRegister()); | 5464 ASSERT(input->IsDoubleRegister()); |
5464 LOperand* result = instr->result(); | 5465 LOperand* result = instr->result(); |
5465 ASSERT(result->IsRegister()); | 5466 ASSERT(result->IsRegister()); |
5466 Register result_reg = ToRegister(result); | 5467 Register result_reg = ToRegister(result); |
5467 | 5468 |
5468 Label bailout, done; | 5469 Label bailout, done; |
5469 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { | 5470 if (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2)) { |
5470 CpuFeatureScope scope(masm(), SSE2); | 5471 CpuFeatureScope scope(masm(), SSE2); |
5471 XMMRegister input_reg = ToDoubleRegister(input); | 5472 XMMRegister input_reg = ToDoubleRegister(input); |
5472 XMMRegister xmm_scratch = double_scratch0(); | 5473 XMMRegister xmm_scratch = double_scratch0(); |
5473 __ DoubleToI(result_reg, input_reg, xmm_scratch, | 5474 __ DoubleToI(result_reg, input_reg, xmm_scratch, |
5474 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear); | 5475 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear); |
5475 } else { | 5476 } else { |
5476 X87Register input_reg = ToX87Register(input); | 5477 X87Register input_reg = ToX87Register(input); |
5477 X87Fxch(input_reg); | 5478 X87Fxch(input_reg); |
5478 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(), | 5479 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(), |
5479 &bailout, Label::kNear); | 5480 &bailout, Label::kNear); |
(...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6423 __ bind(deferred->exit()); | 6424 __ bind(deferred->exit()); |
6424 __ bind(&done); | 6425 __ bind(&done); |
6425 } | 6426 } |
6426 | 6427 |
6427 | 6428 |
6428 #undef __ | 6429 #undef __ |
6429 | 6430 |
6430 } } // namespace v8::internal | 6431 } } // namespace v8::internal |
6431 | 6432 |
6432 #endif // V8_TARGET_ARCH_IA32 | 6433 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |