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) {
void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) {
Register dividend = ToRegister(instr->dividend());
Register result = ToRegister(instr->result());
int32_t divisor = instr->divisor();
ASSERT(dividend.is(ToRegister(instr->result())));
Register scratch = scratch0();
ASSERT(!scratch.is(dividend));
// If the divisor is positive, things are easy: There can be no deopts and we
// can simply do an arithmetic right shift.
if (divisor == 1) return;
uint16_t shift = WhichPowerOf2Abs(divisor);
if (divisor > 1) {
__ sra(dividend, dividend, shift);
__ sra(result, dividend, shift);
return;
}
// If the divisor is negative, we have to negate and handle edge cases.
Label not_kmin_int, done;
__ Subu(scratch, zero_reg, dividend);
if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
__ Move(scratch, dividend);
}
__ Subu(result, zero_reg, dividend);
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
// register.
__ Branch(&not_kmin_int, ne, dividend, Operand(kMinInt));
__ Xor(at, scratch, result);
if (divisor == -1) {
DeoptimizeIf(al, instr->environment());
DeoptimizeIf(ge, instr->environment(), at, Operand(zero_reg));
__ sra(result, dividend, shift);
} 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);
__ 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) {
LInstruction* LChunkBuilder::DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr) {
LOperand* dividend = UseRegisterAtStart(instr->left());
int32_t divisor = instr->right()->GetInteger32Constant();
LInstruction* result =
DefineSameAsFirst(
new(zone()) LFlooringDivByPowerOf2I(dividend, divisor));
bool can_deopt =
(instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
(instr->left()->RangeCanInclude(kMinInt) && divisor == -1);
return can_deopt ? AssignEnvironment(result) : result;
LInstruction* result = DefineAsRegister(new(zone()) LFlooringDivByPowerOf2I(
dividend, divisor));
if ((instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0) ||
(instr->CheckFlag(HValue::kLeftCanBeMinInt) && divisor == -1)) {
result = AssignEnvironment(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