MIPS: Implement flooring division by a constant via truncating division by a constant.
Port r20123 (31ab416) BUG= R=plind44@gmail.com Review URL: https://codereview.chromium.org/206373004 Patch from Balazs Kilvady <kilvadyb@homejinni.com>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20135 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
b12ff51378
commit
2aadbc8f2c
@ -1367,8 +1367,31 @@ void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
|
||||
DeoptimizeIf(eq, instr->environment(), dividend, Operand(zero_reg));
|
||||
}
|
||||
|
||||
// TODO(svenpanne) Add correction terms.
|
||||
__ TruncatingDiv(result, dividend, divisor);
|
||||
// Easy case: We need no dynamic check for the dividend and the flooring
|
||||
// division is the same as the truncating division.
|
||||
if ((divisor > 0 && !hdiv->CheckFlag(HValue::kLeftCanBeNegative)) ||
|
||||
(divisor < 0 && !hdiv->CheckFlag(HValue::kLeftCanBePositive))) {
|
||||
__ TruncatingDiv(result, dividend, Abs(divisor));
|
||||
if (divisor < 0) __ Subu(result, zero_reg, result);
|
||||
return;
|
||||
}
|
||||
|
||||
// In the general case we may need to adjust before and after the truncating
|
||||
// division to get a flooring division.
|
||||
Register temp = ToRegister(instr->temp());
|
||||
ASSERT(!temp.is(dividend) && !temp.is(result));
|
||||
Label needs_adjustment, done;
|
||||
__ Branch(&needs_adjustment, divisor > 0 ? lt : gt,
|
||||
dividend, Operand(zero_reg));
|
||||
__ TruncatingDiv(result, dividend, Abs(divisor));
|
||||
if (divisor < 0) __ Subu(result, zero_reg, result);
|
||||
__ jmp(&done);
|
||||
__ bind(&needs_adjustment);
|
||||
__ Addu(temp, dividend, Operand(divisor > 0 ? 1 : -1));
|
||||
__ TruncatingDiv(result, temp, Abs(divisor));
|
||||
if (divisor < 0) __ Subu(result, zero_reg, result);
|
||||
__ Subu(result, result, Operand(1));
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1337,20 +1337,25 @@ LInstruction* LChunkBuilder::DoFlooringDivByConstI(HMathFloorOfDiv* instr) {
|
||||
ASSERT(instr->right()->representation().Equals(instr->representation()));
|
||||
LOperand* dividend = UseRegister(instr->left());
|
||||
int32_t divisor = instr->right()->GetInteger32Constant();
|
||||
LInstruction* result =
|
||||
DefineAsRegister(new(zone()) LFlooringDivByConstI(dividend, divisor));
|
||||
bool can_deopt =
|
||||
divisor == 0 ||
|
||||
(instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0);
|
||||
return can_deopt ? AssignEnvironment(result) : result;
|
||||
LOperand* temp =
|
||||
((divisor > 0 && !instr->CheckFlag(HValue::kLeftCanBeNegative)) ||
|
||||
(divisor < 0 && !instr->CheckFlag(HValue::kLeftCanBePositive))) ?
|
||||
NULL : TempRegister();
|
||||
LInstruction* result = DefineAsRegister(
|
||||
new(zone()) LFlooringDivByConstI(dividend, divisor, temp));
|
||||
if (divisor == 0 ||
|
||||
(instr->CheckFlag(HValue::kBailoutOnMinusZero) && divisor < 0)) {
|
||||
result = AssignEnvironment(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
|
||||
if (instr->RightIsPowerOf2()) {
|
||||
return DoFlooringDivByPowerOf2I(instr);
|
||||
} else if (false && instr->right()->IsConstant()) {
|
||||
return DoFlooringDivByConstI(instr); // TODO(svenpanne) Fix and re-enable.
|
||||
} else if (instr->right()->IsConstant()) {
|
||||
return DoFlooringDivByConstI(instr);
|
||||
} else {
|
||||
return DoDivI(instr);
|
||||
}
|
||||
|
@ -741,16 +741,17 @@ class LFlooringDivByPowerOf2I V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
};
|
||||
|
||||
|
||||
class LFlooringDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 0> {
|
||||
class LFlooringDivByConstI V8_FINAL : public LTemplateInstruction<1, 1, 2> {
|
||||
public:
|
||||
LFlooringDivByConstI(LOperand* dividend, int32_t divisor) {
|
||||
LFlooringDivByConstI(LOperand* dividend, int32_t divisor, LOperand* temp) {
|
||||
inputs_[0] = dividend;
|
||||
divisor_ = divisor;
|
||||
temps_[0] = temp;
|
||||
}
|
||||
|
||||
LOperand* dividend() { return inputs_[0]; }
|
||||
int32_t divisor() const { return divisor_; }
|
||||
LOperand* temp1() { return temps_[0]; }
|
||||
LOperand* temp() { return temps_[0]; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(FlooringDivByConstI, "flooring-div-by-const-i")
|
||||
DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
|
||||
|
Loading…
Reference in New Issue
Block a user