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,
- ¬_in_int32_range);
- jmp(&done);
-
- bind(¬_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.