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());
}
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);
}
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 {
// 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());
__ 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);
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);
}
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);
}