| Index: src/x64/lithium-codegen-x64.cc
|
| diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
|
| index 4be8657027567489b97880478e232bcdc46e1c38..f39ecad915ba283fe18a7774ad01c855902e1be8 100644
|
| --- a/src/x64/lithium-codegen-x64.cc
|
| +++ b/src/x64/lithium-codegen-x64.cc
|
| @@ -1205,6 +1205,59 @@ void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) {
|
| }
|
|
|
|
|
| +// TODO(svenpanne) Refactor this to avoid code duplication with DoDivI.
|
| +void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) {
|
| + HBinaryOperation* hdiv = instr->hydrogen();
|
| + Register dividend = ToRegister(instr->dividend());
|
| + Register divisor = ToRegister(instr->divisor());
|
| + Register remainder = ToRegister(instr->temp());
|
| + Register result = ToRegister(instr->result());
|
| + ASSERT(dividend.is(rax));
|
| + ASSERT(remainder.is(rdx));
|
| + ASSERT(result.is(rax));
|
| + ASSERT(!divisor.is(rax));
|
| + ASSERT(!divisor.is(rdx));
|
| +
|
| + // Check for x / 0.
|
| + if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
|
| + __ testl(divisor, divisor);
|
| + DeoptimizeIf(zero, instr->environment());
|
| + }
|
| +
|
| + // Check for (0 / -x) that will produce negative zero.
|
| + if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
| + Label dividend_not_zero;
|
| + __ testl(dividend, dividend);
|
| + __ j(not_zero, ÷nd_not_zero, Label::kNear);
|
| + __ testl(divisor, divisor);
|
| + DeoptimizeIf(sign, instr->environment());
|
| + __ bind(÷nd_not_zero);
|
| + }
|
| +
|
| + // Check for (kMinInt / -1).
|
| + if (hdiv->CheckFlag(HValue::kCanOverflow)) {
|
| + Label dividend_not_min_int;
|
| + __ cmpl(dividend, Immediate(kMinInt));
|
| + __ j(not_zero, ÷nd_not_min_int, Label::kNear);
|
| + __ cmpl(divisor, Immediate(-1));
|
| + DeoptimizeIf(zero, instr->environment());
|
| + __ bind(÷nd_not_min_int);
|
| + }
|
| +
|
| + // Sign extend to rdx (= remainder).
|
| + __ cdq();
|
| + __ idivl(divisor);
|
| +
|
| + Label done;
|
| + __ testl(remainder, remainder);
|
| + __ j(zero, &done, Label::kNear);
|
| + __ xorl(remainder, divisor);
|
| + __ sarl(remainder, Immediate(31));
|
| + __ addl(result, remainder);
|
| + __ bind(&done);
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) {
|
| Register dividend = ToRegister(instr->dividend());
|
| int32_t divisor = instr->divisor();
|
| @@ -1272,10 +1325,11 @@ void LCodeGen::DoDivByConstI(LDivByConstI* instr) {
|
| }
|
|
|
|
|
| +// TODO(svenpanne) Refactor this to avoid code duplication with DoFlooringDivI.
|
| void LCodeGen::DoDivI(LDivI* instr) {
|
| HBinaryOperation* hdiv = instr->hydrogen();
|
| - Register dividend = ToRegister(instr->left());
|
| - Register divisor = ToRegister(instr->right());
|
| + Register dividend = ToRegister(instr->dividend());
|
| + Register divisor = ToRegister(instr->divisor());
|
| Register remainder = ToRegister(instr->temp());
|
| Register result = ToRegister(instr->result());
|
| ASSERT(dividend.is(rax));
|
| @@ -1314,15 +1368,7 @@ void LCodeGen::DoDivI(LDivI* instr) {
|
| __ cdq();
|
| __ idivl(divisor);
|
|
|
| - if (hdiv->IsMathFloorOfDiv()) {
|
| - Label done;
|
| - __ testl(remainder, remainder);
|
| - __ j(zero, &done, Label::kNear);
|
| - __ xorl(remainder, divisor);
|
| - __ sarl(remainder, Immediate(31));
|
| - __ addl(result, remainder);
|
| - __ bind(&done);
|
| - } else if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
|
| + if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
|
| // Deoptimize if remainder is not 0.
|
| __ testl(remainder, remainder);
|
| DeoptimizeIf(not_zero, instr->environment());
|
|
|