Index: src/x64/lithium-codegen-x64.cc |
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc |
index c1c98fbeae090bd474833c67d70696d16abb1339..4c75d6cdc13462cf4d0b2a575a64d9ea8b757dca 100644 |
--- a/src/x64/lithium-codegen-x64.cc |
+++ b/src/x64/lithium-codegen-x64.cc |
@@ -2698,21 +2698,36 @@ void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { |
XMMRegister xmm_scratch = xmm0; |
Register output_reg = ToRegister(instr->result()); |
XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); |
- __ xorpd(xmm_scratch, xmm_scratch); // Zero the register. |
- __ ucomisd(input_reg, xmm_scratch); |
- if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
- DeoptimizeIf(below_equal, instr->environment()); |
+ if (CpuFeatures::IsSupported(SSE4_1)) { |
+ CpuFeatures::Scope scope(SSE4_1); |
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
+ // Deoptimize if minus zero. |
+ __ movq(output_reg, input_reg); |
+ __ subq(output_reg, Immediate(1)); |
+ DeoptimizeIf(overflow, instr->environment()); |
+ } |
+ __ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown); |
+ __ cvttsd2si(output_reg, xmm_scratch); |
+ __ cmpl(output_reg, Immediate(0x80000000)); |
+ DeoptimizeIf(equal, instr->environment()); |
} else { |
- DeoptimizeIf(below, instr->environment()); |
- } |
+ __ xorpd(xmm_scratch, xmm_scratch); // Zero the register. |
+ __ ucomisd(input_reg, xmm_scratch); |
- // Use truncating instruction (OK because input is positive). |
- __ cvttsd2si(output_reg, input_reg); |
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
+ DeoptimizeIf(below_equal, instr->environment()); |
+ } else { |
+ DeoptimizeIf(below, instr->environment()); |
+ } |
- // Overflow is signalled with minint. |
- __ cmpl(output_reg, Immediate(0x80000000)); |
- DeoptimizeIf(equal, instr->environment()); |
+ // 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()); |
+ } |
} |