Index: src/mips/lithium-codegen-mips.cc |
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc |
index ca1d2b5bb524b0e8d01fca52e55c88703578a9fb..36ee47bfcd28a8e6ee5e012015180b69f014622e 100644 |
--- a/src/mips/lithium-codegen-mips.cc |
+++ b/src/mips/lithium-codegen-mips.cc |
@@ -874,52 +874,47 @@ void LCodeGen::DoModI(LModI* instr) { |
const Register left = ToRegister(instr->InputAt(0)); |
const Register result = ToRegister(instr->result()); |
- // p2constant holds the right side value if it's a power of 2 constant. |
- // In other cases it is 0. |
- int32_t p2constant = 0; |
- |
- if (instr->InputAt(1)->IsConstantOperand()) { |
- p2constant = ToInteger32(LConstantOperand::cast(instr->InputAt(1))); |
- if (p2constant % 2 != 0) { |
- p2constant = 0; |
- } |
- // Result always takes the sign of the dividend (left). |
- p2constant = abs(p2constant); |
- } |
- |
- // div runs in the background while we check for special cases. |
- Register right = EmitLoadRegister(instr->InputAt(1), scratch); |
- __ div(left, right); |
+ Label done; |
- // Check for x % 0. |
- if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { |
- DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg)); |
- } |
+ if (instr->hydrogen()->HasPowerOf2Divisor()) { |
+ Register scratch = scratch0(); |
+ ASSERT(!left.is(scratch)); |
+ __ mov(scratch, left); |
+ int32_t p2constant = HConstant::cast( |
+ instr->hydrogen()->right())->Integer32Value(); |
+ ASSERT(p2constant != 0); |
+ // Result always takes the sign of the dividend (left). |
+ p2constant = abs(p2constant); |
- Label skip_div, do_div; |
- if (p2constant != 0) { |
- // Fall back to the result of the div instruction if we could have sign |
- // problems. |
- __ Branch(&do_div, lt, left, Operand(zero_reg)); |
- // Modulo by masking. |
- __ And(scratch, left, p2constant - 1); |
- __ Branch(&skip_div); |
- } |
+ Label positive_dividend; |
+ __ Branch(USE_DELAY_SLOT, &positive_dividend, ge, left, Operand(zero_reg)); |
+ __ subu(result, zero_reg, left); |
+ __ And(result, result, p2constant - 1); |
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
+ DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg)); |
+ } |
+ __ Branch(USE_DELAY_SLOT, &done); |
+ __ subu(result, zero_reg, result); |
+ __ bind(&positive_dividend); |
+ __ And(result, scratch, p2constant - 1); |
+ } else { |
+ // div runs in the background while we check for special cases. |
+ Register right = EmitLoadRegister(instr->InputAt(1), scratch); |
+ __ div(left, right); |
- __ bind(&do_div); |
- __ mfhi(scratch); |
- __ bind(&skip_div); |
+ // Check for x % 0. |
+ if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) { |
+ DeoptimizeIf(eq, instr->environment(), right, Operand(zero_reg)); |
+ } |
- if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
- // Result always takes the sign of the dividend (left). |
- Label done; |
__ Branch(USE_DELAY_SLOT, &done, ge, left, Operand(zero_reg)); |
- __ mov(result, scratch); |
- DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg)); |
- __ bind(&done); |
- } else { |
- __ Move(result, scratch); |
+ __ mfhi(result); |
+ |
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
+ DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg)); |
+ } |
} |
+ __ bind(&done); |
} |