| 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 |