| Index: src/ia32/lithium-codegen-ia32.cc
|
| diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
|
| index 52bdbe3232f70a3b5288a9939c742785ebf7fd32..49263658b50dbe7962b1eb75def393055a59de9b 100644
|
| --- a/src/ia32/lithium-codegen-ia32.cc
|
| +++ b/src/ia32/lithium-codegen-ia32.cc
|
| @@ -1556,10 +1556,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(eax));
|
| @@ -1598,15 +1599,7 @@ void LCodeGen::DoDivI(LDivI* instr) {
|
| __ cdq();
|
| __ idiv(divisor);
|
|
|
| - if (hdiv->IsMathFloorOfDiv()) {
|
| - Label done;
|
| - __ test(remainder, remainder);
|
| - __ j(zero, &done, Label::kNear);
|
| - __ xor_(remainder, divisor);
|
| - __ sar(remainder, 31);
|
| - __ add(result, remainder);
|
| - __ bind(&done);
|
| - } else if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
|
| + if (!hdiv->CheckFlag(HValue::kAllUsesTruncatingToInt32)) {
|
| // Deoptimize if remainder is not 0.
|
| __ test(remainder, remainder);
|
| DeoptimizeIf(not_zero, instr->environment());
|
| @@ -1696,6 +1689,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(eax));
|
| + ASSERT(remainder.is(edx));
|
| + ASSERT(result.is(eax));
|
| + ASSERT(!divisor.is(eax));
|
| + ASSERT(!divisor.is(edx));
|
| +
|
| + // Check for x / 0.
|
| + if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
|
| + __ test(divisor, divisor);
|
| + DeoptimizeIf(zero, instr->environment());
|
| + }
|
| +
|
| + // Check for (0 / -x) that will produce negative zero.
|
| + if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero)) {
|
| + Label dividend_not_zero;
|
| + __ test(dividend, dividend);
|
| + __ j(not_zero, ÷nd_not_zero, Label::kNear);
|
| + __ test(divisor, divisor);
|
| + DeoptimizeIf(sign, instr->environment());
|
| + __ bind(÷nd_not_zero);
|
| + }
|
| +
|
| + // Check for (kMinInt / -1).
|
| + if (hdiv->CheckFlag(HValue::kCanOverflow)) {
|
| + Label dividend_not_min_int;
|
| + __ cmp(dividend, kMinInt);
|
| + __ j(not_zero, ÷nd_not_min_int, Label::kNear);
|
| + __ cmp(divisor, -1);
|
| + DeoptimizeIf(zero, instr->environment());
|
| + __ bind(÷nd_not_min_int);
|
| + }
|
| +
|
| + // Sign extend to edx (= remainder).
|
| + __ cdq();
|
| + __ idiv(divisor);
|
| +
|
| + Label done;
|
| + __ test(remainder, remainder);
|
| + __ j(zero, &done, Label::kNear);
|
| + __ xor_(remainder, divisor);
|
| + __ sar(remainder, 31);
|
| + __ add(result, remainder);
|
| + __ bind(&done);
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoMulI(LMulI* instr) {
|
| Register left = ToRegister(instr->left());
|
| LOperand* right = instr->right();
|
|
|