Chromium Code Reviews| Index: src/ia32/lithium-codegen-ia32.cc |
| =================================================================== |
| --- src/ia32/lithium-codegen-ia32.cc (revision 7551) |
| +++ src/ia32/lithium-codegen-ia32.cc (working copy) |
| @@ -795,6 +795,7 @@ |
| __ bind(&done); |
| } else { |
| LOperand* right = instr->InputAt(1); |
| + NearLabel done, remainder_eq_dividend, slow, do_subtraction, both_positive; |
|
Søren Thygesen Gjesse
2011/04/27 14:11:43
Please set up Register variables for left as well:
|
| ASSERT(ToRegister(instr->InputAt(0)).is(eax)); |
| ASSERT(ToRegister(instr->result()).is(edx)); |
| @@ -808,6 +809,45 @@ |
| DeoptimizeIf(zero, instr->environment()); |
| } |
| + __ test(eax, Operand(eax)); |
| + __ j(zero, &remainder_eq_dividend); |
| + __ j(sign, &slow); |
| + |
| + __ test(right_reg, Operand(right_reg)); |
| + __ j(not_sign, &both_positive); |
| + // The sign of the divisor doesn't matter. |
| + __ neg(right_reg); |
| + |
| + __ bind(&both_positive); |
| + // If the dividend is smaller than the nonnegative |
| + // divisor, the dividend is the result. |
| + __ cmp(eax, Operand(right_reg)); |
| + __ j(less, &remainder_eq_dividend); |
| + |
| + // Check if the divisor is a PowerOfTwo integer. |
| + Register scratch = ToRegister(instr->TempAt(0)); |
| + __ mov(scratch, right_reg); |
| + __ sub(Operand(scratch), Immediate(1)); |
| + __ test(scratch, Operand(right_reg)); |
| + __ j(not_zero, &do_subtraction); |
| + __ and_(eax, Operand(scratch)); |
| + __ jmp(&remainder_eq_dividend); |
| + |
| + __ bind(&do_subtraction); |
| + const int kUnfolds = 3; |
| + // Try a few subtractions of the dividend. |
| + __ mov(scratch, eax); |
| + for (int i = 0; i < kUnfolds; i++) { |
| + // Reduce the dividend by the divisor. |
| + __ sub(eax, Operand(right_reg)); |
| + // Check if the dividend is less than the divisor. |
| + __ cmp(eax, Operand(right_reg)); |
| + __ j(less, &remainder_eq_dividend); |
| + } |
| + __ mov(eax, scratch); |
| + |
| + // Slow case, using idiv instruction. |
| + __ bind(&slow); |
| // Sign extend to edx. |
| __ cdq(); |
| @@ -830,6 +870,12 @@ |
| } else { |
| __ idiv(right_reg); |
| } |
| + __ jmp(&done); |
| + |
| + __ bind(&remainder_eq_dividend); |
| + __ mov(edx, eax); |
| + |
| + __ bind(&done); |
| } |
| } |