From bef75b349604b466e5fdb329ae0ad2badd564e00 Mon Sep 17 00:00:00 2001 From: "danno@chromium.org" Date: Thu, 17 Nov 2011 13:33:56 +0000 Subject: [PATCH] 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= Review URL: http://codereview.chromium.org/8591002 Patch from Gergely Kis . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10016 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/mips/lithium-codegen-mips.cc | 75 +++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 40 deletions(-) diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index ca1d2b5..36ee47b 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); } -- 2.7.4