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

Reply via email to