ARM: Small optimisation of VFP immediate creation
authordanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 25 Sep 2012 14:32:07 +0000 (14:32 +0000)
committerdanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 25 Sep 2012 14:32:07 +0000 (14:32 +0000)
Save an instruction in VFP immediate creation by passing a scratch register.

BUG=none
TEST=none

Review URL: https://chromiumcodereview.appspot.com/10990024
Patch from Martyn Capewell <m.m.capewell@googlemail.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12605 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/arm/assembler-arm.cc
src/arm/assembler-arm.h
src/arm/code-stubs-arm.cc
src/arm/lithium-codegen-arm.cc
src/arm/macro-assembler-arm.cc
src/arm/macro-assembler-arm.h

index 30a8830c9eae0a219d694a38788ac8c4c972fa18..78db06d2675f0b2231baa4cb96a7c1b7a97bb7f2 100644 (file)
@@ -1975,6 +1975,7 @@ static bool FitsVMOVDoubleImmediate(double d, uint32_t *encoding) {
 
 void Assembler::vmov(const DwVfpRegister dst,
                      double imm,
+                     const Register scratch,
                      const Condition cond) {
   // Dd = immediate
   // Instruction details available in ARM DDI 0406B, A8-640.
@@ -1989,22 +1990,22 @@ void Assembler::vmov(const DwVfpRegister dst,
     // using vldr from a constant pool.
     uint32_t lo, hi;
     DoubleAsTwoUInt32(imm, &lo, &hi);
+    mov(ip, Operand(lo));
 
-    if (lo == hi) {
-      // If the lo and hi parts of the double are equal, the literal is easier
-      // to create. This is the case with 0.0.
-      mov(ip, Operand(lo));
-      vmov(dst, ip, ip);
-    } else {
+    if (scratch.is(no_reg)) {
       // Move the low part of the double into the lower of the corresponsing S
       // registers of D register dst.
-      mov(ip, Operand(lo));
       vmov(dst.low(), ip, cond);
 
       // Move the high part of the double into the higher of the corresponsing S
       // registers of D register dst.
       mov(ip, Operand(hi));
       vmov(dst.high(), ip, cond);
+    } else {
+      // Move the low and high parts of the double to a D register in one
+      // instruction.
+      mov(scratch, Operand(hi));
+      vmov(dst, ip, scratch, cond);
     }
   }
 }
index 7f2ce30aeeadb125b2392cadc4e55b171802f7e9..c62d480ebaf170dbf39016efee8cef00d8f76217 100644 (file)
@@ -1053,6 +1053,7 @@ class Assembler : public AssemblerBase {
 
   void vmov(const DwVfpRegister dst,
             double imm,
+            const Register scratch = no_reg,
             const Condition cond = al);
   void vmov(const SwVfpRegister dst,
             const SwVfpRegister src,
index 31cc5a28cd1cbd193b95b7fc20ce68a511026fb3..fe9a815d23983ba77e15641e3e5004d736a70ef6 100644 (file)
@@ -3636,13 +3636,13 @@ void MathPowStub::Generate(MacroAssembler* masm) {
       Label not_plus_half;
 
       // Test for 0.5.
-      __ vmov(double_scratch, 0.5);
+      __ vmov(double_scratch, 0.5, scratch);
       __ VFPCompareAndSetFlags(double_exponent, double_scratch);
       __ b(ne, &not_plus_half);
 
       // Calculates square root of base.  Check for the special case of
       // Math.pow(-Infinity, 0.5) == Infinity (ECMA spec, 15.8.2.13).
-      __ vmov(double_scratch, -V8_INFINITY);
+      __ vmov(double_scratch, -V8_INFINITY, scratch);
       __ VFPCompareAndSetFlags(double_base, double_scratch);
       __ vneg(double_result, double_scratch, eq);
       __ b(eq, &done);
@@ -3653,20 +3653,20 @@ void MathPowStub::Generate(MacroAssembler* masm) {
       __ jmp(&done);
 
       __ bind(&not_plus_half);
-      __ vmov(double_scratch, -0.5);
+      __ vmov(double_scratch, -0.5, scratch);
       __ VFPCompareAndSetFlags(double_exponent, double_scratch);
       __ b(ne, &call_runtime);
 
       // Calculates square root of base.  Check for the special case of
       // Math.pow(-Infinity, -0.5) == 0 (ECMA spec, 15.8.2.13).
-      __ vmov(double_scratch, -V8_INFINITY);
+      __ vmov(double_scratch, -V8_INFINITY, scratch);
       __ VFPCompareAndSetFlags(double_base, double_scratch);
       __ vmov(double_result, kDoubleRegZero, eq);
       __ b(eq, &done);
 
       // Add +0 to convert -0 to +0.
       __ vadd(double_scratch, double_base, kDoubleRegZero);
-      __ vmov(double_result, 1.0);
+      __ vmov(double_result, 1.0, scratch);
       __ vsqrt(double_scratch, double_scratch);
       __ vdiv(double_result, double_result, double_scratch);
       __ jmp(&done);
@@ -3701,7 +3701,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
     __ mov(exponent, scratch);
   }
   __ vmov(double_scratch, double_base);  // Back up base.
-  __ vmov(double_result, 1.0);
+  __ vmov(double_result, 1.0, scratch2);
 
   // Get absolute value of exponent.
   __ cmp(scratch, Operand(0));
@@ -3717,7 +3717,7 @@ void MathPowStub::Generate(MacroAssembler* masm) {
 
   __ cmp(exponent, Operand(0));
   __ b(ge, &done);
-  __ vmov(double_scratch, 1.0);
+  __ vmov(double_scratch, 1.0, scratch);
   __ vdiv(double_result, double_scratch, double_result);
   // Test whether result is zero.  Bail out to check for subnormal result.
   // Due to subnormals, x^-y == (1/x)^y does not hold in all cases.
index d5c730889fb750b65ced06fb29037265f68b0c08..e07118317c464ba1041fc36814dfcfda6b56fb16 100644 (file)
@@ -1551,7 +1551,7 @@ void LCodeGen::DoConstantD(LConstantD* instr) {
   ASSERT(instr->result()->IsDoubleRegister());
   DwVfpRegister result = ToDoubleRegister(instr->result());
   double v = instr->value();
-  __ Vmov(result, v);
+  __ Vmov(result, v, scratch0());
 }
 
 
@@ -3530,12 +3530,12 @@ void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
   __ cmp(scratch, Operand(HeapNumber::kExponentBias + 32));
   DeoptimizeIf(ge, instr->environment());
 
+  __ Vmov(double_scratch0(), 0.5, scratch);
+  __ vadd(double_scratch0(), input, double_scratch0());
+
   // Save the original sign for later comparison.
   __ and_(scratch, result, Operand(HeapNumber::kSignMask));
 
-  __ Vmov(double_scratch0(), 0.5);
-  __ vadd(double_scratch0(), input, double_scratch0());
-
   // Check sign of the result: if the sign changed, the input
   // value was in ]0.5, 0[ and the result should be -0.
   __ vmov(result, double_scratch0().high());
@@ -3584,7 +3584,7 @@ void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
   // Math.pow(-Infinity, 0.5) == Infinity
   // Math.sqrt(-Infinity) == NaN
   Label done;
-  __ vmov(temp, -V8_INFINITY);
+  __ vmov(temp, -V8_INFINITY, scratch0());
   __ VFPCompareAndSetFlags(input, temp);
   __ vneg(result, temp, eq);
   __ b(&done, eq);
@@ -4066,7 +4066,7 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
     // Only load canonical NaN if the comparison above set the overflow.
     __ Vmov(value,
             FixedDoubleArray::canonical_not_the_hole_nan_as_double(),
-            vs);
+            no_reg, vs);
   }
 
   __ vstr(value, scratch, instr->additional_index() << element_size_shift);
index c616c896f493a1a3edb586219e18175ef2866a4a..fef33c14ea8816850fe68ba5a811a3db737b911c 100644 (file)
@@ -789,6 +789,7 @@ void MacroAssembler::VFPCompareAndLoadFlags(const DwVfpRegister src1,
 
 void MacroAssembler::Vmov(const DwVfpRegister dst,
                           const double imm,
+                          const Register scratch,
                           const Condition cond) {
   ASSERT(CpuFeatures::IsEnabled(VFP2));
   static const DoubleRepresentation minus_zero(-0.0);
@@ -800,7 +801,7 @@ void MacroAssembler::Vmov(const DwVfpRegister dst,
   } else if (value.bits == minus_zero.bits) {
     vneg(dst, kDoubleRegZero, cond);
   } else {
-    vmov(dst, imm, cond);
+    vmov(dst, imm, scratch, cond);
   }
 }
 
@@ -3676,7 +3677,7 @@ void MacroAssembler::ClampDoubleToUint8(Register result_reg,
 
   // Double value is >= 255, return 255.
   bind(&above_zero);
-  Vmov(temp_double_reg, 255.0);
+  Vmov(temp_double_reg, 255.0, result_reg);
   VFPCompareAndSetFlags(input_reg, temp_double_reg);
   b(le, &in_bounds);
   mov(result_reg, Operand(255));
index 7d127b5e8781f6086ceaacc0c5c50ece65b8adf3..5a810277428154a7f1fe9aac8a32ee5aaa298ae8 100644 (file)
@@ -483,6 +483,7 @@ class MacroAssembler: public Assembler {
 
   void Vmov(const DwVfpRegister dst,
             const double imm,
+            const Register scratch = no_reg,
             const Condition cond = al);
 
   // Enter exit frame.