| Index: src/x87/lithium-codegen-x87.cc
|
| diff --git a/src/x87/lithium-codegen-x87.cc b/src/x87/lithium-codegen-x87.cc
|
| index d30a90891af344ddb57ed9c3e4631bac6d728aab..4409b1eccd31585d043a2fcd0a114f372063c575 100644
|
| --- a/src/x87/lithium-codegen-x87.cc
|
| +++ b/src/x87/lithium-codegen-x87.cc
|
| @@ -2001,10 +2001,9 @@ void LCodeGen::DoConstantS(LConstantS* instr) {
|
|
|
|
|
| void LCodeGen::DoConstantD(LConstantD* instr) {
|
| - double v = instr->value();
|
| - uint64_t int_val = bit_cast<uint64_t, double>(v);
|
| - int32_t lower = static_cast<int32_t>(int_val);
|
| - int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt));
|
| + uint64_t const bits = instr->bits();
|
| + uint32_t const lower = static_cast<uint32_t>(bits);
|
| + uint32_t const upper = static_cast<uint32_t>(bits >> 32);
|
| DCHECK(instr->result()->IsDoubleRegister());
|
|
|
| __ push(Immediate(upper));
|
| @@ -2613,7 +2612,9 @@ void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
|
|
|
| __ add(esp, Immediate(kDoubleSize));
|
| int offset = sizeof(kHoleNanUpper32);
|
| - __ cmp(MemOperand(esp, -offset), Immediate(kHoleNanUpper32));
|
| + // x87 converts sNaN(0xfff7fffffff7ffff) to QNaN(0xfffffffffff7ffff),
|
| + // so we check the upper with 0xffffffff for hole as a temporary fix.
|
| + __ cmp(MemOperand(esp, -offset), Immediate(0xffffffff));
|
| EmitBranch(instr, equal);
|
| }
|
|
|
| @@ -4242,10 +4243,11 @@ void LCodeGen::DoMathLog(LMathLog* instr) {
|
| __ jmp(&done, Label::kNear);
|
|
|
| __ bind(&nan_result);
|
| - ExternalReference nan =
|
| - ExternalReference::address_of_canonical_non_hole_nan();
|
| X87PrepareToWrite(input_reg);
|
| - __ fld_d(Operand::StaticVariable(nan));
|
| + __ push(Immediate(0xffffffff));
|
| + __ push(Immediate(0x7fffffff));
|
| + __ fld_d(MemOperand(esp, 0));
|
| + __ lea(esp, Operand(esp, kDoubleSize));
|
| X87CommitWrite(input_reg);
|
| __ jmp(&done, Label::kNear);
|
|
|
| @@ -4640,8 +4642,6 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
|
|
|
|
|
| void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
|
| - ExternalReference canonical_nan_reference =
|
| - ExternalReference::address_of_canonical_non_hole_nan();
|
| Operand double_store_operand = BuildFastArrayOperand(
|
| instr->elements(),
|
| instr->key(),
|
| @@ -4649,25 +4649,21 @@ void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
|
| FAST_DOUBLE_ELEMENTS,
|
| instr->base_offset());
|
|
|
| - // Can't use SSE2 in the serializer
|
| + uint64_t int_val = kHoleNanInt64;
|
| + int32_t lower = static_cast<int32_t>(int_val);
|
| + int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt));
|
| + Operand double_store_operand2 = BuildFastArrayOperand(
|
| + instr->elements(), instr->key(),
|
| + instr->hydrogen()->key()->representation(), FAST_DOUBLE_ELEMENTS,
|
| + instr->base_offset() + kPointerSize);
|
| +
|
| if (instr->hydrogen()->IsConstantHoleStore()) {
|
| // This means we should store the (double) hole. No floating point
|
| // registers required.
|
| - double nan_double = FixedDoubleArray::hole_nan_as_double();
|
| - uint64_t int_val = bit_cast<uint64_t, double>(nan_double);
|
| - int32_t lower = static_cast<int32_t>(int_val);
|
| - int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt));
|
| -
|
| __ mov(double_store_operand, Immediate(lower));
|
| - Operand double_store_operand2 = BuildFastArrayOperand(
|
| - instr->elements(),
|
| - instr->key(),
|
| - instr->hydrogen()->key()->representation(),
|
| - FAST_DOUBLE_ELEMENTS,
|
| - instr->base_offset() + kPointerSize);
|
| __ mov(double_store_operand2, Immediate(upper));
|
| } else {
|
| - Label no_special_nan_handling;
|
| + Label no_special_nan_handling, done;
|
| X87Register value = ToX87Register(instr->value());
|
| X87Fxch(value);
|
|
|
| @@ -4675,23 +4671,27 @@ void LCodeGen::DoStoreKeyedFixedDoubleArray(LStoreKeyed* instr) {
|
| __ fld(0);
|
| __ fld(0);
|
| __ FCmp();
|
| -
|
| __ j(parity_odd, &no_special_nan_handling, Label::kNear);
|
| - __ sub(esp, Immediate(kDoubleSize));
|
| + // All NaNs are Canonicalized to 0x7fffffffffffffff
|
| + __ mov(double_store_operand, Immediate(0xffffffff));
|
| + __ mov(double_store_operand2, Immediate(0x7fffffff));
|
| + __ jmp(&done, Label::kNear);
|
| + } else {
|
| + __ lea(esp, Operand(esp, -kDoubleSize));
|
| __ fst_d(MemOperand(esp, 0));
|
| - __ cmp(MemOperand(esp, sizeof(kHoleNanLower32)),
|
| - Immediate(kHoleNanUpper32));
|
| - __ add(esp, Immediate(kDoubleSize));
|
| - Label canonicalize;
|
| - __ j(not_equal, &canonicalize, Label::kNear);
|
| - __ jmp(&no_special_nan_handling, Label::kNear);
|
| - __ bind(&canonicalize);
|
| - __ fstp(0);
|
| - __ fld_d(Operand::StaticVariable(canonical_nan_reference));
|
| + __ lea(esp, Operand(esp, kDoubleSize));
|
| + int offset = sizeof(kHoleNanUpper32);
|
| + // x87 converts sNaN(0xfff7fffffff7ffff) to QNaN(0xfffffffffff7ffff),
|
| + // so we check the upper with 0xffffffff for hole as a temporary fix.
|
| + __ cmp(MemOperand(esp, -offset), Immediate(0xffffffff));
|
| + __ j(not_equal, &no_special_nan_handling, Label::kNear);
|
| + __ mov(double_store_operand, Immediate(lower));
|
| + __ mov(double_store_operand2, Immediate(upper));
|
| + __ jmp(&done, Label::kNear);
|
| }
|
| -
|
| __ bind(&no_special_nan_handling);
|
| __ fst_d(double_store_operand);
|
| + __ bind(&done);
|
| }
|
| }
|
|
|
| @@ -5189,9 +5189,10 @@ void LCodeGen::EmitNumberUntagDNoSSE2(LNumberUntagD* instr, Register input_reg,
|
| DeoptimizeIf(not_equal, instr, "not a heap number/undefined");
|
|
|
| __ bind(&convert);
|
| - ExternalReference nan =
|
| - ExternalReference::address_of_canonical_non_hole_nan();
|
| - __ fld_d(Operand::StaticVariable(nan));
|
| + __ push(Immediate(0xffffffff));
|
| + __ push(Immediate(0x7fffffff));
|
| + __ fld_d(MemOperand(esp, 0));
|
| + __ lea(esp, Operand(esp, kDoubleSize));
|
| __ jmp(&done, Label::kNear);
|
|
|
| __ bind(&heap_number);
|
|
|