Revision: 16505
Author:   [email protected]
Date:     Tue Sep  3 11:39:19 2013 UTC
Log: MIPS: Improve TruncateNumberToI implementation after DoubleToIStub usage (r16461).

Using TruncateHeapNumberToI here simplifies the code and we get rid of ConvertToInt32 and EmitOutOfInt32RangeTruncate macro assembler instructions.

BUG=

Review URL: https://codereview.chromium.org/23444033
Patch from Balazs Kilvady <[email protected]>.
http://code.google.com/p/v8/source/detail?r=16505

Modified:
 /branches/bleeding_edge/src/mips/code-stubs-mips.cc
 /branches/bleeding_edge/src/mips/macro-assembler-mips.cc
 /branches/bleeding_edge/src/mips/macro-assembler-mips.h

=======================================
--- /branches/bleeding_edge/src/mips/code-stubs-mips.cc Sun Sep 1 17:22:08 2013 UTC +++ /branches/bleeding_edge/src/mips/code-stubs-mips.cc Tue Sep 3 11:39:19 2013 UTC
@@ -567,10 +567,80 @@
   Register input_low = scratch3;
   __ Move(input_low, input_high, double_input);

-  __ EmitOutOfInt32RangeTruncate(result_reg,
-                                 input_high,
-                                 input_low,
-                                 scratch);
+  Label normal_exponent, restore_sign;
+  // Extract the biased exponent in result.
+  __ Ext(result_reg,
+         input_high,
+         HeapNumber::kExponentShift,
+         HeapNumber::kExponentBits);
+
+  // Check for Infinity and NaNs, which should return 0.
+  __ Subu(scratch, result_reg, HeapNumber::kExponentMask);
+  __ Movz(result_reg, zero_reg, scratch);
+  __ Branch(&done, eq, scratch, Operand(zero_reg));
+
+  // Express exponent as delta to (number of mantissa bits + 31).
+  __ Subu(result_reg,
+          result_reg,
+ Operand(HeapNumber::kExponentBias + HeapNumber::kMantissaBits + 31));
+
+  // If the delta is strictly positive, all bits would be shifted away,
+  // which means that we can return 0.
+  __ Branch(&normal_exponent, le, result_reg, Operand(zero_reg));
+  __ mov(result_reg, zero_reg);
+  __ Branch(&done);
+
+  __ bind(&normal_exponent);
+  const int kShiftBase = HeapNumber::kNonMantissaBitsInTopWord - 1;
+  // Calculate shift.
+ __ Addu(scratch, result_reg, Operand(kShiftBase + HeapNumber::kMantissaBits));
+
+  // Save the sign.
+  Register sign = result_reg;
+  result_reg = no_reg;
+  __ And(sign, input_high, Operand(HeapNumber::kSignMask));
+
+ // On ARM shifts > 31 bits are valid and will result in zero. On MIPS we need
+  // to check for this specific case.
+  Label high_shift_needed, high_shift_done;
+  __ Branch(&high_shift_needed, lt, scratch, Operand(32));
+  __ mov(input_high, zero_reg);
+  __ Branch(&high_shift_done);
+  __ bind(&high_shift_needed);
+
+  // Set the implicit 1 before the mantissa part in input_high.
+  __ Or(input_high,
+        input_high,
+        Operand(1 << HeapNumber::kMantissaBitsInTopWord));
+  // Shift the mantissa bits to the correct position.
+  // We don't need to clear non-mantissa bits as they will be shifted away.
+  // If they weren't, it would mean that the answer is in the 32bit range.
+  __ sllv(input_high, input_high, scratch);
+
+  __ bind(&high_shift_done);
+
+  // Replace the shifted bits with bits from the lower mantissa word.
+  Label pos_shift, shift_done;
+  __ li(at, 32);
+  __ subu(scratch, at, scratch);
+  __ Branch(&pos_shift, ge, scratch, Operand(zero_reg));
+
+  // Negate scratch.
+  __ Subu(scratch, zero_reg, scratch);
+  __ sllv(input_low, input_low, scratch);
+  __ Branch(&shift_done);
+
+  __ bind(&pos_shift);
+  __ srlv(input_low, input_low, scratch);
+
+  __ bind(&shift_done);
+  __ Or(input_high, input_high, Operand(input_low));
+  // Restore sign if necessary.
+  __ mov(scratch, sign);
+  result_reg = sign;
+  sign = no_reg;
+  __ Subu(result_reg, zero_reg, input_high);
+  __ Movz(result_reg, input_high, scratch);

   __ bind(&done);

@@ -1486,7 +1556,6 @@
   Register right = a0;
   Register scratch1 = t3;
   Register scratch2 = t5;
-  Register scratch3 = t0;

   ASSERT(smi_operands || (not_numbers != NULL));
   if (smi_operands) {
@@ -1590,12 +1659,8 @@
         __ SmiUntag(a2, right);
       } else {
         // Convert operands to 32-bit integers. Right in a2 and left in a3.
-        __ TruncateNumberToI(
-            left, a3, heap_number_map,
-            scratch1, scratch2, scratch3, not_numbers);
-        __ TruncateNumberToI(
-            right, a2, heap_number_map,
-            scratch1, scratch2, scratch3, not_numbers);
+ __ TruncateNumberToI(left, a3, heap_number_map, scratch1, not_numbers); + __ TruncateNumberToI(right, a2, heap_number_map, scratch1, not_numbers);
       }
       Label result_not_a_smi;
       switch (op) {
=======================================
--- /branches/bleeding_edge/src/mips/macro-assembler-mips.cc Sun Sep 1 17:22:08 2013 UTC +++ /branches/bleeding_edge/src/mips/macro-assembler-mips.cc Tue Sep 3 11:39:19 2013 UTC
@@ -1296,60 +1296,6 @@
     clz(rd, rs);
   }
 }
-
-
-// Tries to get a signed int32 out of a double precision floating point heap -// number. Rounds towards 0. Branch to 'not_int32' if the double is out of the
-// 32bits signed integer range.
-// This method implementation differs from the ARM version for performance
-// reasons.
-void MacroAssembler::ConvertToInt32(Register source,
-                                    Register dest,
-                                    Register scratch,
-                                    Register scratch2,
-                                    FPURegister double_scratch,
-                                    Label *not_int32) {
-  Label right_exponent, done;
-  // Get exponent word (ENDIAN issues).
-  lw(scratch, FieldMemOperand(source, HeapNumber::kExponentOffset));
-  // Get exponent alone in scratch2.
-  And(scratch2, scratch, Operand(HeapNumber::kExponentMask));
-  // Load dest with zero.  We use this either for the final shift or
-  // for the answer.
-  mov(dest, zero_reg);
- // Check whether the exponent matches a 32 bit signed int that is not a Smi. - // A non-Smi integer is 1.xxx * 2^30 so the exponent is 30 (biased). This is - // the exponent that we are fastest at and also the highest exponent we can
-  // handle here.
-  const uint32_t non_smi_exponent =
-      (HeapNumber::kExponentBias + 30) << HeapNumber::kExponentShift;
- // If we have a match of the int32-but-not-Smi exponent then skip some logic.
-  Branch(&right_exponent, eq, scratch2, Operand(non_smi_exponent));
-  // If the exponent is higher than that then go to not_int32 case.  This
-  // catches numbers that don't fit in a signed int32, infinities and NaNs.
-  Branch(not_int32, gt, scratch2, Operand(non_smi_exponent));
-
-  // We know the exponent is smaller than 30 (biased).  If it is less than
- // 0 (biased) then the number is smaller in magnitude than 1.0 * 2^0, i.e.
-  // it rounds to zero.
-  const uint32_t zero_exponent =
-      (HeapNumber::kExponentBias + 0) << HeapNumber::kExponentShift;
-  Subu(scratch2, scratch2, Operand(zero_exponent));
-  // Dest already has a Smi zero.
-  Branch(&done, lt, scratch2, Operand(zero_reg));
-  bind(&right_exponent);
-
-  // MIPS FPU instructions implementing double precision to integer
-  // conversion using round to zero. Since the FP value was qualified
-  // above, the resulting integer should be a legal int32.
-  // The original 'Exponent' word is still in scratch.
- lwc1(double_scratch, FieldMemOperand(source, HeapNumber::kMantissaOffset));
-  mtc1(scratch, FPURegister::from_code(double_scratch.code() + 1));
-  trunc_w_d(double_scratch, double_scratch);
-  mfc1(dest, double_scratch);
-
-  bind(&done);
-}


 void MacroAssembler::EmitFPUTruncate(FPURoundingMode rounding_mode,
@@ -1414,88 +1360,6 @@

   bind(&done);
 }
-
-
-void MacroAssembler::EmitOutOfInt32RangeTruncate(Register result,
-                                                 Register input_high,
-                                                 Register input_low,
-                                                 Register scratch) {
-  Label done, normal_exponent, restore_sign;
-  // Extract the biased exponent in result.
-  Ext(result,
-      input_high,
-      HeapNumber::kExponentShift,
-      HeapNumber::kExponentBits);
-
-  // Check for Infinity and NaNs, which should return 0.
-  Subu(scratch, result, HeapNumber::kExponentMask);
-  Movz(result, zero_reg, scratch);
-  Branch(&done, eq, scratch, Operand(zero_reg));
-
-  // Express exponent as delta to (number of mantissa bits + 31).
-  Subu(result,
-       result,
- Operand(HeapNumber::kExponentBias + HeapNumber::kMantissaBits + 31));
-
-  // If the delta is strictly positive, all bits would be shifted away,
-  // which means that we can return 0.
-  Branch(&normal_exponent, le, result, Operand(zero_reg));
-  mov(result, zero_reg);
-  Branch(&done);
-
-  bind(&normal_exponent);
-  const int kShiftBase = HeapNumber::kNonMantissaBitsInTopWord - 1;
-  // Calculate shift.
-  Addu(scratch, result, Operand(kShiftBase + HeapNumber::kMantissaBits));
-
-  // Save the sign.
-  Register sign = result;
-  result = no_reg;
-  And(sign, input_high, Operand(HeapNumber::kSignMask));
-
- // On ARM shifts > 31 bits are valid and will result in zero. On MIPS we need
-  // to check for this specific case.
-  Label high_shift_needed, high_shift_done;
-  Branch(&high_shift_needed, lt, scratch, Operand(32));
-  mov(input_high, zero_reg);
-  Branch(&high_shift_done);
-  bind(&high_shift_needed);
-
-  // Set the implicit 1 before the mantissa part in input_high.
-  Or(input_high,
-     input_high,
-     Operand(1 << HeapNumber::kMantissaBitsInTopWord));
-  // Shift the mantissa bits to the correct position.
-  // We don't need to clear non-mantissa bits as they will be shifted away.
-  // If they weren't, it would mean that the answer is in the 32bit range.
-  sllv(input_high, input_high, scratch);
-
-  bind(&high_shift_done);
-
-  // Replace the shifted bits with bits from the lower mantissa word.
-  Label pos_shift, shift_done;
-  li(at, 32);
-  subu(scratch, at, scratch);
-  Branch(&pos_shift, ge, scratch, Operand(zero_reg));
-
-  // Negate scratch.
-  Subu(scratch, zero_reg, scratch);
-  sllv(input_low, input_low, scratch);
-  Branch(&shift_done);
-
-  bind(&pos_shift);
-  srlv(input_low, input_low, scratch);
-
-  bind(&shift_done);
-  Or(input_high, input_high, Operand(input_low));
-  // Restore sign if necessary.
-  mov(scratch, sign);
-  result = sign;
-  sign = no_reg;
-  Subu(result, zero_reg, input_high);
-  Movz(result, input_high, scratch);
-  bind(&done);
-}


 void MacroAssembler::TryInlineTruncateDoubleToI(Register result,
@@ -1570,31 +1434,14 @@
 void MacroAssembler::TruncateNumberToI(Register object,
                                        Register result,
                                        Register heap_number_map,
-                                       Register scratch1,
-                                       Register scratch2,
-                                       Register scratch3,
+                                       Register scratch,
                                        Label* not_number) {
   Label done;
-  Label not_in_int32_range;
-  DoubleRegister double_scratch = f12;
+  ASSERT(!result.is(object));

   UntagAndJumpIfSmi(result, object, &done);
-  JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number);
-  ConvertToInt32(object,
-                 result,
-                 scratch1,
-                 scratch2,
-                 double_scratch,
-                 &not_in_int32_range);
-  jmp(&done);
-
-  bind(&not_in_int32_range);
-  lw(scratch1, FieldMemOperand(object, HeapNumber::kExponentOffset));
-  lw(scratch2, FieldMemOperand(object, HeapNumber::kMantissaOffset));
-  EmitOutOfInt32RangeTruncate(result,
-                              scratch1,
-                              scratch2,
-                              scratch3);
+  JumpIfNotHeapNumber(object, heap_number_map, scratch, not_number);
+  TruncateHeapNumberToI(result, object);

   bind(&done);
 }
=======================================
--- /branches/bleeding_edge/src/mips/macro-assembler-mips.h Sun Sep 1 17:22:08 2013 UTC +++ /branches/bleeding_edge/src/mips/macro-assembler-mips.h Tue Sep 3 11:39:19 2013 UTC
@@ -758,17 +758,6 @@
     BranchF(target, nan, cc, cmp1, cmp2, bd);
   };

-  // Convert the HeapNumber pointed to by source to a 32bits signed integer
- // dest. If the HeapNumber does not fit into a 32bits signed integer branch
-  // to not_int32 label. If FPU is available double_scratch is used but not
-  // scratch2.
-  void ConvertToInt32(Register source,
-                      Register dest,
-                      Register scratch,
-                      Register scratch2,
-                      FPURegister double_scratch,
-                      Label *not_int32);
-
// Truncates a double using a specific rounding mode, and writes the value
   // to the result register.
   // The except_flag will contain any exceptions caused by the instruction.
@@ -783,17 +772,6 @@
                        CheckForInexactConversion check_inexact
                            = kDontCheckForInexactConversion);

-  // Helper for EmitECMATruncate.
-  // This will truncate a floating-point value outside of the singed 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'.
-  // Note that this code does not work for values in the 32bit range!
-  void EmitOutOfInt32RangeTruncate(Register result,
-                                   Register input_high,
-                                   Register input_low,
-                                   Register scratch);
-
   // Performs a truncating conversion of a floating point number as used by
// the JS bitwise operations. See ECMA-262 9.5: ToInt32. Goes to 'done' if it
   // succeeds, otherwise falls through if result is saturated. On return
@@ -821,9 +799,7 @@
   void TruncateNumberToI(Register object,
                          Register result,
                          Register heap_number_map,
-                         Register scratch1,
-                         Register scratch2,
-                         Register scratch3,
+                         Register scratch,
                          Label* not_int32);

   // Loads the number from object into dst register.

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to