Commit 8f546061 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6277 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent b6ebcd58
......@@ -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);
}
......
......@@ -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 {
......
......@@ -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);
......
......@@ -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);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment