MIPS: Use signaling NaN for holes in fixed double arrays.
authorpaul.lind <paul.lind@imgtec.com>
Thu, 22 Jan 2015 06:14:52 +0000 (22:14 -0800)
committerCommit bot <commit-bot@chromium.org>
Thu, 22 Jan 2015 06:15:02 +0000 (06:15 +0000)
Port 9eace97bbaab72962c0fda62e5f9011a10604d0d
Port 5d641ec969e376ee7fa258b41b2988c9e75c4bc8

BUG=

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

Cr-Commit-Position: refs/heads/master@{#26208}

src/mips/codegen-mips.cc
src/mips/lithium-codegen-mips.cc
src/mips/lithium-mips.h
src/mips/macro-assembler-mips.cc
src/mips64/codegen-mips64.cc
src/mips64/macro-assembler-mips64.cc
test/cctest/test-macro-assembler-mips.cc

index fbd4044..0e28eed 100644 (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));
index 4ec552d..2c5e7f1 100644 (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);
 }
index ecffef7..365ffd1 100644 (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(); }
 };
 
 
index 6079180..b43fb56 100644 (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));
 
index b292506..fa0a2db 100644 (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));
index 2761ca0..9032473 100644 (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));
 
index 6cb00e4..3a97d21 100644 (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()));
 }