Revision: 21156
Author:   [email protected]
Date:     Tue May  6 08:05:27 2014 UTC
Log:      ARM64: Use default-NaN mode to canonicalize NaNs.

BUG=
[email protected]

Review URL: https://codereview.chromium.org/255343004
http://code.google.com/p/v8/source/detail?r=21156

Modified:
 /branches/bleeding_edge/src/arm64/code-stubs-arm64.cc
 /branches/bleeding_edge/src/arm64/ic-arm64.cc
 /branches/bleeding_edge/src/arm64/lithium-arm64.h
 /branches/bleeding_edge/src/arm64/lithium-codegen-arm64.cc
 /branches/bleeding_edge/src/arm64/macro-assembler-arm64-inl.h
 /branches/bleeding_edge/src/arm64/macro-assembler-arm64.cc
 /branches/bleeding_edge/src/arm64/macro-assembler-arm64.h
 /branches/bleeding_edge/src/objects.h
 /branches/bleeding_edge/test/cctest/test-assembler-arm64.cc

=======================================
--- /branches/bleeding_edge/src/arm64/code-stubs-arm64.cc Wed Apr 30 14:33:35 2014 UTC +++ /branches/bleeding_edge/src/arm64/code-stubs-arm64.cc Tue May 6 08:05:27 2014 UTC
@@ -1577,6 +1577,7 @@
   //         jssp[8]:     Preserved x22 (used for argc).
   //         jssp[0]:     Preserved x21 (used for argv).
   __ Drop(x11);
+  __ AssertFPCRState();
   __ Ret();

   // The stack pointer is still csp if we aren't returning, and the frame
@@ -1660,6 +1661,11 @@
   __ Mov(jssp, csp);
   __ SetStackPointer(jssp);

+ // Configure the FPCR. We don't restore it, so this is technically not allowed + // according to AAPCS64. However, we only set default-NaN mode and this will
+  // be harmless for most C code. Also, it works for ARM.
+  __ ConfigureFPCR();
+
   ProfileEntryHookStub::MaybeCallEntryHook(masm);

   // Set up the reserved register for 0.0.
@@ -4633,7 +4639,7 @@

   __ Bind(&double_elements);
   __ Ldr(x10, FieldMemOperand(array, JSObject::kElementsOffset));
-  __ StoreNumberToDoubleElements(value, index_smi, x10, x11, d0, d1,
+  __ StoreNumberToDoubleElements(value, index_smi, x10, x11, d0,
                                  &slow_elements);
   __ Ret();
 }
@@ -4735,6 +4741,7 @@
   __ Blr(x10);
   // Return to calling code.
   __ Peek(lr, 0);
+  __ AssertFPCRState();
   __ Ret();

   __ SetStackPointer(old_stack_pointer);
=======================================
--- /branches/bleeding_edge/src/arm64/ic-arm64.cc Tue Apr 29 06:42:26 2014 UTC +++ /branches/bleeding_edge/src/arm64/ic-arm64.cc Tue May 6 08:05:27 2014 UTC
@@ -1021,7 +1021,6 @@
                                  elements,
                                  x10,
                                  d0,
-                                 d1,
                                  &transition_double_elements);
   if (increment_length == kIncrementLength) {
     // Add 1 to receiver->length.
=======================================
--- /branches/bleeding_edge/src/arm64/lithium-arm64.h Mon May 5 11:03:14 2014 UTC +++ /branches/bleeding_edge/src/arm64/lithium-arm64.h Tue May 6 08:05:27 2014 UTC
@@ -2386,6 +2386,10 @@
   }

   bool NeedsCanonicalization() {
+    if (hydrogen()->value()->IsAdd() || hydrogen()->value()->IsSub() ||
+        hydrogen()->value()->IsMul() || hydrogen()->value()->IsDiv()) {
+      return false;
+    }
     return this->hydrogen()->NeedsCanonicalization();
   }
uint32_t additional_index() const { return this->hydrogen()->index_offset(); }
=======================================
--- /branches/bleeding_edge/src/arm64/lithium-codegen-arm64.cc Tue May 6 07:05:07 2014 UTC +++ /branches/bleeding_edge/src/arm64/lithium-codegen-arm64.cc Tue May 6 08:05:27 2014 UTC
@@ -5174,11 +5174,8 @@
   }

   if (instr->NeedsCanonicalization()) {
-    DoubleRegister dbl_scratch = double_scratch();
-    __ Fmov(dbl_scratch,
-            FixedDoubleArray::canonical_not_the_hole_nan_as_double());
-    __ Fmaxnm(dbl_scratch, dbl_scratch, value);
-    __ Str(dbl_scratch, FieldMemOperand(store_base, offset));
+    __ CanonicalizeNaN(double_scratch(), value);
+    __ Str(double_scratch(), FieldMemOperand(store_base, offset));
   } else {
     __ Str(value, FieldMemOperand(store_base, offset));
   }
=======================================
--- /branches/bleeding_edge/src/arm64/macro-assembler-arm64-inl.h Tue Apr 29 06:42:26 2014 UTC +++ /branches/bleeding_edge/src/arm64/macro-assembler-arm64-inl.h Tue May 6 08:05:27 2014 UTC
@@ -977,7 +977,6 @@

 void MacroAssembler::Msr(SystemRegister sysreg, const Register& rt) {
   ASSERT(allow_macro_instructions_);
-  ASSERT(!rt.IsZero());
   msr(sysreg, rt);
 }

=======================================
--- /branches/bleeding_edge/src/arm64/macro-assembler-arm64.cc Wed Apr 30 09:50:58 2014 UTC +++ /branches/bleeding_edge/src/arm64/macro-assembler-arm64.cc Tue May 6 08:05:27 2014 UTC
@@ -1220,6 +1220,64 @@
     }
   }
 }
+
+
+void MacroAssembler::AssertFPCRState(Register fpcr) {
+  if (emit_debug_code()) {
+    Label unexpected_mode, done;
+    UseScratchRegisterScope temps(this);
+    if (fpcr.IsNone()) {
+      fpcr = temps.AcquireX();
+      Mrs(fpcr, FPCR);
+    }
+
+    // Settings overridden by ConfiugreFPCR():
+    //   - Assert that default-NaN mode is set.
+    Tbz(fpcr, DN_offset, &unexpected_mode);
+
+    // Settings left to their default values:
+    //   - Assert that flush-to-zero is not set.
+    Tbnz(fpcr, FZ_offset, &unexpected_mode);
+    //   - Assert that the rounding mode is nearest-with-ties-to-even.
+    STATIC_ASSERT(FPTieEven == 0);
+    Tst(fpcr, RMode_mask);
+    B(eq, &done);
+
+    Bind(&unexpected_mode);
+    Abort(kUnexpectedFPCRMode);
+
+    Bind(&done);
+  }
+}
+
+
+void MacroAssembler::ConfigureFPCR() {
+  UseScratchRegisterScope temps(this);
+  Register fpcr = temps.AcquireX();
+  Mrs(fpcr, FPCR);
+
+ // If necessary, enable default-NaN mode. The default values of the other FPCR
+  // options should be suitable, and AssertFPCRState will verify that.
+  Label no_write_required;
+  Tbnz(fpcr, DN_offset, &no_write_required);
+
+  Orr(fpcr, fpcr, DN_mask);
+  Msr(FPCR, fpcr);
+
+  Bind(&no_write_required);
+  AssertFPCRState(fpcr);
+}
+
+
+void MacroAssembler::CanonicalizeNaN(const FPRegister& dst,
+                                     const FPRegister& src) {
+  AssertFPCRState();
+
+ // With DN=1 and RMode=FPTieEven, subtracting 0.0 preserves all inputs except
+  // for NaNs, which become the default NaN. We use fsub rather than fadd
+ // because sub preserves -0.0 inputs: -0.0 + 0.0 = 0.0, but -0.0 - 0.0 = -0.0.
+  Fsub(dst, src, fp_zero);
+}


 void MacroAssembler::LoadRoot(CPURegister destination,
@@ -3888,7 +3946,6 @@
                                                  Register elements_reg,
                                                  Register scratch1,
                                                  FPRegister fpscratch1,
-                                                 FPRegister fpscratch2,
                                                  Label* fail,
                                                  int elements_offset) {
   ASSERT(!AreAliased(value_reg, key_reg, elements_reg, scratch1));
@@ -3906,12 +3963,9 @@
            fail, DONT_DO_SMI_CHECK);

   Ldr(fpscratch1, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
- Fmov(fpscratch2, FixedDoubleArray::canonical_not_the_hole_nan_as_double());

-  // Check for NaN by comparing the number to itself: NaN comparison will
-  // report unordered, indicated by the overflow flag being set.
-  Fcmp(fpscratch1, fpscratch1);
-  Fcsel(fpscratch1, fpscratch2, fpscratch1, vs);
+  // Canonicalize NaNs.
+  CanonicalizeNaN(fpscratch1);

   // Store the result.
   Bind(&store_num);
=======================================
--- /branches/bleeding_edge/src/arm64/macro-assembler-arm64.h Tue Apr 29 06:42:26 2014 UTC +++ /branches/bleeding_edge/src/arm64/macro-assembler-arm64.h Tue May 6 08:05:27 2014 UTC
@@ -787,6 +787,13 @@
// Helpers ------------------------------------------------------------------
   // Root register.
   inline void InitializeRootRegister();
+
+  void AssertFPCRState(Register fpcr = NoReg);
+  void ConfigureFPCR();
+  void CanonicalizeNaN(const FPRegister& dst, const FPRegister& src);
+  void CanonicalizeNaN(const FPRegister& reg) {
+    CanonicalizeNaN(reg, reg);
+  }

   // Load an object from the root table.
   void LoadRoot(CPURegister destination,
@@ -1533,7 +1540,6 @@
                                    Register elements_reg,
                                    Register scratch1,
                                    FPRegister fpscratch1,
-                                   FPRegister fpscratch2,
                                    Label* fail,
                                    int elements_offset = 0);

=======================================
--- /branches/bleeding_edge/src/objects.h       Mon May  5 18:27:57 2014 UTC
+++ /branches/bleeding_edge/src/objects.h       Tue May  6 08:05:27 2014 UTC
@@ -1291,6 +1291,7 @@
V(kUnexpectedNegativeValue, "Unexpected negative value") \ V(kUnexpectedNumberOfPreAllocatedPropertyFields, \ "Unexpected number of pre-allocated property fields") \ + V(kUnexpectedFPCRMode, "Unexpected FPCR mode.") \ V(kUnexpectedSmi, "Unexpected smi value") \ V(kUnexpectedStringFunction, "Unexpected String function") \ V(kUnexpectedStringType, "Unexpected string type") \
=======================================
--- /branches/bleeding_edge/test/cctest/test-assembler-arm64.cc Tue Apr 29 10:58:16 2014 UTC +++ /branches/bleeding_edge/test/cctest/test-assembler-arm64.cc Tue May 6 08:05:27 2014 UTC
@@ -177,7 +177,11 @@
   CpuFeatures::Probe(false);

#define RESET() \
-  __ Reset();
+ __ Reset(); \ + /* Reset the machine state (like simulator.ResetState()). */ \ + __ Msr(NZCV, xzr); \
+  __ Msr(FPCR, xzr);
+

#define START_AFTER_RESET() \ __ SetStackPointer(csp); \

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to