Index: src/mips/code-stubs-mips.cc |
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc |
index 93f3fdec7aaa29997f17861aedcf4277d4f2ef4c..ff157389b04aab286965791132e4091202a157a2 100644 |
--- a/src/mips/code-stubs-mips.cc |
+++ b/src/mips/code-stubs-mips.cc |
@@ -567,10 +567,80 @@ void DoubleToIStub::Generate(MacroAssembler* masm) { |
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 @@ void BinaryOpStub_GenerateFPOperation(MacroAssembler* masm, |
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 @@ void BinaryOpStub_GenerateFPOperation(MacroAssembler* masm, |
__ 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) { |