Chromium Code Reviews| Index: src/arm/lithium-codegen-arm.cc |
| =================================================================== |
| --- src/arm/lithium-codegen-arm.cc (revision 6591) |
| +++ src/arm/lithium-codegen-arm.cc (working copy) |
| @@ -2625,34 +2625,53 @@ |
| } |
| -void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { |
| - DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); |
| - Register result = ToRegister(instr->result()); |
| - Register prev_fpscr = ToRegister(instr->TempAt(0)); |
| - SwVfpRegister single_scratch = double_scratch0().low(); |
| - Register scratch = scratch0(); |
| +// Truncates a double using a specific rounding mode. |
| +// Clears the z flag (ne condition) if an overflow occurs. |
| +void LCodeGen::EmitVFPTruncate(VFPRoundingMode rounding_mode, |
| + SwVfpRegister result, |
| + DwVfpRegister double_input, |
| + Register scratch1, |
| + Register scratch2) { |
| + Register prev_fpscr = scratch1; |
| + Register scratch = scratch2; |
| // Set custom FPCSR: |
| - // - Set rounding mode to "Round towards Minus Infinity". |
| + // - 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 | kVFPRoundingModeMask | kVFPFlushToZeroMask)); |
| - __ orr(scratch, scratch, Operand(kVFPRoundToMinusInfinityBits)); |
| + __ bic(scratch, prev_fpscr, Operand(kVFPExceptionMask | |
| + kVFPRoundingModeMask | |
| + kVFPFlushToZeroMask)); |
| + __ orr(scratch, scratch, Operand(rounding_mode)); |
| __ vmsr(scratch); |
| // Convert the argument to an integer. |
| - __ vcvt_s32_f64(single_scratch, |
| - input, |
| - Assembler::FPSCRRounding, |
| - al); |
| + __ vcvt_s32_f64(result, |
| + double_input, |
| + kFPSCRRounding); |
| - // Retrieve FPSCR and check for vfp exceptions. |
| + // Retrieve FPSCR. |
| __ vmrs(scratch); |
| - // Restore FPSCR |
| + // Restore FPSCR. |
| __ vmsr(prev_fpscr); |
| + // Check for vfp exceptions. |
| __ tst(scratch, Operand(kVFPExceptionMask)); |
| +} |
| + |
| + |
| +void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { |
| + DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); |
| + Register result = ToRegister(instr->result()); |
| + SwVfpRegister single_scratch = double_scratch0().low(); |
| + Register scratch1 = scratch0(); |
| + Register scratch2 = ToRegister(instr->TempAt(0)); |
| + |
| + EmitVFPTruncate(kRoundToMinusInf, |
|
Søren Thygesen Gjesse
2011/02/03 09:07:17
To much indentation.
Rodolph Perfetta
2011/02/03 15:03:39
Done.
|
| + single_scratch, |
| + input, |
| + scratch1, |
| + scratch2); |
| DeoptimizeIf(ne, instr->environment()); |
| // Move the result back to general purpose register r0. |
| @@ -2662,8 +2681,8 @@ |
| Label done; |
| __ cmp(result, Operand(0)); |
| __ b(ne, &done); |
| - __ vmov(scratch, input.high()); |
| - __ tst(scratch, Operand(HeapNumber::kSignMask)); |
| + __ vmov(scratch1, input.high()); |
| + __ tst(scratch1, Operand(HeapNumber::kSignMask)); |
| DeoptimizeIf(ne, instr->environment()); |
| __ bind(&done); |
| } |
| @@ -3297,7 +3316,43 @@ |
| void LCodeGen::DoDoubleToI(LDoubleToI* instr) { |
| - Abort("DoDoubleToI unimplemented."); |
| + LOperand* input = instr->InputAt(0); |
| + ASSERT(input->IsDoubleRegister()); |
| + LOperand* result = instr->result(); |
| + ASSERT(result->IsRegister()); |
| + |
| + DoubleRegister double_input = ToDoubleRegister(input); |
| + Register result_reg = ToRegister(result); |
| + SwVfpRegister single_scratch = double_scratch0().low(); |
| + Register scratch1 = scratch0(); |
| + Register scratch2 = ToRegister(instr->TempAt(0)); |
| + |
| + VFPRoundingMode rounding_mode = instr->truncating() ? kRoundToMinusInf |
| + : kRoundToNearest; |
| + |
| + |
| + EmitVFPTruncate(rounding_mode, |
|
Søren Thygesen Gjesse
2011/02/03 09:07:17
Indentation.
Rodolph Perfetta
2011/02/03 15:03:39
Done.
|
| + single_scratch, |
| + double_input, |
| + scratch1, |
| + scratch2); |
| + // Deoptimize if we had a vfp invalid exception. |
| + DeoptimizeIf(ne, instr->environment()); |
| + // Retrieve the result. |
| + __ vmov(result_reg, single_scratch); |
| + |
| + if (instr->truncating() && |
| + instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| + Label done; |
| + __ cmp(result_reg, Operand(0)); |
| + __ b(ne, &done); |
| + // Check for -0. |
| + __ vmov(scratch1, double_input.high()); |
| + __ tst(scratch1, Operand(HeapNumber::kSignMask)); |
| + DeoptimizeIf(ne, instr->environment()); |
| + |
|
Søren Thygesen Gjesse
2011/02/03 09:07:17
Indentation.
Rodolph Perfetta
2011/02/03 15:03:39
Done.
|
| + __ bind(&done); |
| + } |
| } |