Index: src/mips/lithium-codegen-mips.cc |
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc |
index d05cd28b46c34f3956e1948bc6896f539bfeec58..044b9c7c6d70c77903c9f2f3388145744db9a34f 100644 |
--- a/src/mips/lithium-codegen-mips.cc |
+++ b/src/mips/lithium-codegen-mips.cc |
@@ -1136,9 +1136,37 @@ void LCodeGen::DoModI(LModI* instr) { |
__ And(result_reg, scratch, divisor - 1); |
__ bind(&done); |
- } else { |
- // TODO(svenpanne) Add right->has_fixed_right_arg() case. |
+ } else if (hmod->fixed_right_arg().has_value) { |
+ const Register scratch = scratch0(); |
+ const Register left_reg = ToRegister(instr->left()); |
+ const Register result_reg = ToRegister(instr->result()); |
+ |
+ Register right_reg = EmitLoadRegister(instr->right(), scratch); |
+ |
+ int32_t divisor = hmod->fixed_right_arg().value; |
+ ASSERT(IsPowerOf2(divisor)); |
+ // Check if our assumption of a fixed right operand still holds. |
+ DeoptimizeIf(ne, instr->environment(), right_reg, Operand(divisor)); |
+ |
+ Label left_is_not_negative, done; |
+ if (left->CanBeNegative()) { |
+ __ Branch(USE_DELAY_SLOT, &left_is_not_negative, |
+ ge, left_reg, Operand(zero_reg)); |
+ __ subu(result_reg, zero_reg, left_reg); |
+ __ And(result_reg, result_reg, divisor - 1); |
+ if (hmod->CheckFlag(HValue::kBailoutOnMinusZero)) { |
+ DeoptimizeIf(eq, instr->environment(), result_reg, Operand(zero_reg)); |
+ } |
+ __ Branch(USE_DELAY_SLOT, &done); |
+ __ subu(result_reg, zero_reg, result_reg); |
+ } |
+ |
+ __ bind(&left_is_not_negative); |
+ __ And(result_reg, left_reg, divisor - 1); |
+ __ bind(&done); |
+ |
+ } else { |
const Register scratch = scratch0(); |
const Register left_reg = ToRegister(instr->left()); |
const Register result_reg = ToRegister(instr->result()); |