Revision: 6277
Author: [email protected]
Date: Tue Jan 11 23:47:13 2011
Log: 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.
Review URL: http://codereview.chromium.org/6197003
http://code.google.com/p/v8/source/detail?r=6277

Modified:
 /branches/bleeding_edge/src/arm/assembler-arm.cc
 /branches/bleeding_edge/src/arm/assembler-arm.h
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
 /branches/bleeding_edge/src/arm/macro-assembler-arm.cc

=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm.cc Tue Jan 11 04:45:25 2011 +++ /branches/bleeding_edge/src/arm/assembler-arm.cc Tue Jan 11 23:47:13 2011
@@ -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);
 }


=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm.h     Tue Jan 11 04:45:25 2011
+++ /branches/bleeding_edge/src/arm/assembler-arm.h     Tue Jan 11 23:47:13 2011
@@ -298,12 +298,17 @@
 const DwVfpRegister d15 = { 15 };

 // VFP FPSCR constants.
-static const uint32_t kVFPExceptionMask = 0xf;
-static const uint32_t kVFPRoundingModeMask = 3 << 22;
+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 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 {
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Jan 11 07:51:08 2011 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Jan 11 23:47:13 2011
@@ -1134,7 +1134,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());
@@ -1172,7 +1172,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);

=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Tue Jan 11 06:11:03 2011 +++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Tue Jan 11 23:47:13 2011
@@ -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,24 +547,18 @@
                                             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);
+  vmrs(fpscr_flags, cond);
 }

 void MacroAssembler::VFPCompareAndLoadFlags(const DwVfpRegister src1,
                                             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);
+  vmrs(fpscr_flags, cond);
 }


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

Reply via email to