Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Message from discussion r12676 committed - ARM: Fast path for integer inputs to EmitVFPTruncate...
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Followup To:
Add Cc | Add Followup-to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers you hear
 
codesite-nore...@google.com  
View profile  
 More options Oct 8 2012, 8:50 am
From: codesite-nore...@google.com
Date: Mon, 08 Oct 2012 12:50:31 +0000
Local: Mon, Oct 8 2012 8:50 am
Subject: [v8] r12676 committed - ARM: Fast path for integer inputs to EmitVFPTruncate...
Revision: 12676
Author:   da...@chromium.org
Date:     Mon Oct  8 05:50:15 2012
Log:      ARM: Fast path for integer inputs to EmitVFPTruncate

BUG=none
TEST=none

Review URL: https://codereview.chromium.org/11049025
Patch from Martyn Capewell <m.m.capew...@googlemail.com>.
http://code.google.com/p/v8/source/detail?r=12676

Modified:
  /branches/bleeding_edge/src/arm/code-stubs-arm.cc
  /branches/bleeding_edge/src/arm/code-stubs-arm.h
  /branches/bleeding_edge/src/arm/lithium-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/stub-cache-arm.cc

=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.cc   Thu Sep 27 04:31:26  
2012
+++ /branches/bleeding_edge/src/arm/code-stubs-arm.cc   Mon Oct  8 05:50:15  
2012
@@ -826,6 +826,7 @@
                                                    Register object,
                                                    Destination destination,
                                                    DwVfpRegister double_dst,
+                                                  DwVfpRegister  
double_scratch,
                                                    Register dst1,
                                                    Register dst2,
                                                    Register heap_number_map,
@@ -863,10 +864,10 @@
      __ vldr(double_dst, scratch1, HeapNumber::kValueOffset);

      __ EmitVFPTruncate(kRoundToZero,
-                       single_scratch,
+                       scratch1,
                         double_dst,
-                       scratch1,
                         scratch2,
+                       double_scratch,
                         kCheckForInexactConversion);

      // Jump to not_int32 if the operation did not succeed.
@@ -906,7 +907,8 @@
                                              Register scratch1,
                                              Register scratch2,
                                              Register scratch3,
-                                            DwVfpRegister double_scratch,
+                                            DwVfpRegister double_scratch0,
+                                            DwVfpRegister double_scratch1,
                                              Label* not_int32) {
    ASSERT(!dst.is(object));
    ASSERT(!scratch1.is(object) && !scratch2.is(object)  
&& !scratch3.is(object));
@@ -929,23 +931,20 @@
    // Convert the floating point value to a 32-bit integer.
    if (CpuFeatures::IsSupported(VFP2)) {
      CpuFeatures::Scope scope(VFP2);
-    SwVfpRegister single_scratch = double_scratch.low();
+
      // Load the double value.
      __ sub(scratch1, object, Operand(kHeapObjectTag));
-    __ vldr(double_scratch, scratch1, HeapNumber::kValueOffset);
+    __ vldr(double_scratch0, scratch1, HeapNumber::kValueOffset);

      __ EmitVFPTruncate(kRoundToZero,
-                       single_scratch,
-                       double_scratch,
+                       dst,
+                       double_scratch0,
                         scratch1,
-                       scratch2,
+                       double_scratch1,
                         kCheckForInexactConversion);

      // Jump to not_int32 if the operation did not succeed.
      __ b(ne, not_int32);
-    // Get the result in the destination register.
-    __ vmov(dst, single_scratch);
-
    } else {
      // Load the double value in the destination registers.
      __ ldr(scratch1, FieldMemOperand(object, HeapNumber::kExponentOffset));
@@ -2850,7 +2849,6 @@
    Register scratch1 = r7;
    Register scratch2 = r9;
    DwVfpRegister double_scratch = d0;
-  SwVfpRegister single_scratch = s3;

    Register heap_number_result = no_reg;
    Register heap_number_map = r6;
@@ -2888,6 +2886,7 @@
                                                     right,
                                                     destination,
                                                     d7,
+                                                   d8,
                                                     r2,
                                                     r3,
                                                     heap_number_map,
@@ -2899,6 +2898,7 @@
                                                     left,
                                                     destination,
                                                     d6,
+                                                   d8,
                                                     r4,
                                                     r5,
                                                     heap_number_map,
@@ -2934,10 +2934,10 @@
            // transition.

            __ EmitVFPTruncate(kRoundToZero,
-                             single_scratch,
+                             scratch1,
                               d5,
-                             scratch1,
-                             scratch2);
+                             scratch2,
+                             d8);

            if (result_type_ <= BinaryOpIC::INT32) {
              // If the ne condition is set, result does
@@ -2946,7 +2946,6 @@
            }

            // Check if the result fits in a smi.
-          __ vmov(scratch1, single_scratch);
            __ add(scratch2, scratch1, Operand(0x40000000), SetCC);
            // If not try to return a heap number.
            __ b(mi, &return_heap_number);
@@ -3041,6 +3040,7 @@
                                               scratch2,
                                               scratch3,
                                               d0,
+                                             d1,
                                               &transition);
        FloatingPointHelper::LoadNumberAsInt32(masm,
                                               right,
@@ -3050,6 +3050,7 @@
                                               scratch2,
                                               scratch3,
                                               d0,
+                                             d1,
                                               &transition);

        // The ECMA-262 standard specifies that, for shift operations, only  
the
=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.h    Wed Jul 25 08:26:16  
2012
+++ /branches/bleeding_edge/src/arm/code-stubs-arm.h    Mon Oct  8 05:50:15  
2012
@@ -773,6 +773,7 @@
                                        Register object,
                                        Destination destination,
                                        DwVfpRegister double_dst,
+                                      DwVfpRegister double_scratch,
                                        Register dst1,
                                        Register dst2,
                                        Register heap_number_map,
@@ -794,7 +795,8 @@
                                  Register scratch1,
                                  Register scratch2,
                                  Register scratch3,
-                                DwVfpRegister double_scratch,
+                                DwVfpRegister double_scratch0,
+                                DwVfpRegister double_scratch1,
                                  Label* not_int32);

    // Generate non VFP3 code to check if a double can be exactly  
represented by a
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc      Wed Sep 19 01:13:46 2012
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc      Mon Oct  8 05:50:15 2012
@@ -1040,7 +1040,8 @@
      return DefineFixedDouble(result, d2);
    } else {
      LOperand* input = UseRegisterAtStart(instr->value());
-    LOperand* temp = (op == kMathFloor) ? TempRegister() : NULL;
+
+    LOperand* temp = (op == kMathRound) ? FixedTemp(d3) : NULL;
      LUnaryMathOperation* result = new(zone()) LUnaryMathOperation(input,  
temp);
      switch (op) {
        case kMathAbs:
@@ -1616,8 +1617,7 @@
          LOperand* temp1 = TempRegister();
          LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister()
                                                        : NULL;
-        LOperand* temp3 = instr->CanTruncateToInt32() ? FixedTemp(d11)
-                                                      : NULL;
+        LOperand* temp3 = FixedTemp(d11);
          res = DefineSameAsFirst(new(zone()) LTaggedToI(value,
                                                         temp1,
                                                         temp2,
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc      Tue Oct  2  
09:48:45 2012
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc      Mon Oct  8  
05:50:15 2012
@@ -3499,27 +3499,22 @@
  void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
    DoubleRegister input = ToDoubleRegister(instr->value());
    Register result = ToRegister(instr->result());
-  SwVfpRegister single_scratch = double_scratch0().low();
-  Register scratch1 = scratch0();
-  Register scratch2 = ToRegister(instr->temp());
+  Register scratch = scratch0();

    __ EmitVFPTruncate(kRoundToMinusInf,
-                     single_scratch,
+                     result,
                       input,
-                     scratch1,
-                     scratch2);
+                     scratch,
+                     double_scratch0());
    DeoptimizeIf(ne, instr->environment());

-  // Move the result back to general purpose register r0.
-  __ vmov(result, single_scratch);
-
    if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
      // Test for -0.
      Label done;
      __ cmp(result, Operand(0));
      __ b(ne, &done);
-    __ vmov(scratch1, input.high());
-    __ tst(scratch1, Operand(HeapNumber::kSignMask));
+    __ vmov(scratch, input.high());
+    __ tst(scratch, Operand(HeapNumber::kSignMask));
      DeoptimizeIf(ne, instr->environment());
      __ bind(&done);
    }
@@ -3529,6 +3524,7 @@
  void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
    DoubleRegister input = ToDoubleRegister(instr->value());
    Register result = ToRegister(instr->result());
+  DwVfpRegister double_scratch1 = ToDoubleRegister(instr->temp());
    Register scratch = scratch0();
    Label done, check_sign_on_zero;

@@ -3571,12 +3567,11 @@
    }

    __ EmitVFPTruncate(kRoundToMinusInf,
-                     double_scratch0().low(),
+                     result,
                       double_scratch0(),
-                     result,
-                     scratch);
+                     scratch,
+                     double_scratch1);
    DeoptimizeIf(ne, instr->environment());
-  __ vmov(result, double_scratch0().low());

    if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
      // Test for -0.
@@ -4602,7 +4597,7 @@
    Register scratch1 = scratch0();
    Register scratch2 = ToRegister(instr->temp());
    DwVfpRegister double_scratch = double_scratch0();
-  SwVfpRegister single_scratch = double_scratch.low();
+  DwVfpRegister double_scratch2 = ToDoubleRegister(instr->temp3());

    ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2));
    ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1));
@@ -4622,7 +4617,7 @@

    if (instr->truncating()) {
      Register scratch3 = ToRegister(instr->temp2());
-    DwVfpRegister double_scratch2 = ToDoubleRegister(instr->temp3());
+    SwVfpRegister single_scratch = double_scratch.low();
      ASSERT(!scratch3.is(input_reg) &&
             !scratch3.is(scratch1) &&
             !scratch3.is(scratch2));
@@ -4657,14 +4652,12 @@
      __ sub(ip, input_reg, Operand(kHeapObjectTag));
      __ vldr(double_scratch, ip, HeapNumber::kValueOffset);
      __ EmitVFPTruncate(kRoundToZero,
-                       single_scratch,
+                       input_reg,
                         double_scratch,
                         scratch1,
-                       scratch2,
+                       double_scratch2,
                         kCheckForInexactConversion);
      DeoptimizeIf(ne, instr->environment());
-    // Load the result.
-    __ vmov(input_reg, single_scratch);

      if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
        __ cmp(input_reg, Operand(0));
@@ -4728,12 +4721,12 @@
    Register scratch1 = scratch0();
    Register scratch2 = ToRegister(instr->temp());
    DwVfpRegister double_input = ToDoubleRegister(instr->value());
-  SwVfpRegister single_scratch = double_scratch0().low();

    Label done;

    if (instr->truncating()) {
      Register scratch3 = ToRegister(instr->temp2());
+    SwVfpRegister single_scratch = double_scratch0().low();
      __ EmitECMATruncate(result_reg,
                          double_input,
                          single_scratch,
@@ -4741,18 +4734,17 @@
                          scratch2,
                          scratch3);
    } else {
-    VFPRoundingMode rounding_mode = kRoundToMinusInf;
-    __ EmitVFPTruncate(rounding_mode,
-                       single_scratch,
+    DwVfpRegister double_scratch = double_scratch0();
+    __ EmitVFPTruncate(kRoundToMinusInf,
+                       result_reg,
                         double_input,
                         scratch1,
-                       scratch2,
+                       double_scratch,
                         kCheckForInexactConversion);
+
      // Deoptimize if we had a vfp invalid exception,
      // including inexact operation.
      DeoptimizeIf(ne, instr->environment());
-    // Retrieve the result.
-    __ vmov(result_reg, single_scratch);
    }
      __ bind(&done);
  }
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc      Thu Sep 27  
00:45:49 2012
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc      Mon Oct  8  
05:50:15 2012
@@ -2437,16 +2437,27 @@

  void MacroAssembler::EmitVFPTruncate(VFPRoundingMode rounding_mode,
-                                     SwVfpRegister result,
+                                     Register result,
                                       DwVfpRegister double_input,
-                                     Register scratch1,
-                                     Register scratch2,
+                                     Register scratch,
+                                     DwVfpRegister double_scratch,
                                       CheckForInexactConversion  
check_inexact) {
+  ASSERT(!result.is(scratch));
+  ASSERT(!double_input.is(double_scratch));
+
    ASSERT(CpuFeatures::IsSupported(VFP2));
    CpuFeatures::Scope scope(VFP2);
-  Register prev_fpscr = scratch1;
-  Register scratch = scratch2;
+  Register prev_fpscr = result;
+  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);

+  // Convert to integer, respecting rounding mode.
    int32_t check_inexact_conversion =
      (check_inexact == kCheckForInexactConversion) ?  
kVFPInexactExceptionBit : 0;

@@ -2468,7 +2479,7 @@
    vmsr(scratch);

    // Convert the argument to an integer.
-  vcvt_s32_f64(result,
+  vcvt_s32_f64(double_scratch.low(),
                 double_input,
                 (rounding_mode == kRoundToZero) ? kDefaultRoundToZero
                                                 : kFPSCRRounding);
@@ -2477,8 +2488,12 @@
    vmrs(scratch);
    // Restore FPSCR.
    vmsr(prev_fpscr);
+  // Move the converted value into the result register.
+  vmov(result, double_scratch.low());
    // Check for vfp exceptions.
    tst(scratch, Operand(kVFPExceptionMask | check_inexact_conversion));
+
+  bind(&done);
  }

=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.h       Thu Sep 27  
00:45:49 2012
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.h       Mon Oct  8  
05:50:15 2012
@@ -939,21 +939,22 @@
                        DwVfpRegister double_scratch,
                        Label *not_int32);

-  // Truncates a double using a specific rounding mode.
+  // 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.
-  // If exact_conversion is true, the z flag is also cleared if the  
conversion
-  // was inexact, i.e. if the double value could not be converted exactly
-  // to a 32bit integer.
+  // If kCheckForInexactConversion is passed, the z flag is also cleared  
if the
+  // conversion was inexact, i.e. if the double value could not be  
converted
+  // exactly to a 32-bit integer.
    void EmitVFPTruncate(VFPRoundingMode rounding_mode,
-                       SwVfpRegister result,
+                       Register result,
                         DwVfpRegister double_input,
-                       Register scratch1,
-                       Register scratch2,
+                       Register scratch,
+                       DwVfpRegister double_scratch,
                         CheckForInexactConversion check
                             = kDontCheckForInexactConversion);

    // Helper for EmitECMATruncate.
-  // This will truncate a floating-point value outside of the singed 32bit
+  // This will truncate a floating-point value outside of the signed 32bit
    // integer range to a 32bit signed integer.
    // Expects the double value loaded in input_high and input_low.
    // Exits with the answer in 'result'.
=======================================
--- /branches/bleeding_edge/src/arm/stub-cache-arm.cc   Thu Sep 27 00:45:49  
2012
+++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc   Mon Oct  8 05:50:15  
2012
@@ -3646,6 +3646,7 @@
                                  Register scratch0,
                                  Register scratch1,
                                  DwVfpRegister double_scratch0,
+                                DwVfpRegister double_scratch1,
                                  Label* fail) {
    if (CpuFeatures::IsSupported(VFP2)) {
      CpuFeatures::Scope scope(VFP2);
@@ -3662,13 +3663,12 @@
      __ sub(ip, key, Operand(kHeapObjectTag));
      __ vldr(double_scratch0, ip, HeapNumber::kValueOffset);
      __ EmitVFPTruncate(kRoundToZero,
-                       double_scratch0.low(),
+                       scratch0,
                         double_scratch0,
-                       scratch0,
                         scratch1,
+                       double_scratch1,
                         kCheckForInexactConversion);
      __ b(ne, fail);
-    __ vmov(scratch0, double_scratch0.low());
      __ TrySmiTag(scratch0, fail, scratch1);
      __ mov(key, scratch0);
      __ bind(&key_ok);
@@ -3696,7 +3696,7 @@
    // have been verified by the caller to not be a smi.

    // Check that the key is a smi or a heap number convertible to a smi.
-  GenerateSmiKeyCheck(masm, key, r4, r5, d1, &miss_force_generic);
+  GenerateSmiKeyCheck(masm, key, r4, r5, d1, d2, &miss_force_generic);

    __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset));
    // r3: elements array
@@ -4030,7 +4030,7 @@
    // have been verified by the caller to not be a smi.

    // Check that the key is a smi or a heap number convertible to a smi.
-  GenerateSmiKeyCheck(masm, key, r4, r5, d1, &miss_force_generic);
+  GenerateSmiKeyCheck(masm, key, r4, r5, d1, d2, &miss_force_generic);

    __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset));

@@ -4365,7 +4365,7 @@
    // have been verified by the caller to not be a smi.

    // Check that the key is a smi or a heap number convertible to a smi.
-  GenerateSmiKeyCheck(masm, r0, r4, r5, d1, &miss_force_generic);
+  GenerateSmiKeyCheck(masm, r0, r4, r5, d1, d2, &miss_force_generic);

    // Get the elements array.
    __ ldr(r2, FieldMemOperand(r1, JSObject::kElementsOffset));
@@ -4417,7 +4417,7 @@
    // have been verified by the caller to not be a smi.

    // Check that the key is a smi or a heap number convertible to a smi.
-  GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, &miss_force_generic);
+  GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, d2, &miss_force_generic);

    // Get the elements array.
    __ ldr(elements_reg,
@@ -4493,7 +4493,7 @@
    // have been verified by the caller to not be a smi.

    // Check that the key is a smi or a heap number convertible to a smi.
-  GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, &miss_force_generic);
+  GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, d2, &miss_force_generic);

    if (IsFastSmiElementsKind(elements_kind)) {
      __ JumpIfNotSmi(value_reg, &transition_elements_kind);
@@ -4661,7 +4661,7 @@
    // have been verified by the caller to not be a smi.

    // Check that the key is a smi or a heap number convertible to a smi.
-  GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, &miss_force_generic);
+  GenerateSmiKeyCheck(masm, key_reg, r4, r5, d1, d2, &miss_force_generic);

    __ ldr(elements_reg,
           FieldMemOperand(receiver_reg, JSObject::kElementsOffset));


 
You must Sign in before you can post messages.
To post a message you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.