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