Commit d50a179b authored by plind44@gmail.com's avatar plind44@gmail.com

MIPS: Remove uses of RangeCanInclude() in flooring division by power of 2.

Port r19877 (17029d3)

Original commit message:
Drive-By-Fix: Improve ARM code generation for flooring division by
power of 2.

BUG=v8:3204
LOG=y
R=plind44@gmail.com

Review URL: https://codereview.chromium.org/195893013

Patch from Balazs Kilvady <kilvadyb@homejinni.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19904 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent cfed3c94
...@@ -1195,39 +1195,48 @@ void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) { ...@@ -1195,39 +1195,48 @@ void LCodeGen::DoMultiplyAddD(LMultiplyAddD* instr) {
void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) { void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
Register dividend = ToRegister(instr->dividend()); Register dividend = ToRegister(instr->dividend());
Register result = ToRegister(instr->result());
int32_t divisor = instr->divisor(); int32_t divisor = instr->divisor();
ASSERT(dividend.is(ToRegister(instr->result())));
Register scratch = scratch0(); Register scratch = scratch0();
ASSERT(!scratch.is(dividend));
// If the divisor is positive, things are easy: There can be no deopts and we // If the divisor is positive, things are easy: There can be no deopts and we
// can simply do an arithmetic right shift. // can simply do an arithmetic right shift.
if (divisor == 1) return; if (divisor == 1) return;
uint16_t shift = WhichPowerOf2Abs(divisor); uint16_t shift = WhichPowerOf2Abs(divisor);
if (divisor > 1) { if (divisor > 1) {
__ sra(dividend, dividend, shift); __ sra(result, dividend, shift);
return; return;
} }
// If the divisor is negative, we have to negate and handle edge cases. // If the divisor is negative, we have to negate and handle edge cases.
Label not_kmin_int, done; if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
__ Subu(scratch, zero_reg, dividend); __ Move(scratch, dividend);
}
__ Subu(result, zero_reg, dividend);
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg)); DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg));
} }
if (instr->hydrogen()->left()->RangeCanInclude(kMinInt)) { if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
// Note that we could emit branch-free code, but that would need one more // Note that we could emit branch-free code, but that would need one more
// register. // register.
__ Branch(&not_kmin_int, ne, dividend, Operand(kMinInt));
__ Xor(at, scratch, result);
if (divisor == -1) { if (divisor == -1) {
DeoptimizeIf(al, instr->environment()); DeoptimizeIf(ge, instr->environment(), at, Operand(zero_reg));
__ sra(result, dividend, shift);
} else { } else {
__ li(dividend, Operand(kMinInt / divisor)); Label no_overflow, done;
__ Branch(&no_overflow, lt, at, Operand(zero_reg));
__ li(result, Operand(kMinInt / divisor));
__ Branch(&done); __ Branch(&done);
__ bind(&no_overflow);
__ sra(result, dividend, shift);
__ bind(&done);
} }
} else {
__ sra(result, dividend, shift);
} }
__ bind(&not_kmin_int);
__ sra(dividend, scratch, shift);
__ bind(&done);
} }
......
...@@ -1280,13 +1280,13 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { ...@@ -1280,13 +1280,13 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
LInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) { LInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) {
LOperand* dividend = UseRegisterAtStart(instr->left()); LOperand* dividend = UseRegisterAtStart(instr->left());
int32_t divisor = instr->right()->GetInteger32Constant(); int32_t divisor = instr->right()->GetInteger32Constant();
LInstruction* result = LInstruction* result = DefineAsRegister(new(zone()) LFlooringDivByPowerOf2I(
DefineSameAsFirst( dividend, divisor));
new(zone()) LFlooringDivByPowerOf2I(dividend, divisor)); if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
bool can_deopt = (instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) {
(instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) || result = AssignEnvironment(result);
(instr->left()->RangeCanInclude(kMinInt) && divisor == -1); }
return can_deopt ? AssignEnvironment(result) : result; return result;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment