Chromium Code Reviews| Index: src/ia32/lithium-codegen-ia32.cc |
| diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc |
| index 28f4679a41cf5e7c37fc7545a0283bdceac37271..10b7132d4d04beedaa42efa6ec5d5942ec5d335d 100644 |
| --- a/src/ia32/lithium-codegen-ia32.cc |
| +++ b/src/ia32/lithium-codegen-ia32.cc |
| @@ -781,41 +781,65 @@ void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { |
| void LCodeGen::DoModI(LModI* instr) { |
| - LOperand* right = instr->InputAt(1); |
| - ASSERT(ToRegister(instr->result()).is(edx)); |
| - ASSERT(ToRegister(instr->InputAt(0)).is(eax)); |
| - ASSERT(!ToRegister(instr->InputAt(1)).is(eax)); |
| - ASSERT(!ToRegister(instr->InputAt(1)).is(edx)); |
| + if (HMod::cast(instr->hydrogen())->HasPowerOf2Divisor()) { |
| + Register dividend = ToRegister(instr->InputAt(0)); |
| - Register right_reg = ToRegister(right); |
| + int32_t divisor = |
| + HConstant::cast( |
| + HMod::cast(instr->hydrogen())->right())->Integer32Value(); |
| - // Check for x % 0. |
| - if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { |
| - __ test(right_reg, ToOperand(right)); |
| - DeoptimizeIf(zero, instr->environment()); |
| - } |
| + if (divisor < 0) divisor = -divisor; |
| - // Sign extend to edx. |
| - __ cdq(); |
| + NearLabel positive_dividend, done; |
| + __ test(dividend, Operand(dividend)); |
| + __ j(not_sign, &positive_dividend); |
| + __ neg(dividend); |
| + __ and_ (dividend, divisor - 1); |
|
Kevin Millikin (Chromium)
2011/03/11 11:59:43
No space after and_ here and below.
Vyacheslav Egorov (Chromium)
2011/03/14 14:30:51
Done.
|
| + if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| + __ j(not_zero, &done); |
| + DeoptimizeIf(no_condition, instr->environment()); |
| + } |
| + __ neg(dividend); |
| + __ bind(&positive_dividend); |
| + __ and_ (dividend, divisor - 1); |
| + __ bind(&done); |
| + } else { |
| + LOperand* right = instr->InputAt(1); |
| + ASSERT(ToRegister(instr->InputAt(0)).is(eax)); |
| + ASSERT(ToRegister(instr->result()).is(edx)); |
| - // Check for (0 % -x) that will produce negative zero. |
| - if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| - NearLabel positive_left; |
| - NearLabel done; |
| - __ test(eax, Operand(eax)); |
| - __ j(not_sign, &positive_left); |
| - __ idiv(right_reg); |
| + Register right_reg = ToRegister(right); |
| + ASSERT(!right_reg.is(eax)); |
| + ASSERT(!right_reg.is(edx)); |
| - // Test the remainder for 0, because then the result would be -0. |
| - __ test(edx, Operand(edx)); |
| - __ j(not_zero, &done); |
| + // Check for x % 0. |
| + if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { |
| + __ test(right_reg, ToOperand(right)); |
| + DeoptimizeIf(zero, instr->environment()); |
| + } |
| - DeoptimizeIf(no_condition, instr->environment()); |
| - __ bind(&positive_left); |
| - __ idiv(right_reg); |
| - __ bind(&done); |
| - } else { |
| - __ idiv(right_reg); |
| + // Sign extend to edx. |
| + __ cdq(); |
| + |
| + // Check for (0 % -x) that will produce negative zero. |
| + if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| + NearLabel positive_left; |
| + NearLabel done; |
| + __ test(eax, Operand(eax)); |
| + __ j(not_sign, &positive_left); |
| + __ idiv(right_reg); |
| + |
| + // Test the remainder for 0, because then the result would be -0. |
| + __ test(edx, Operand(edx)); |
| + __ j(not_zero, &done); |
| + |
| + DeoptimizeIf(no_condition, instr->environment()); |
| + __ bind(&positive_left); |
| + __ idiv(right_reg); |
| + __ bind(&done); |
| + } else { |
| + __ idiv(right_reg); |
| + } |
| } |
| } |