Revision: 6268
Author: [email protected]
Date: Tue Jan 11 04:45:25 2011
Log: ARM: Add instructions VFPCompareAndSetFlags and VFPCompareAndLoadFlags
to macro assembler
Also removed the SBit from the vcmp instruction as it is not part of the
instruction.
Review URL: http://codereview.chromium.org/6117003
http://code.google.com/p/v8/source/detail?r=6268
Modified:
/branches/bleeding_edge/src/arm/assembler-arm.cc
/branches/bleeding_edge/src/arm/assembler-arm.h
/branches/bleeding_edge/src/arm/code-stubs-arm.cc
/branches/bleeding_edge/src/arm/codegen-arm.cc
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/arm/macro-assembler-arm.cc
/branches/bleeding_edge/src/arm/macro-assembler-arm.h
=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm.cc Mon Jan 10 00:04:30
2011
+++ /branches/bleeding_edge/src/arm/assembler-arm.cc Tue Jan 11 04:45:25
2011
@@ -2337,7 +2337,6 @@
void Assembler::vcmp(const DwVfpRegister src1,
const DwVfpRegister src2,
- const SBit s,
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
@@ -2353,7 +2352,6 @@
void Assembler::vcmp(const DwVfpRegister src1,
const double src2,
- const SBit s,
const Condition cond) {
// vcmp(Dd, Dm) double precision floating point comparison.
// Instruction details available in ARM DDI 0406A, A8-570.
=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm.h Mon Jan 10 00:04:30 2011
+++ /branches/bleeding_edge/src/arm/assembler-arm.h Tue Jan 11 04:45:25 2011
@@ -1147,11 +1147,9 @@
const Condition cond = al);
void vcmp(const DwVfpRegister src1,
const DwVfpRegister src2,
- const SBit s = LeaveCC,
const Condition cond = al);
void vcmp(const DwVfpRegister src1,
const double src2,
- const SBit s = LeaveCC,
const Condition cond = al);
void vmrs(const Register dst,
const Condition cond = al);
=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.cc Thu Jan 6 04:41:41
2011
+++ /branches/bleeding_edge/src/arm/code-stubs-arm.cc Tue Jan 11 04:45:25
2011
@@ -866,8 +866,7 @@
__ vldr(d0, scratch2, HeapNumber::kValueOffset);
__ sub(probe, probe, Operand(kHeapObjectTag));
__ vldr(d1, probe, HeapNumber::kValueOffset);
- __ vcmp(d0, d1);
- __ vmrs(pc);
+ __ VFPCompareAndSetFlags(d0, d1);
__ b(ne, not_found); // The cache did not contain this value.
__ b(&load_result_from_cache);
} else {
@@ -975,8 +974,7 @@
CpuFeatures::Scope scope(VFP3);
Label no_nan;
// ARMv7 VFP3 instructions to implement double precision comparison.
- __ vcmp(d7, d6);
- __ vmrs(pc); // Move vector status bits to normal status bits.
+ __ VFPCompareAndSetFlags(d7, d6);
Label nan;
__ b(vs, &nan);
__ mov(r0, Operand(EQUAL), LeaveCC, eq);
@@ -1096,8 +1094,7 @@
__ sub(ip, tos_, Operand(kHeapObjectTag));
__ vldr(d1, ip, HeapNumber::kValueOffset);
- __ vcmp(d1, 0.0);
- __ vmrs(pc);
+ __ VFPCompareAndSetFlags(d1, 0.0);
// "tos_" is a register, and contains a non zero value by default.
// Hence we only need to overwrite "tos_" with zero to return false for
// FP_ZERO or FP_NAN cases. Otherwise, by default it returns true.
@@ -4915,8 +4912,7 @@
__ vldr(d1, r2, HeapNumber::kValueOffset);
// Compare operands
- __ vcmp(d0, d1);
- __ vmrs(pc); // Move vector status bits to normal status bits.
+ __ VFPCompareAndSetFlags(d0, d1);
// Don't base result on status bits when a NaN is involved.
__ b(vs, &unordered);
=======================================
--- /branches/bleeding_edge/src/arm/codegen-arm.cc Thu Jan 6 07:53:56 2011
+++ /branches/bleeding_edge/src/arm/codegen-arm.cc Tue Jan 11 04:45:25 2011
@@ -4667,8 +4667,7 @@
__ mov(scratch2, Operand(0x7FF00000));
__ mov(scratch1, Operand(0, RelocInfo::NONE));
__ vmov(d1, scratch1, scratch2); // Load infinity into d1.
- __ vcmp(d0, d1);
- __ vmrs(pc);
+ __ VFPCompareAndSetFlags(d0, d1);
runtime.Branch(eq); // d0 reached infinity.
__ vdiv(d0, d2, d0);
__ b(&allocate_return);
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Jan 11
04:32:00 2011
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Jan 11
04:45:25 2011
@@ -1080,13 +1080,8 @@
DoubleRegister reg = ToDoubleRegister(instr->input());
Register scratch = scratch0();
- // Test for the double value. Zero and NaN are false.
- // Clear the Invalid cumulative exception flags.
- __ ClearFPSCRBits(kVFPInvalidExceptionBit, scratch);
- __ vcmp(reg, 0.0);
- // Retrieve the exception and status flags and
- // check for zero or an invalid exception.
- __ vmrs(scratch);
+ // Test the double value. Zero and NaN are false.
+ __ VFPCompareAndLoadFlags(reg, 0.0, scratch);
__ tst(scratch, Operand(kVFPZConditionFlagBit |
kVFPInvalidExceptionBit));
EmitBranch(true_block, false_block, ne);
} else {
@@ -1114,7 +1109,7 @@
__ tst(reg, Operand(kSmiTagMask));
__ b(eq, true_label);
- // Test for double values. Zero and NaN are false.
+ // Test double values. Zero and NaN are false.
Label call_stub;
DoubleRegister dbl_scratch = d0;
Register scratch = scratch0();
@@ -1124,12 +1119,7 @@
__ b(ne, &call_stub);
__ sub(ip, reg, Operand(kHeapObjectTag));
__ vldr(dbl_scratch, ip, HeapNumber::kValueOffset);
- // Clear the Invalid cumulative exception flags.
- __ ClearFPSCRBits(kVFPInvalidExceptionBit, scratch);
- __ vcmp(dbl_scratch, 0.0);
- // Retrieve the exception and status flags and
- // check for zero or an invalid exception.
- __ vmrs(scratch);
+ __ VFPCompareAndLoadFlags(dbl_scratch, 0.0, scratch);
__ tst(scratch, Operand(kVFPZConditionFlagBit |
kVFPInvalidExceptionBit));
__ b(ne, false_label);
__ b(true_label);
@@ -2206,7 +2196,7 @@
__ bind(&heap_number);
__ sub(ip, input_reg, Operand(kHeapObjectTag));
__ vldr(dbl_tmp, ip, HeapNumber::kValueOffset);
- __ vcmp(dbl_tmp, 0.0); // Sets overflow bit if NaN.
+ __ vcmp(dbl_tmp, 0.0); // Sets overflow bit in FPSCR flags if NaN.
__ vcvt_s32_f64(flt_scratch, dbl_tmp);
__ vmov(input_reg, flt_scratch); // 32-bit result of conversion.
__ vmrs(pc); // Move vector status bits to normal status bits.
@@ -2227,8 +2217,7 @@
// back to check; note that using non-overlapping s and d regs would be
// slightly faster.
__ vcvt_f64_s32(dbl_scratch, flt_scratch);
- __ vcmp(dbl_scratch, dbl_tmp);
- __ vmrs(pc); // Move vector status bits to normal status bits.
+ __ VFPCompareAndSetFlags(dbl_scratch, dbl_tmp);
DeoptimizeIf(ne, instr->environment()); // Not equal or unordered.
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
__ tst(input_reg, Operand(input_reg));
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Mon Jan 10
04:24:19 2011
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Tue Jan 11
04:45:25 2011
@@ -519,10 +519,54 @@
}
-void MacroAssembler::ClearFPSCRBits(uint32_t bits_to_clear, Register
scratch) {
- vmrs(scratch);
- bic(scratch, scratch, Operand(bits_to_clear));
- vmsr(scratch);
+void MacroAssembler::ClearFPSCRBits(const uint32_t bits_to_clear,
+ const Register scratch,
+ const Condition cond) {
+ vmrs(scratch, cond);
+ bic(scratch, scratch, Operand(bits_to_clear), LeaveCC, cond);
+ vmsr(scratch, cond);
+}
+
+
+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);
+}
+
+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);
+}
+
+
+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);
+}
+
+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);
}
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.h Mon Jan 10
04:24:19 2011
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.h Tue Jan 11
04:45:25 2011
@@ -247,8 +247,29 @@
const MemOperand& dst,
Condition cond = al);
- // Clear FPSCR bits.
- void ClearFPSCRBits(uint32_t bits_to_clear, Register scratch);
+ // Clear specified FPSCR bits.
+ void ClearFPSCRBits(const uint32_t bits_to_clear,
+ const Register scratch,
+ const Condition cond = al);
+
+ // Compare double values and move the result to the normal condition
flags.
+ void VFPCompareAndSetFlags(const DwVfpRegister src1,
+ const DwVfpRegister src2,
+ const Condition cond = al);
+ void VFPCompareAndSetFlags(const DwVfpRegister src1,
+ const double src2,
+ const Condition cond = al);
+
+ // Compare double values and then load the fpscr flags to a register.
+ void VFPCompareAndLoadFlags(const DwVfpRegister src1,
+ const DwVfpRegister src2,
+ const Register fpscr_flags,
+ const Condition cond = al);
+ void VFPCompareAndLoadFlags(const DwVfpRegister src1,
+ const double src2,
+ const Register fpscr_flags,
+ const Condition cond = al);
+
//
---------------------------------------------------------------------------
// Activation frames
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev