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
This commit is contained in:
parent
cfed3c94af
commit
d50a179b87
@ -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::kBailoutOnMinusZero)) {
|
||||
DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg));
|
||||
if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
|
||||
__ Move(scratch, dividend);
|
||||
}
|
||||
if (instr->hydrogen()->left()->RangeCanInclude(kMinInt)) {
|
||||
__ Subu(result, zero_reg, dividend);
|
||||
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
||||
DeoptimizeIf(eq, instr->environment(), result, Operand(zero_reg));
|
||||
}
|
||||
if (instr->hydrogen()->CheckFlag(HValue::kLeftCanBeMinInt)) {
|
||||
// Note that we could emit branch-free code, but that would need one more
|
||||
// register.
|
||||
__ Branch(¬_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(¬_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;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user