MIPS: Use signaling NaN for holes in fixed double arrays.

Port 9eace97bba
Port 5d641ec969

BUG=

Review URL: https://codereview.chromium.org/867453002

Cr-Commit-Position: refs/heads/master@{#26208}
This commit is contained in:
paul.lind 2015-01-21 22:14:52 -08:00 committed by Commit bot
parent 7619374979
commit 3552f87e8f
7 changed files with 26 additions and 9 deletions

View File

@ -771,15 +771,16 @@ void ElementsTransitionGenerator::GenerateSmiToDouble(
// Repurpose registers no longer in use.
Register hole_lower = elements;
Register hole_upper = length;
__ li(hole_lower, Operand(kHoleNanLower32));
__ li(hole_upper, Operand(kHoleNanUpper32));
// scratch1: begin of source FixedArray element fields, not tagged
// hole_lower: kHoleNanLower32
// hole_upper: kHoleNanUpper32
// array_end: end of destination FixedDoubleArray, not tagged
// scratch3: begin of FixedDoubleArray element fields, not tagged
__ Branch(USE_DELAY_SLOT, &entry);
__ li(hole_upper, Operand(kHoleNanUpper32)); // In delay slot.
__ Branch(&entry);
__ bind(&only_change_map);
__ sw(target_map, FieldMemOperand(receiver, HeapObject::kMapOffset));

View File

@ -1744,6 +1744,20 @@ void LCodeGen::DoConstantS(LConstantS* instr) {
void LCodeGen::DoConstantD(LConstantD* instr) {
DCHECK(instr->result()->IsDoubleRegister());
DoubleRegister result = ToDoubleRegister(instr->result());
#if V8_HOST_ARCH_IA32
// Need some crappy work-around for x87 sNaN -> qNaN breakage in simulator
// builds.
uint64_t bits = instr->bits();
if ((bits & V8_UINT64_C(0x7FF8000000000000)) ==
V8_UINT64_C(0x7FF0000000000000)) {
uint32_t lo = static_cast<uint32_t>(bits);
uint32_t hi = static_cast<uint32_t>(bits >> 32);
__ li(at, Operand(lo));
__ li(scratch0(), Operand(hi));
__ Move(result, at, scratch0());
return;
}
#endif
double v = instr->value();
__ Move(result, v);
}

View File

@ -1323,6 +1323,7 @@ class LConstantD FINAL : public LTemplateInstruction<1, 0, 0> {
DECLARE_HYDROGEN_ACCESSOR(Constant)
double value() const { return hydrogen()->DoubleValue(); }
uint64_t bits() const { return hydrogen()->DoubleValueAsBits(); }
};

View File

@ -3917,7 +3917,7 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
// Check for nan: all NaN values have a value greater (signed) than 0x7ff00000
// in the exponent.
li(scratch1, Operand(kNaNOrInfinityLowerBoundUpper32));
li(scratch1, Operand(kHoleNanUpper32 & HeapNumber::kExponentMask));
lw(exponent_reg, FieldMemOperand(value_reg, HeapNumber::kExponentOffset));
Branch(&maybe_nan, ge, exponent_reg, Operand(scratch1));

View File

@ -665,13 +665,15 @@ void ElementsTransitionGenerator::GenerateSmiToDouble(
Register hole_lower = elements;
Register hole_upper = length;
__ li(hole_lower, Operand(kHoleNanLower32));
__ li(hole_upper, Operand(kHoleNanUpper32));
// scratch1: begin of source FixedArray element fields, not tagged
// hole_lower: kHoleNanLower32
// hole_upper: kHoleNanUpper32
// array_end: end of destination FixedDoubleArray, not tagged
// scratch3: begin of FixedDoubleArray element fields, not tagged
__ Branch(USE_DELAY_SLOT, &entry);
__ li(hole_upper, Operand(kHoleNanUpper32)); // In delay slot.
__ Branch(&entry);
__ bind(&only_change_map);
__ sd(target_map, FieldMemOperand(receiver, HeapObject::kMapOffset));

View File

@ -3884,7 +3884,7 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
// Check for nan: all NaN values have a value greater (signed) than 0x7ff00000
// in the exponent.
li(scratch1, Operand(kNaNOrInfinityLowerBoundUpper32));
li(scratch1, Operand(kHoleNanUpper32 & HeapNumber::kExponentMask));
lw(exponent_reg, FieldMemOperand(value_reg, HeapNumber::kExponentOffset));
Branch(&maybe_nan, ge, exponent_reg, Operand(scratch1));

View File

@ -150,8 +150,7 @@ static void TestNaN(const char *code) {
double value = a->get_scalar(0);
CHECK(std::isnan(value) &&
bit_cast<uint64_t>(value) ==
bit_cast<uint64_t>(
i::FixedDoubleArray::canonical_not_the_hole_nan_as_double()));
bit_cast<uint64_t>(std::numeric_limits<double>::quiet_NaN()));
}