| Index: src/x64/lithium-codegen-x64.cc
|
| diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
|
| index 57db277577ef3d9ca3258731893664add185809b..808c4d87355f3626d5829df45f62745d893f236c 100644
|
| --- a/src/x64/lithium-codegen-x64.cc
|
| +++ b/src/x64/lithium-codegen-x64.cc
|
| @@ -3031,7 +3031,6 @@ void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
|
| XMMRegister xmm_scratch = xmm0;
|
| Register output_reg = ToRegister(instr->result());
|
| XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
|
| - Label done;
|
|
|
| if (CpuFeatures::IsSupported(SSE4_1)) {
|
| CpuFeatures::Scope scope(SSE4_1);
|
| @@ -3046,10 +3045,13 @@ void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
|
| __ cmpl(output_reg, Immediate(0x80000000));
|
| DeoptimizeIf(equal, instr->environment());
|
| } else {
|
| + Label negative_sign, done;
|
| // Deoptimize on negative inputs.
|
| __ xorps(xmm_scratch, xmm_scratch); // Zero the register.
|
| __ ucomisd(input_reg, xmm_scratch);
|
| - DeoptimizeIf(below, instr->environment());
|
| + DeoptimizeIf(parity_even, instr->environment());
|
| + __ j(below, &negative_sign, Label::kNear);
|
| +
|
| if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
| // Check for negative zero.
|
| Label positive_sign;
|
| @@ -3064,12 +3066,23 @@ void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
|
|
|
| // 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, Label::kNear);
|
| +
|
| + // Non-zero negative reaches here.
|
| + __ bind(&negative_sign);
|
| + // Truncate, then compare and compensate.
|
| + __ cvttsd2si(output_reg, input_reg);
|
| + __ cvtlsi2sd(xmm_scratch, output_reg);
|
| + __ ucomisd(input_reg, xmm_scratch);
|
| + __ j(equal, &done, Label::kNear);
|
| + __ subl(output_reg, Immediate(1));
|
| + DeoptimizeIf(overflow, instr->environment());
|
| +
|
| + __ bind(&done);
|
| }
|
| - __ bind(&done);
|
| }
|
|
|
|
|
|
|