Split and replace the EmitVFPTruncate routine to only do what is needed. Floor
authorrodolph.perfetta@gmail.com <rodolph.perfetta@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 5 Mar 2013 19:35:59 +0000 (19:35 +0000)
committerrodolph.perfetta@gmail.com <rodolph.perfetta@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 5 Mar 2013 19:35:59 +0000 (19:35 +0000)
and Round have been rewritten to use the default rounding mode.

BUG=none
TEST=none

Review URL: https://codereview.chromium.org/12393008

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

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

index cf8fd6a..93dda9d 100644 (file)
@@ -891,13 +891,7 @@ void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm,
     __ sub(scratch1, object, Operand(kHeapObjectTag));
     __ vldr(double_dst, scratch1, HeapNumber::kValueOffset);
 
-    __ EmitVFPTruncate(kRoundToZero,
-                       scratch1,
-                       double_dst,
-                       scratch2,
-                       double_scratch,
-                       kCheckForInexactConversion);
-
+    __ TestDoubleIsInt32(double_dst, double_scratch);
     // Jump to not_int32 if the operation did not succeed.
     __ b(ne, not_int32);
 
@@ -989,13 +983,7 @@ void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm,
     __ sub(scratch1, object, Operand(kHeapObjectTag));
     __ vldr(double_scratch0, scratch1, HeapNumber::kValueOffset);
 
-    __ EmitVFPTruncate(kRoundToZero,
-                       dst,
-                       double_scratch0,
-                       scratch1,
-                       double_scratch1,
-                       kCheckForInexactConversion);
-
+    __ TryDoubleToInt32Exact(dst, double_scratch0, double_scratch1);
     // Jump to not_int32 if the operation did not succeed.
     __ b(ne, not_int32);
   } else {
@@ -3094,16 +3082,14 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
           // Otherwise return a heap number if allowed, or jump to type
           // transition.
 
-          __ EmitVFPTruncate(kRoundToZero,
-                             scratch1,
-                             d5,
-                             scratch2,
-                             d8);
-
           if (result_type_ <= BinaryOpIC::INT32) {
+            __ TryDoubleToInt32Exact(scratch1, d5, d8);
             // If the ne condition is set, result does
             // not fit in a 32-bit integer.
             __ b(ne, &transition);
+          } else {
+            __ vcvt_s32_f64(s8, d5);
+            __ vmov(scratch1, s8);
           }
 
           // Check if the result fits in a smi.
index 34f5939..6fd9797 100644 (file)
@@ -3934,25 +3934,22 @@ void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
   CpuFeatureScope scope(masm(), VFP2);
   DwVfpRegister input = ToDoubleRegister(instr->value());
   Register result = ToRegister(instr->result());
-  Register scratch = scratch0();
+  Register input_high = scratch0();
+  Label done, exact;
 
-  __ EmitVFPTruncate(kRoundToMinusInf,
-                     result,
-                     input,
-                     scratch,
-                     double_scratch0());
-  DeoptimizeIf(ne, instr->environment());
+  __ vmov(input_high, input.high());
+  __ TryInt32Floor(result, input, input_high, double_scratch0(), &done, &exact);
+  DeoptimizeIf(al, instr->environment());
 
+  __ bind(&exact);
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
     // Test for -0.
-    Label done;
     __ cmp(result, Operand::Zero());
     __ b(ne, &done);
-    __ vmov(scratch, input.high());
-    __ tst(scratch, Operand(HeapNumber::kSignMask));
-    DeoptimizeIf(ne, instr->environment());
-    __ bind(&done);
+    __ cmp(input_high, Operand::Zero());
+    DeoptimizeIf(mi, instr->environment());
   }
+  __ bind(&done);
 }
 
 
@@ -3961,63 +3958,37 @@ void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
   DwVfpRegister input = ToDoubleRegister(instr->value());
   Register result = ToRegister(instr->result());
   DwVfpRegister double_scratch1 = ToDoubleRegister(instr->temp());
-  Register scratch = scratch0();
-  Label done, check_sign_on_zero;
-
-  // Extract exponent bits.
-  __ vmov(result, input.high());
-  __ ubfx(scratch,
-          result,
-          HeapNumber::kExponentShift,
-          HeapNumber::kExponentBits);
-
-  // If the number is in ]-0.5, +0.5[, the result is +/- 0.
-  __ cmp(scratch, Operand(HeapNumber::kExponentBias - 2));
-  __ mov(result, Operand::Zero(), LeaveCC, le);
-  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-    __ b(le, &check_sign_on_zero);
-  } else {
-    __ b(le, &done);
-  }
-
-  // The following conversion will not work with numbers
-  // outside of ]-2^32, 2^32[.
-  __ 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));
-
-  // 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());
-  __ eor(result, result, Operand(scratch), SetCC);
+  DwVfpRegister input_plus_dot_five = double_scratch1;
+  Register input_high = scratch0();
+  DwVfpRegister dot_five = double_scratch0();
+  Label convert, done;
+
+  __ Vmov(dot_five, 0.5, scratch0());
+  __ vabs(double_scratch1, input);
+  __ VFPCompareAndSetFlags(double_scratch1, dot_five);
+  // If input is in [-0.5, -0], the result is -0.
+  // If input is in [+0, +0.5[, the result is +0.
+  // If the input is +0.5, the result is 1.
+  __ b(hi, &convert);  // Out of [-0.5, +0.5].
   if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-    DeoptimizeIf(mi, instr->environment());
-  } else {
-    __ mov(result, Operand::Zero(), LeaveCC, mi);
-    __ b(mi, &done);
-  }
-
-  __ EmitVFPTruncate(kRoundToMinusInf,
-                     result,
-                     double_scratch0(),
-                     scratch,
-                     double_scratch1);
-  DeoptimizeIf(ne, instr->environment());
+    __ vmov(input_high, input.high());
+    __ cmp(input_high, Operand::Zero());
+    DeoptimizeIf(mi, instr->environment());  // [-0.5, -0].
+  }
+  __ VFPCompareAndSetFlags(input, dot_five);
+  __ mov(result, Operand(1), LeaveCC, eq);  // +0.5.
+  // Remaining cases: [+0, +0.5[ or [-0.5, +0.5[, depending on
+  // flag kBailoutOnMinusZero.
+  __ mov(result, Operand::Zero(), LeaveCC, ne);
+  __ b(&done);
 
-  if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
-    // Test for -0.
-    __ cmp(result, Operand::Zero());
-    __ b(ne, &done);
-    __ bind(&check_sign_on_zero);
-    __ vmov(scratch, input.high());
-    __ tst(scratch, Operand(HeapNumber::kSignMask));
-    DeoptimizeIf(ne, instr->environment());
-  }
+  __ bind(&convert);
+  __ vadd(input_plus_dot_five, input, dot_five);
+  __ vmov(input_high, input_plus_dot_five.high());
+  // Reuse dot_five (double_scratch0) as we no longer need this value.
+  __ TryInt32Floor(result, input_plus_dot_five, input_high, double_scratch0(),
+                   &done, &done);
+  DeoptimizeIf(al, instr->environment());
   __ bind(&done);
 }
 
@@ -5289,12 +5260,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
 
     __ sub(ip, input_reg, Operand(kHeapObjectTag));
     __ vldr(double_scratch, ip, HeapNumber::kValueOffset);
-    __ EmitVFPTruncate(kRoundToZero,
-                       input_reg,
-                       double_scratch,
-                       scratch1,
-                       double_scratch2,
-                       kCheckForInexactConversion);
+    __ TryDoubleToInt32Exact(input_reg, double_scratch, double_scratch2);
     DeoptimizeIf(ne, instr->environment());
 
     if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
@@ -5390,15 +5356,8 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
                         scratch2,
                         scratch3);
   } else {
-    __ EmitVFPTruncate(kRoundToMinusInf,
-                       result_reg,
-                       double_input,
-                       scratch1,
-                       double_scratch,
-                       kCheckForInexactConversion);
-
-    // Deoptimize if we had a vfp invalid exception,
-    // including inexact operation.
+    __ TryDoubleToInt32Exact(result_reg, double_input, double_scratch);
+    // Deoptimize if the input wasn't a int32 (inside a double).
     DeoptimizeIf(ne, instr->environment());
   }
     __ bind(&done);
index 400f615..2265d03 100644 (file)
@@ -2535,74 +2535,76 @@ void MacroAssembler::ConvertToInt32(Register source,
 }
 
 
-void MacroAssembler::TryFastDoubleToInt32(Register result,
-                                          DwVfpRegister double_input,
-                                          DwVfpRegister double_scratch,
-                                          Label* done) {
+void MacroAssembler::TestDoubleIsInt32(DwVfpRegister double_input,
+                                       DwVfpRegister double_scratch) {
   ASSERT(!double_input.is(double_scratch));
+  ASSERT(CpuFeatures::IsSupported(VFP2));
+  CpuFeatureScope scope(this, VFP2);
 
   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,
-                                     Register result,
-                                     DwVfpRegister double_input,
-                                     Register scratch,
-                                     DwVfpRegister double_scratch,
-                                     CheckForInexactConversion check_inexact) {
-  ASSERT(!result.is(scratch));
+void MacroAssembler::TryDoubleToInt32Exact(Register result,
+                                           DwVfpRegister double_input,
+                                           DwVfpRegister double_scratch) {
   ASSERT(!double_input.is(double_scratch));
-
   ASSERT(CpuFeatures::IsSupported(VFP2));
   CpuFeatureScope scope(this, VFP2);
-  Register prev_fpscr = result;
-  Label done;
-
-  // Test for values that can be exactly represented as a signed 32-bit integer.
-  TryFastDoubleToInt32(result, double_input, double_scratch, &done);
-
-  // Convert to integer, respecting rounding mode.
-  int32_t check_inexact_conversion =
-    (check_inexact == kCheckForInexactConversion) ? kVFPInexactExceptionBit : 0;
-
-  // Set custom FPCSR:
-  //  - Set rounding mode.
-  //  - Clear vfp cumulative exception flags.
-  //  - Make sure Flush-to-zero mode control bit is unset.
-  vmrs(prev_fpscr);
-  bic(scratch,
-      prev_fpscr,
-      Operand(kVFPExceptionMask |
-              check_inexact_conversion |
-              kVFPRoundingModeMask |
-              kVFPFlushToZeroMask));
-  // 'Round To Nearest' is encoded by 0b00 so no bits need to be set.
-  if (rounding_mode != kRoundToNearest) {
-    orr(scratch, scratch, Operand(rounding_mode));
-  }
-  vmsr(scratch);
-
-  // Convert the argument to an integer.
-  vcvt_s32_f64(double_scratch.low(),
-               double_input,
-               (rounding_mode == kRoundToZero) ? kDefaultRoundToZero
-                                               : kFPSCRRounding);
 
-  // Retrieve FPSCR.
-  vmrs(scratch);
-  // Restore FPSCR.
-  vmsr(prev_fpscr);
-  // Move the converted value into the result register.
+  vcvt_s32_f64(double_scratch.low(), double_input);
   vmov(result, double_scratch.low());
-  // Check for vfp exceptions.
-  tst(scratch, Operand(kVFPExceptionMask | check_inexact_conversion));
+  vcvt_f64_s32(double_scratch, double_scratch.low());
+  VFPCompareAndSetFlags(double_input, double_scratch);
+}
 
-  bind(&done);
+
+void MacroAssembler::TryInt32Floor(Register result,
+                                   DwVfpRegister double_input,
+                                   Register input_high,
+                                   DwVfpRegister double_scratch,
+                                   Label* done,
+                                   Label* exact) {
+  ASSERT(!result.is(input_high));
+  ASSERT(!double_input.is(double_scratch));
+  ASSERT(CpuFeatures::IsSupported(VFP2));
+  CpuFeatureScope scope(this, VFP2);
+  Label negative, exception;
+
+  // Test for NaN and infinities.
+  Sbfx(result, input_high,
+       HeapNumber::kExponentShift, HeapNumber::kExponentBits);
+  cmp(result, Operand(-1));
+  b(eq, &exception);
+  // Test for values that can be exactly represented as a
+  // signed 32-bit integer.
+  TryDoubleToInt32Exact(result, double_input, double_scratch);
+  // If exact, return (result already fetched).
+  b(eq, exact);
+  cmp(input_high, Operand::Zero());
+  b(mi, &negative);
+
+  // Input is in ]+0, +inf[.
+  // If result equals 0x7fffffff input was out of range or
+  // in ]0x7fffffff, 0x80000000[. We ignore this last case which
+  // could fits into an int32, that means we always think input was
+  // out of range and always go to exception.
+  // If result < 0x7fffffff, go to done, result fetched.
+  cmn(result, Operand(1));
+  b(mi, &exception);
+  b(done);
+
+  // Input is in ]-inf, -0[.
+  // If x is a non integer negative number,
+  // floor(x) <=> round_to_zero(x) - 1.
+  bind(&negative);
+  sub(result, result, Operand(1), SetCC);
+  // If result is still negative, go to done, result fetched.
+  // Else, we had an overflow and we fall through exception.
+  b(mi, done);
+  bind(&exception);
 }
 
 
@@ -2697,33 +2699,25 @@ void MacroAssembler::EmitECMATruncate(Register result,
   Label done;
 
   // Test if the value can be exactly represented as a signed integer.
-  vcvt_s32_f64(double_scratch.low(), double_input);
-  vmov(result, double_scratch.low());
-  vcvt_f64_s32(double_scratch, double_scratch.low());
-  // Note: this comparison is cheaper than reading the FPSCR exception bits.
-  VFPCompareAndSetFlags(double_input, double_scratch);
+  TryDoubleToInt32Exact(result, double_input, double_scratch);
   b(eq, &done);
 
   // Check the exception flags. If they are not set, we are done.
   // If they are set, it could be because of the conversion above, or because
   // they were set before this code.
   vmrs(scratch);
-  tst(scratch, Operand(kVFPOverflowExceptionBit |
-                       kVFPUnderflowExceptionBit |
-                       kVFPInvalidOpExceptionBit));
+  tst(scratch, Operand(kVFPInvalidOpExceptionBit));
   b(eq, &done);
 
   // Clear cumulative exception flags.
-  bic(scratch, scratch, Operand(kVFPExceptionMask));
+  bic(scratch, scratch, Operand(kVFPInvalidOpExceptionBit));
   vmsr(scratch);
   // Try a conversion to a signed integer.
   vcvt_s32_f64(double_scratch.low(), double_input);
   // Retrieve the FPSCR.
   vmrs(scratch);
-  // Check for overflow and NaNs.
-  tst(scratch, Operand(kVFPOverflowExceptionBit |
-                       kVFPUnderflowExceptionBit |
-                       kVFPInvalidOpExceptionBit));
+  // Check for invalid conversions (out of range and NaNs).
+  tst(scratch, Operand(kVFPInvalidOpExceptionBit));
   // If we had no exceptions we are done.
   b(eq, &done);
 
index 1fcd7a6..cf2f045 100644 (file)
@@ -944,27 +944,26 @@ class MacroAssembler: public Assembler {
                       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.
-  // 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,
-                       Register result,
-                       DwVfpRegister double_input,
-                       Register scratch,
-                       DwVfpRegister double_scratch,
-                       CheckForInexactConversion check
-                           = kDontCheckForInexactConversion);
+  // Check if a double can be exactly represented as a signed 32-bit integer.
+  // Z flag set to one if true.
+  void TestDoubleIsInt32(DwVfpRegister double_input,
+                         DwVfpRegister double_scratch);
+
+  // Try to convert a double to a signed 32-bit integer.
+  // Z flag set to one and result assigned if the conversion is exact.
+  void TryDoubleToInt32Exact(Register result,
+                             DwVfpRegister double_input,
+                             DwVfpRegister double_scratch);
+
+  // Floor a double and writes the value to the result register.
+  // Go to exact if the conversion is exact (to be able to test -0),
+  // fall through calling code if an overflow occurred, else go to done.
+  void TryInt32Floor(Register result,
+                     DwVfpRegister double_input,
+                     Register input_high,
+                     DwVfpRegister double_scratch,
+                     Label* done,
+                     Label* exact);
 
   // Helper for EmitECMATruncate.
   // This will truncate a floating-point value outside of the signed 32bit
index 80be94c..a01b81b 100644 (file)
@@ -2151,10 +2151,7 @@ Handle<Code> CallStubCompiler::CompileMathFloorCall(
 
   __ CheckMap(r0, r1, Heap::kHeapNumberMapRootIndex, &slow, DONT_DO_SMI_CHECK);
 
-  Label wont_fit_smi, no_vfp_exception, restore_fpscr_and_return;
-
-  // If vfp3 is enabled, we use the fpu rounding with the RM (round towards
-  // minus infinity) mode.
+  Label smi_check, just_return;
 
   // Load the HeapNumber value.
   // We will need access to the value in the core registers, so we load it
@@ -2164,73 +2161,46 @@ Handle<Code> CallStubCompiler::CompileMathFloorCall(
   __ Ldrd(r4, r5, FieldMemOperand(r0, HeapNumber::kValueOffset));
   __ vmov(d1, r4, r5);
 
-  // Backup FPSCR.
-  __ vmrs(r3);
-  // Set custom FPCSR:
-  //  - Set rounding mode to "Round towards Minus Infinity"
-  //    (i.e. bits [23:22] = 0b10).
-  //  - Clear vfp cumulative exception flags (bits [3:0]).
-  //  - Make sure Flush-to-zero mode control bit is unset (bit 22).
-  __ bic(r9, r3,
-      Operand(kVFPExceptionMask | kVFPRoundingModeMask | kVFPFlushToZeroMask));
-  __ orr(r9, r9, Operand(kRoundToMinusInf));
-  __ vmsr(r9);
-
-  // Convert the argument to an integer.
-  __ vcvt_s32_f64(s0, d1, kFPSCRRounding);
-
-  // Use vcvt latency to start checking for special cases.
-  // Get the argument exponent and clear the sign bit.
-  __ bic(r6, r5, Operand(HeapNumber::kSignMask));
-  __ mov(r6, Operand(r6, LSR, HeapNumber::kMantissaBitsInTopWord));
-
-  // Retrieve FPSCR and check for vfp exceptions.
-  __ vmrs(r9);
-  __ tst(r9, Operand(kVFPExceptionMask));
-  __ b(&no_vfp_exception, eq);
-
-  // Check for NaN, Infinity, and -Infinity.
+  // Check for NaN, Infinities and -0.
   // They are invariant through a Math.Floor call, so just
   // return the original argument.
-  __ sub(r7, r6, Operand(HeapNumber::kExponentMask
-        >> HeapNumber::kMantissaBitsInTopWord), SetCC);
-  __ b(&restore_fpscr_and_return, eq);
-  // We had an overflow or underflow in the conversion. Check if we
-  // have a big exponent.
-  __ cmp(r7, Operand(HeapNumber::kMantissaBits));
-  // If greater or equal, the argument is already round and in r0.
-  __ b(&restore_fpscr_and_return, ge);
-  __ b(&wont_fit_smi);
-
-  __ bind(&no_vfp_exception);
-  // Move the result back to general purpose register r0.
-  __ vmov(r0, s0);
-  // Check if the result fits into a smi.
+  __ Sbfx(r3, r5, HeapNumber::kExponentShift, HeapNumber::kExponentBits);
+  __ cmp(r3, Operand(-1));
+  __ b(eq, &just_return);
+  __ eor(r3, r5, Operand(0x80000000u));
+  __ orr(r3, r3, r4, SetCC);
+  __ b(eq, &just_return);
+  // Test for values that can be exactly represented as a
+  // signed 32-bit integer.
+  __ TryDoubleToInt32Exact(r0, d1, d2);
+  // If exact, check smi
+  __ b(eq, &smi_check);
+  __ cmp(r5, Operand(0));
+
+  // If input is in ]+0, +inf[, the cmp has cleared overflow and negative
+  // (V=0 and N=0), the two following instructions won't execute and
+  // we fall through smi_check to check if the result can fit into a smi.
+
+  // If input is in ]-inf, -0[, sub one and, go to slow if we have
+  // an overflow. Else we fall through smi check.
+  // Hint: if x is a negative, non integer number,
+  // floor(x) <=> round_to_zero(x) - 1.
+  __ sub(r0, r0, Operand(1), SetCC, mi);
+  __ b(vs, &slow);
+
+  __ bind(&smi_check);
+  // Check if the result can fit into an smi. If we had an overflow,
+  // the result is either 0x80000000 or 0x7FFFFFFF and won't fit into an smi.
   __ add(r1, r0, Operand(0x40000000), SetCC);
-  __ b(&wont_fit_smi, mi);
+  // If result doesn't fit into an smi, branch to slow.
+  __ b(&slow, mi);
   // Tag the result.
-  STATIC_ASSERT(kSmiTag == 0);
   __ mov(r0, Operand(r0, LSL, kSmiTagSize));
 
-  // Check for -0.
-  __ cmp(r0, Operand::Zero());
-  __ b(&restore_fpscr_and_return, ne);
-  // r5 already holds the HeapNumber exponent.
-  __ tst(r5, Operand(HeapNumber::kSignMask));
-  // If our HeapNumber is negative it was -0, so load its address and return.
-  // Else r0 is loaded with 0, so we can also just return.
-  __ ldr(r0, MemOperand(sp, 0 * kPointerSize), ne);
-
-  __ bind(&restore_fpscr_and_return);
-  // Restore FPSCR and return.
-  __ vmsr(r3);
+  __ bind(&just_return);
   __ Drop(argc + 1);
   __ Ret();
 
-  __ bind(&wont_fit_smi);
-  // Restore FPCSR and fall to slow case.
-  __ vmsr(r3);
-
   __ bind(&slow);
   // Tail call the full function. We do not have to patch the receiver
   // because the function makes no use of it.
@@ -3392,12 +3362,7 @@ static void GenerateSmiKeyCheck(MacroAssembler* masm,
                 DONT_DO_SMI_CHECK);
     __ sub(ip, key, Operand(kHeapObjectTag));
     __ vldr(double_scratch0, ip, HeapNumber::kValueOffset);
-    __ EmitVFPTruncate(kRoundToZero,
-                       scratch0,
-                       double_scratch0,
-                       scratch1,
-                       double_scratch1,
-                       kCheckForInexactConversion);
+    __ TryDoubleToInt32Exact(scratch0, double_scratch0, double_scratch1);
     __ b(ne, fail);
     __ TrySmiTag(scratch0, fail, scratch1);
     __ mov(key, scratch0);