| Index: src/ia32/lithium-codegen-ia32.cc
|
| ===================================================================
|
| --- src/ia32/lithium-codegen-ia32.cc (revision 11394)
|
| +++ src/ia32/lithium-codegen-ia32.cc (working copy)
|
| @@ -2924,11 +2924,13 @@
|
| __ cmp(output_reg, 0x80000000u);
|
| DeoptimizeIf(equal, instr->environment());
|
| } else {
|
| + Label negative_sign;
|
| Label done;
|
| - // Deoptimize on negative numbers.
|
| + // Deoptimize on unordered.
|
| __ 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.
|
| @@ -2944,10 +2946,21 @@
|
|
|
| // Use truncating instruction (OK because input is positive).
|
| __ cvttsd2si(output_reg, Operand(input_reg));
|
| -
|
| // Overflow is signalled with minint.
|
| __ cmp(output_reg, 0x80000000u);
|
| DeoptimizeIf(equal, instr->environment());
|
| + __ jmp(&done, Label::kNear);
|
| +
|
| + // Non-zero negative reaches here
|
| + __ bind(&negative_sign);
|
| + // Truncate, then compare and compensate
|
| + __ cvttsd2si(output_reg, Operand(input_reg));
|
| + __ cvtsi2sd(xmm_scratch, output_reg);
|
| + __ ucomisd(input_reg, xmm_scratch);
|
| + __ j(equal, &done, Label::kNear);
|
| + __ sub(output_reg, Immediate(1));
|
| + DeoptimizeIf(overflow, instr->environment());
|
| +
|
| __ bind(&done);
|
| }
|
| }
|
|
|