Reviewers: danno, Paul Lind,
Description:
MIPS: Re-work DoModI.
Changes:
-separated the two code-paths (constant power of 2 divisor similar to ARM
and
everything else)
-replaced a bailout condition with faster handling (negative modulo result)
-removed a possibly useless mov instruction from one path
-replaced the IsConstantOperand condition with the more meaningful
HasPowerOf2Divisor (although in this specific case they're equivalent)
BUG=
TEST=
Please review this at http://codereview.chromium.org/8591002/
Affected files:
M src/mips/lithium-codegen-mips.cc
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);
}
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev