Chromium Code Reviews| Index: src/x64/lithium-codegen-x64.cc | 
| diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc | 
| index 202e7a24fcd239a7fe47aacf26ac24f9fce5b33a..9e7e228dadb9138f393f7319128329d8391dffad 100644 | 
| --- a/src/x64/lithium-codegen-x64.cc | 
| +++ b/src/x64/lithium-codegen-x64.cc | 
| @@ -2721,33 +2721,44 @@ void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { | 
| Register output_reg = ToRegister(instr->result()); | 
| XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); | 
| + Label done; | 
| // xmm_scratch = 0.5 | 
| __ movq(kScratchRegister, V8_INT64_C(0x3FE0000000000000), RelocInfo::NONE); | 
| __ movq(xmm_scratch, kScratchRegister); | 
| - | 
| + NearLabel below_half; | 
| + __ ucomisd(xmm_scratch, input_reg); | 
| + __ j(above, &below_half); // If input_reg is NaN, this doesn't jump. | 
| // input = input + 0.5 | 
| + // This addition might give a result that isn't the correct for | 
| + // rounding, due to loss of precission, but only for a number that's | 
| 
 
William Hesse
2011/04/13 09:12:45
precision
 
Lasse Reichstein
2011/04/13 09:35:23
Fixed, thanks.
 
 | 
| + // so big that the conversion below will overflow anyway. | 
| __ addsd(input_reg, xmm_scratch); | 
| + // Compute Math.floor(input). | 
| + // Use truncating instruction (OK because input is positive). | 
| + __ cvttsd2si(output_reg, input_reg); | 
| + // Overflow is signalled with minint. | 
| + __ cmpl(output_reg, Immediate(0x80000000)); | 
| + DeoptimizeIf(equal, instr->environment()); | 
| + __ jmp(&done); | 
| - // We need to return -0 for the input range [-0.5, 0[, otherwise | 
| - // compute Math.floor(value + 0.5). | 
| + __ bind(&below_half); | 
| if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| - __ ucomisd(input_reg, xmm_scratch); | 
| - DeoptimizeIf(below_equal, instr->environment()); | 
| + // Bailout if negative (including -0). | 
| + __ movq(output_reg, input_reg); | 
| + __ testq(output_reg, output_reg); | 
| + DeoptimizeIf(negative, instr->environment()); | 
| } else { | 
| - // If we don't need to bailout on -0, we check only bailout | 
| - // on negative inputs. | 
| - __ xorpd(xmm_scratch, xmm_scratch); // Zero the register. | 
| + // Bailout if below -0.5, otherwise round to (positive) zero, even | 
| + // if negative. | 
| + // xmm_scrach = -0.5 | 
| + __ movq(kScratchRegister, V8_INT64_C(0xBFE0000000000000), RelocInfo::NONE); | 
| + __ movq(xmm_scratch, kScratchRegister); | 
| __ ucomisd(input_reg, xmm_scratch); | 
| DeoptimizeIf(below, instr->environment()); | 
| } | 
| + __ xorl(output_reg, output_reg); | 
| - // Compute Math.floor(value + 0.5). | 
| - // Use truncating instruction (OK because input is positive). | 
| - __ cvttsd2si(output_reg, input_reg); | 
| - | 
| - // Overflow is signalled with minint. | 
| - __ cmpl(output_reg, Immediate(0x80000000)); | 
| - DeoptimizeIf(equal, instr->environment()); | 
| + __ bind(&done); | 
| } |