Revision: 13162
Author:   [email protected]
Date:     Fri Dec  7 03:29:27 2012
Log:      Improve double to integer truncation on ARM.

BUG=none
TEST=none

Review URL: https://chromiumcodereview.appspot.com/11412272
Patch from Rodolph Perfetta <[email protected]>.
http://code.google.com/p/v8/source/detail?r=13162

Modified:
 /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/stub-cache-arm.cc

=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Dec 5 07:49:22 2012 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Fri Dec 7 03:29:27 2012
@@ -4968,7 +4968,6 @@
   if (instr->truncating()) {
     CpuFeatures::Scope scope(VFP2);
     Register scratch3 = ToRegister(instr->temp2());
-    SwVfpRegister single_scratch = double_scratch.low();
     ASSERT(!scratch3.is(input_reg) &&
            !scratch3.is(scratch1) &&
            !scratch3.is(scratch2));
@@ -4990,7 +4989,7 @@

     __ EmitECMATruncate(input_reg,
                         double_scratch2,
-                        single_scratch,
+                        double_scratch,
                         scratch1,
                         scratch2,
                         scratch3);
@@ -5072,20 +5071,19 @@
   Register scratch1 = scratch0();
   Register scratch2 = ToRegister(instr->temp());
   DwVfpRegister double_input = ToDoubleRegister(instr->value());
+  DwVfpRegister double_scratch = double_scratch0();

   Label done;

   if (instr->truncating()) {
     Register scratch3 = ToRegister(instr->temp2());
-    SwVfpRegister single_scratch = double_scratch0().low();
     __ EmitECMATruncate(result_reg,
                         double_input,
-                        single_scratch,
+                        double_scratch,
                         scratch1,
                         scratch2,
                         scratch3);
   } else {
-    DwVfpRegister double_scratch = double_scratch0();
     __ EmitVFPTruncate(kRoundToMinusInf,
                        result_reg,
                        double_input,
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Wed Dec 5 03:04:10 2012 +++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Fri Dec 7 03:29:27 2012
@@ -2488,6 +2488,20 @@
     bind(&done);
   }
 }
+
+
+void MacroAssembler::TryFastDoubleToInt32(Register result,
+                                          DwVfpRegister double_input,
+                                          DwVfpRegister double_scratch,
+                                          Label* done) {
+  ASSERT(!double_input.is(double_scratch));
+
+  vcvt_s32_f64(double_scratch.low(), double_input);
+  vmov(result, double_scratch.low());
+  vcvt_f64_s32(double_scratch, double_scratch.low());
+  VFPCompareAndSetFlags(double_input, double_scratch);
+  b(eq, done);
+}


 void MacroAssembler::EmitVFPTruncate(VFPRoundingMode rounding_mode,
@@ -2505,11 +2519,7 @@
   Label done;

// Test for values that can be exactly represented as a signed 32-bit integer.
-  vcvt_s32_f64(double_scratch.low(), double_input);
-  vmov(result, double_scratch.low());
-  vcvt_f64_s32(double_scratch, double_scratch.low());
-  VFPCompareAndSetFlags(double_input, double_scratch);
-  b(eq, &done);
+  TryFastDoubleToInt32(result, double_input, double_scratch, &done);

   // Convert to integer, respecting rounding mode.
   int32_t check_inexact_conversion =
@@ -2626,7 +2636,7 @@

 void MacroAssembler::EmitECMATruncate(Register result,
                                       DwVfpRegister double_input,
-                                      SwVfpRegister single_scratch,
+                                      DwVfpRegister double_scratch,
                                       Register scratch,
                                       Register input_high,
                                       Register input_low) {
@@ -2637,16 +2647,18 @@
   ASSERT(!scratch.is(result) &&
          !scratch.is(input_high) &&
          !scratch.is(input_low));
-  ASSERT(!single_scratch.is(double_input.low()) &&
-         !single_scratch.is(double_input.high()));
+  ASSERT(!double_input.is(double_scratch));

   Label done;

+ // Test for values that can be exactly represented as a signed 32-bit integer.
+  TryFastDoubleToInt32(result, double_input, double_scratch, &done);
+
   // Clear cumulative exception flags.
   ClearFPSCRBits(kVFPExceptionMask, scratch);
   // Try a conversion to a signed integer.
-  vcvt_s32_f64(single_scratch, double_input);
-  vmov(result, single_scratch);
+  vcvt_s32_f64(double_scratch.low(), double_input);
+  vmov(result, double_scratch.low());
   // Retrieve he FPSCR.
   vmrs(scratch);
   // Check for overflow and NaNs.
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.h Wed Dec 5 03:04:10 2012 +++ /branches/bleeding_edge/src/arm/macro-assembler-arm.h Fri Dec 7 03:29:27 2012
@@ -959,6 +959,14 @@
                       DwVfpRegister double_scratch,
                       Label *not_int32);

+ // Try to convert a double to a signed 32-bit integer. If the double value
+  // can be exactly represented as an integer, the code jumps to 'done' and
+ // 'result' contains the integer value. Otherwise, the code falls through.
+  void TryFastDoubleToInt32(Register result,
+                            DwVfpRegister double_input,
+                            DwVfpRegister double_scratch,
+                            Label* done);
+
// Truncates a double using a specific rounding mode, and writes the value
   // to the result register.
   // Clears the z flag (ne condition) if an overflow occurs.
@@ -989,7 +997,7 @@
// Exits with 'result' holding the answer and all other registers clobbered.
   void EmitECMATruncate(Register result,
                         DwVfpRegister double_input,
-                        SwVfpRegister single_scratch,
+                        DwVfpRegister double_scratch,
                         Register scratch,
                         Register scratch2,
                         Register scratch3);
=======================================
--- /branches/bleeding_edge/src/arm/stub-cache-arm.cc Wed Dec 5 03:04:10 2012 +++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc Fri Dec 7 03:29:27 2012
@@ -3836,7 +3836,7 @@
         // not include -kHeapObjectTag into it.
         __ sub(r5, value, Operand(kHeapObjectTag));
         __ vldr(d0, r5, HeapNumber::kValueOffset);
-        __ EmitECMATruncate(r5, d0, s2, r6, r7, r9);
+        __ EmitECMATruncate(r5, d0, d1, r6, r7, r9);

         switch (elements_kind) {
           case EXTERNAL_BYTE_ELEMENTS:

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

Reply via email to