ARM: Always use the overflow flag to check for NaNs participating in a floating point...
authorsgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 12 Jan 2011 07:47:13 +0000 (07:47 +0000)
committersgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 12 Jan 2011 07:47:13 +0000 (07:47 +0000)
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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6277 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/arm/assembler-arm.cc
src/arm/assembler-arm.h
src/arm/lithium-codegen-arm.cc
src/arm/macro-assembler-arm.cc

index f94bd5e..a7c1897 100644 (file)
@@ -2339,14 +2339,12 @@ void Assembler::vcmp(const DwVfpRegister src1,
                      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 @@ void Assembler::vcmp(const DwVfpRegister src1,
                      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 172eca9..430c2ac 100644 (file)
@@ -298,12 +298,17 @@ const DwVfpRegister d14 = { 14 };
 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 {
index 0998339..0e4497f 100644 (file)
@@ -1134,7 +1134,7 @@ void LCodeGen::DoBranch(LBranch* instr) {
 
     // 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 @@ void LCodeGen::DoBranch(LBranch* instr) {
       __ 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 775ee38..2114623 100644 (file)
@@ -532,16 +532,14 @@ void MacroAssembler::VFPCompareAndSetFlags(const DwVfpRegister src1,
                                            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 @@ void MacroAssembler::VFPCompareAndLoadFlags(const DwVfpRegister src1,
                                             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);
 }