Index: src/mips/macro-assembler-mips.cc |
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc |
index 926b3bfbb4e690b8b43905ee72b8c94173581ec0..6105e716b598a703a230461e4742302379fcab43 100644 |
--- a/src/mips/macro-assembler-mips.cc |
+++ b/src/mips/macro-assembler-mips.cc |
@@ -1395,49 +1395,68 @@ void MacroAssembler::ConvertToInt32(Register source, |
void MacroAssembler::EmitFPUTruncate(FPURoundingMode rounding_mode, |
- FPURegister result, |
+ Register result, |
DoubleRegister double_input, |
- Register scratch1, |
+ Register scratch, |
+ DoubleRegister double_scratch, |
Register except_flag, |
CheckForInexactConversion check_inexact) { |
+ ASSERT(!result.is(scratch)); |
+ ASSERT(!double_input.is(double_scratch)); |
+ ASSERT(!except_flag.is(scratch)); |
+ |
ASSERT(CpuFeatures::IsSupported(FPU)); |
CpuFeatures::Scope scope(FPU); |
+ Label done; |
+ |
+ // Clear the except flag (0 = no exception) |
+ mov(except_flag, zero_reg); |
+ |
+ // Test for values that can be exactly represented as a signed 32-bit integer. |
+ cvt_w_d(double_scratch, double_input); |
+ mfc1(result, double_scratch); |
+ cvt_d_w(double_scratch, double_scratch); |
+ BranchF(&done, NULL, eq, double_input, double_scratch); |
int32_t except_mask = kFCSRFlagMask; // Assume interested in all exceptions. |
if (check_inexact == kDontCheckForInexactConversion) { |
- // Ingore inexact exceptions. |
+ // Ignore inexact exceptions. |
except_mask &= ~kFCSRInexactFlagMask; |
} |
// Save FCSR. |
- cfc1(scratch1, FCSR); |
+ cfc1(scratch, FCSR); |
// Disable FPU exceptions. |
ctc1(zero_reg, FCSR); |
// Do operation based on rounding mode. |
switch (rounding_mode) { |
case kRoundToNearest: |
- Round_w_d(result, double_input); |
+ Round_w_d(double_scratch, double_input); |
break; |
case kRoundToZero: |
- Trunc_w_d(result, double_input); |
+ Trunc_w_d(double_scratch, double_input); |
break; |
case kRoundToPlusInf: |
- Ceil_w_d(result, double_input); |
+ Ceil_w_d(double_scratch, double_input); |
break; |
case kRoundToMinusInf: |
- Floor_w_d(result, double_input); |
+ Floor_w_d(double_scratch, double_input); |
break; |
} // End of switch-statement. |
// Retrieve FCSR. |
cfc1(except_flag, FCSR); |
// Restore FCSR. |
- ctc1(scratch1, FCSR); |
+ ctc1(scratch, FCSR); |
+ // Move the converted value into the result register. |
+ mfc1(result, double_scratch); |
// Check for fpu exceptions. |
And(except_flag, except_flag, Operand(except_mask)); |
+ |
+ bind(&done); |
} |