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()); |