Reviewers: karlklose, Rodolph Perfetta,

Description:
ARM: Always use the overflow flag to check for NaNs participating in a floating
point compare.

Looks as if we don't need to use the vcmpe instruction instead of the vcmp, as the overflow FPSCR bit suits our purpose. If we at some point need vcmpe lte's
implement it as a separate instruction.

Please review this at http://codereview.chromium.org/6197003/

SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge/

Affected files:
  M     src/arm/assembler-arm.h
  M     src/arm/assembler-arm.cc
  M     src/arm/lithium-codegen-arm.cc
  M     src/arm/macro-assembler-arm.cc


Index: src/arm/assembler-arm.cc
===================================================================
--- src/arm/assembler-arm.cc    (revision 6268)
+++ src/arm/assembler-arm.cc    (working copy)
@@ -2339,14 +2339,12 @@
                      const DwVfpRegister src2,
                      const Condition cond) {
   // vcmp(Dd, Dm) double precision floating point comparison.
-  // We set bit E, as we want any NaN to set the cumulative exception flag
-  // in the FPSCR.
   // Instruction details available in ARM DDI 0406A, A8-570.
   // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0100 (19-16) |
- // Vd(15-12) | 101(11-9) | sz(8)=1 | E(7)=1 | 1(6) | M(5)=? | 0(4) | Vm(3-0) + // Vd(15-12) | 101(11-9) | sz(8)=1 | E(7)=0 | 1(6) | M(5)=? | 0(4) | Vm(3-0)
   ASSERT(CpuFeatures::IsEnabled(VFP3));
   emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 |
-       src1.code()*B12 | 0x5*B9 | B8 | B7 | B6 | src2.code());
+       src1.code()*B12 | 0x5*B9 | B8 | B6 | src2.code());
 }


@@ -2355,14 +2353,12 @@
                      const Condition cond) {
   // vcmp(Dd, Dm) double precision floating point comparison.
   // Instruction details available in ARM DDI 0406A, A8-570.
-  // We set bit E, as we want any NaN to set the cumulative exception flag
-  // in the FPSCR.
   // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0101 (19-16) |
- // Vd(15-12) | 101(11-9) | sz(8)=1 | E(7)=1 | 1(6) | M(5)=? | 0(4) | 0000(3-0) + // Vd(15-12) | 101(11-9) | sz(8)=1 | E(7)=0 | 1(6) | M(5)=? | 0(4) | 0000(3-0)
   ASSERT(CpuFeatures::IsEnabled(VFP3));
   ASSERT(src2 == 0.0);
   emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | B16 |
-       src1.code()*B12 | 0x5*B9 | B8 | B7 | B6);
+       src1.code()*B12 | 0x5*B9 | B8 | B6);
 }


Index: src/arm/assembler-arm.h
===================================================================
--- src/arm/assembler-arm.h     (revision 6268)
+++ src/arm/assembler-arm.h     (working copy)
@@ -298,13 +298,18 @@
 const DwVfpRegister d15 = { 15 };

 // VFP FPSCR constants.
-static const uint32_t kVFPExceptionMask = 0xf;
+static const uint32_t kVFPNConditionFlagBit = 1 << 31;
+static const uint32_t kVFPZConditionFlagBit = 1 << 30;
+static const uint32_t kVFPCConditionFlagBit = 1 << 29;
+static const uint32_t kVFPVConditionFlagBit = 1 << 28;
+
+static const uint32_t kVFPFlushToZeroMask = 1 << 24;
+
 static const uint32_t kVFPRoundingModeMask = 3 << 22;
-static const uint32_t kVFPFlushToZeroMask = 1 << 24;
 static const uint32_t kVFPRoundToMinusInfinityBits = 2 << 22;
-static const uint32_t kVFPZConditionFlagBit = 1 << 30;
-static const uint32_t kVFPInvalidExceptionBit = 1;

+static const uint32_t kVFPExceptionMask = 0xf;
+
 // Coprocessor register
 struct CRegister {
   bool is_valid() const { return 0 <= code_ && code_ < 16; }
Index: src/arm/lithium-codegen-arm.cc
===================================================================
--- src/arm/lithium-codegen-arm.cc      (revision 6268)
+++ src/arm/lithium-codegen-arm.cc      (working copy)
@@ -1082,7 +1082,7 @@

     // Test the double value. Zero and NaN are false.
     __ VFPCompareAndLoadFlags(reg, 0.0, scratch);
- __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPInvalidExceptionBit)); + __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit));
     EmitBranch(true_block, false_block, ne);
   } else {
     ASSERT(r.IsTagged());
@@ -1120,7 +1120,7 @@
       __ sub(ip, reg, Operand(kHeapObjectTag));
       __ vldr(dbl_scratch, ip, HeapNumber::kValueOffset);
       __ VFPCompareAndLoadFlags(dbl_scratch, 0.0, scratch);
- __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPInvalidExceptionBit)); + __ tst(scratch, Operand(kVFPZConditionFlagBit | kVFPVConditionFlagBit));
       __ b(ne, false_label);
       __ b(true_label);

Index: src/arm/macro-assembler-arm.cc
===================================================================
--- src/arm/macro-assembler-arm.cc      (revision 6268)
+++ src/arm/macro-assembler-arm.cc      (working copy)
@@ -532,16 +532,14 @@
                                            const DwVfpRegister src2,
                                            const Condition cond) {
   // Compare and move FPSCR flags to the normal condition flags.
-  vcmp(src1, src2, cond);
-  vmrs(pc, cond);
+  VFPCompareAndLoadFlags(src1, src2, pc, cond);
 }

 void MacroAssembler::VFPCompareAndSetFlags(const DwVfpRegister src1,
                                            const double src2,
                                            const Condition cond) {
   // Compare and move FPSCR flags to the normal condition flags.
-  vcmp(src1, src2, cond);
-  vmrs(pc, cond);
+  VFPCompareAndLoadFlags(src1, src2, pc, cond);
 }


@@ -549,9 +547,6 @@
                                             const DwVfpRegister src2,
                                             const Register fpscr_flags,
                                             const Condition cond) {
- // Clear the Invalid cumulative exception flags (use fpscr_flags as scratch).
-  ClearFPSCRBits(kVFPInvalidExceptionBit, fpscr_flags);
-
   // Compare and load FPSCR.
   vcmp(src1, src2, cond);
   vmrs(fpscr_flags);
@@ -561,9 +556,6 @@
                                             const double src2,
                                             const Register fpscr_flags,
                                             const Condition cond) {
- // Clear the Invalid cumulative exception flags (use fpscr_flags as scratch).
-  ClearFPSCRBits(kVFPInvalidExceptionBit, fpscr_flags);
-
   // Compare and load FPSCR.
   vcmp(src1, src2, cond);
   vmrs(fpscr_flags);


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to