Index: src/mips/macro-assembler-mips.cc |
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc |
index bc5bc01d90c78f99b99a6d375ddd168514bc19d5..3b53954374bbe66d9d262af4491971b453e0cdec 100644 |
--- a/src/mips/macro-assembler-mips.cc |
+++ b/src/mips/macro-assembler-mips.cc |
@@ -4666,9 +4666,7 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg, |
int elements_offset) { |
DCHECK(!AreAliased(value_reg, key_reg, elements_reg, scratch1, scratch2, |
scratch3)); |
- Label smi_value, maybe_nan, have_double_value, is_nan, done; |
- Register mantissa_reg = scratch2; |
- Register exponent_reg = scratch3; |
+ Label smi_value, done; |
// Handle smi values specially. |
JumpIfSmi(value_reg, &smi_value); |
@@ -4680,50 +4678,27 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg, |
fail, |
DONT_DO_SMI_CHECK); |
- // Check for nan: all NaN values have a value greater (signed) than 0x7ff00000 |
- // in the exponent. |
- li(scratch1, Operand(kHoleNanUpper32 & HeapNumber::kExponentMask)); |
- lw(exponent_reg, FieldMemOperand(value_reg, HeapNumber::kExponentOffset)); |
- Branch(&maybe_nan, ge, exponent_reg, Operand(scratch1)); |
- |
- lw(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset)); |
- |
- bind(&have_double_value); |
- Lsa(scratch1, elements_reg, key_reg, kDoubleSizeLog2 - kSmiTagSize); |
- sw(mantissa_reg, |
- FieldMemOperand(scratch1, FixedDoubleArray::kHeaderSize - elements_offset |
- + kHoleNanLower32Offset)); |
- sw(exponent_reg, |
- FieldMemOperand(scratch1, FixedDoubleArray::kHeaderSize - elements_offset |
- + kHoleNanUpper32Offset)); |
- jmp(&done); |
- |
- bind(&maybe_nan); |
- // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise |
- // it's an Infinity, and the non-NaN code path applies. |
- Branch(&is_nan, gt, exponent_reg, Operand(scratch1)); |
- lw(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset)); |
- Branch(&have_double_value, eq, mantissa_reg, Operand(zero_reg)); |
- bind(&is_nan); |
- // Load canonical NaN for storing into the double array. |
- LoadRoot(at, Heap::kNanValueRootIndex); |
- lw(mantissa_reg, FieldMemOperand(at, HeapNumber::kMantissaOffset)); |
- lw(exponent_reg, FieldMemOperand(at, HeapNumber::kExponentOffset)); |
- jmp(&have_double_value); |
+ // Double value, turn potential sNaN into qNan. |
+ DoubleRegister double_result = f0; |
+ DoubleRegister double_scratch = f2; |
+ |
+ ldc1(double_result, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); |
+ Branch(USE_DELAY_SLOT, &done); // Canonicalization is one instruction. |
+ FPUCanonicalizeNaN(double_result, double_result); |
bind(&smi_value); |
+ Register untagged_value = scratch2; |
+ SmiUntag(untagged_value, value_reg); |
+ mtc1(untagged_value, double_scratch); |
+ cvt_d_w(double_result, double_scratch); |
+ |
+ bind(&done); |
Addu(scratch1, elements_reg, |
Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag - |
elements_offset)); |
Lsa(scratch1, scratch1, key_reg, kDoubleSizeLog2 - kSmiTagSize); |
// scratch1 is now effective address of the double element |
- |
- Register untagged_value = scratch2; |
- SmiUntag(untagged_value, value_reg); |
- mtc1(untagged_value, f2); |
- cvt_d_w(f0, f2); |
- sdc1(f0, MemOperand(scratch1, 0)); |
- bind(&done); |
+ sdc1(double_result, MemOperand(scratch1, 0)); |
} |
void MacroAssembler::SubNanPreservePayloadAndSign_s(FloatRegister fd, |
@@ -4857,6 +4832,10 @@ void MacroAssembler::CheckMap(Register obj, |
Branch(fail, ne, scratch, Operand(at)); |
} |
+void MacroAssembler::FPUCanonicalizeNaN(const DoubleRegister dst, |
+ const DoubleRegister src) { |
+ sub_d(dst, src, kDoubleRegZero); |
+} |
void MacroAssembler::GetWeakValue(Register value, Handle<WeakCell> cell) { |
li(value, Operand(cell)); |