From b0b10ec72d112fc87052876e54d17578fab3f2cd Mon Sep 17 00:00:00 2001 From: "plind44@gmail.com" Date: Wed, 11 Jun 2014 20:06:01 +0000 Subject: [PATCH] MIPS: Fixed flooring division by a power of 2, once again... Port r21769 (52e191b) Original commit message: Avoid right shifts by zero bits: On ARM it actually means shifting by 32 bits (correctness issue) and on other platforms they are useless (performance issue). This is fix for the fix in r20544. BUG=v8:3259 LOG=y R=plind44@gmail.com Review URL: https://codereview.chromium.org/322403006 Patch from Balazs Kilvady . git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21780 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/mips/lithium-codegen-mips.cc | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index 65fe1aa..1b2dec0 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -1309,8 +1309,8 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) { Register dividend = ToRegister(instr->dividend()); Register result = ToRegister(instr->result()); int32_t divisor = instr->divisor(); - Register scratch = scratch0(); - ASSERT(!scratch.is(dividend)); + Register scratch = result.is(dividend) ? scratch0() : dividend; + ASSERT(!result.is(dividend) || !scratch.is(dividend)); // If the divisor is 1, return the dividend. if (divisor == 1) { @@ -1328,6 +1328,8 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) { // If the divisor is negative, we have to negate and handle edge cases. if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { + // divident can be the same register as result so save the value of it + // for checking overflow. __ Move(scratch, dividend); } __ Subu(result, zero_reg, dividend); @@ -1335,16 +1337,18 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) { DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg)); } - // If the negation could not overflow, simply shifting is OK. - if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { - __ sra(result, dividend, shift); - return; - } - // Dividing by -1 is basically negation, unless we overflow. __ Xor(at, scratch, result); if (divisor == -1) { - DeoptimizeIf(ge, instr->environment(), at, Operand(zero_reg)); + if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { + DeoptimizeIf(ge, instr->environment(), at, Operand(zero_reg)); + } + return; + } + + // If the negation could not overflow, simply shifting is OK. + if (!instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) { + __ sra(result, result, shift); return; } @@ -1353,7 +1357,7 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) { __ li(result, Operand(kMinInt / divisor)); __ Branch(&done); __ bind(&no_overflow); - __ sra(result, dividend, shift); + __ sra(result, result, shift); __ bind(&done); } -- 2.7.4