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 9cd0c1c51ec4a4cd5423758558d81a6a03489a42..1f6192f0a51129017e53fd3af4c815362121a1f1 100644 |
| --- a/src/x64/lithium-codegen-x64.cc |
| +++ b/src/x64/lithium-codegen-x64.cc |
| @@ -864,16 +864,56 @@ void LCodeGen::DoMulI(LMulI* instr) { |
| __ movl(kScratchRegister, left); |
| } |
| + bool can_overflow = |
| + instr->hydrogen()->CheckFlag(HValue::kCanOverflow); |
| if (right->IsConstantOperand()) { |
| int right_value = ToInteger32(LConstantOperand::cast(right)); |
| - __ imull(left, left, Immediate(right_value)); |
| + if (right_value == -1) { |
| + __ negl(left); |
| + } else if (right_value == 0) { |
|
William Hesse
2011/03/17 12:55:06
If BailoutOnMinusZero is true, we always bail out
Lasse Reichstein
2011/03/17 18:11:55
Yes, I noticed too that we bail out even if we don
|
| + __ xorl(left, left); |
| + } else if (right_value == 2) { |
| + __ addl(left, left); |
| + } else if (!can_overflow) { |
| + // If the multiplication is known to not overflow, we |
| + // can use operations that don't set the overflow flag |
| + // correctly. |
| + switch (right_value) { |
| + case 1: |
| + // Do nothing. |
| + break; |
| + case 3: |
| + __ leal(left, Operand(left, left, times_2, 0)); |
| + break; |
| + case 4: |
| + __ shll(left, Immediate(2)); |
| + break; |
| + case 5: |
| + __ leal(left, Operand(left, left, times_4, 0)); |
| + break; |
| + case 8: |
| + __ shll(left, Immediate(3)); |
| + break; |
| + case 9: |
| + __ leal(left, Operand(left, left, times_8, 0)); |
| + break; |
| + case 16: |
| + __ shll(left, Immediate(4)); |
| + break; |
| + default: |
| + __ imull(left, left, Immediate(right_value)); |
| + break; |
| + } |
| + } else { |
| + __ imull(left, left, Immediate(right_value)); |
| + } |
| } else if (right->IsStackSlot()) { |
| __ imull(left, ToOperand(right)); |
| } else { |
| __ imull(left, ToRegister(right)); |
| } |
| - if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) { |
| + if (can_overflow) { |
| DeoptimizeIf(overflow, instr->environment()); |
| } |