Reviewers: Karl Klose,

Description:
ARM: Add instruction VFPCompareAndSetFlags to macro assembler

Please review this at http://codereview.chromium.org/6117003/

SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge/

Affected files:
  M     src/arm/code-stubs-arm.cc
  M     src/arm/codegen-arm.cc
  M     src/arm/lithium-codegen-arm.cc
  M     src/arm/macro-assembler-arm.h


Index: src/arm/code-stubs-arm.cc
===================================================================
--- src/arm/code-stubs-arm.cc   (revision 6232)
+++ src/arm/code-stubs-arm.cc   (working copy)
@@ -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);
Index: src/arm/codegen-arm.cc
===================================================================
--- src/arm/codegen-arm.cc      (revision 6232)
+++ src/arm/codegen-arm.cc      (working copy)
@@ -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);
Index: src/arm/lithium-codegen-arm.cc
===================================================================
--- src/arm/lithium-codegen-arm.cc      (revision 6232)
+++ src/arm/lithium-codegen-arm.cc      (working copy)
@@ -1076,8 +1076,7 @@
     EmitBranch(true_block, false_block, nz);
   } else if (r.IsDouble()) {
     DoubleRegister reg = ToDoubleRegister(instr->input());
-    __ vcmp(reg, 0.0);
-    __ vmrs(pc);  // Move vector status bits to normal status bits.
+    __ VFPCompareAndSetFlags(reg, 0.0);
     EmitBranch(true_block, false_block, ne);
   } else {
     ASSERT(r.IsTagged());
@@ -1114,8 +1113,7 @@
       __ b(ne, &call_stub);
       __ sub(ip, reg, Operand(kHeapObjectTag));
       __ vldr(dbl_scratch, ip, HeapNumber::kValueOffset);
-      __ vcmp(dbl_scratch, 0.0);
-      __ vmrs(pc);  // Move vector status bits to normal status bits.
+      __ VFPCompareAndSetFlags(dbl_scratch, 0.0);
       __ b(eq, false_label);
       __ b(true_label);

@@ -2179,7 +2177,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.
@@ -2200,8 +2198,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));
Index: src/arm/macro-assembler-arm.h
===================================================================
--- src/arm/macro-assembler-arm.h       (revision 6232)
+++ src/arm/macro-assembler-arm.h       (working copy)
@@ -579,6 +579,21 @@
                          Register source,
                          Register scratch);

+  void VFPCompareAndSetFlags(const DwVfpRegister src1,
+                             const DwVfpRegister src2,
+                             const SBit s = LeaveCC,
+                             const Condition cond = al) {
+    vcmp(src1, src2, s, cond);
+    vmrs(pc);
+  }
+  void VFPCompareAndSetFlags(const DwVfpRegister src1,
+                             const double src2,
+                             const SBit s = LeaveCC,
+                             const Condition cond = al) {
+    vcmp(src1, src2, s, cond);
+    vmrs(pc);
+  }
+
// ---------------------------------------------------------------------------
   // Runtime calls



--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to