Chromium Code Reviews| Index: src/a64/lithium-codegen-a64.cc |
| diff --git a/src/a64/lithium-codegen-a64.cc b/src/a64/lithium-codegen-a64.cc |
| index e35aa2eb63e97a57a43477f5428b6e60c3ec4538..e42ff1089b139e2db96e15f232de2cf1a25714da 100644 |
| --- a/src/a64/lithium-codegen-a64.cc |
| +++ b/src/a64/lithium-codegen-a64.cc |
| @@ -1057,6 +1057,11 @@ void LCodeGen::DeoptimizeIfZero(Register rt, LEnvironment* environment) { |
| } |
| +void LCodeGen::DeoptimizeIfNotZero(Register rt, LEnvironment* environment) { |
| + DeoptimizeBranch(environment, reg_not_zero, rt); |
| +} |
| + |
| + |
| void LCodeGen::DeoptimizeIfNegative(Register rt, LEnvironment* environment) { |
| int sign_bit = rt.Is64Bits() ? kXSignBit : kWSignBit; |
| DeoptimizeBranch(environment, reg_bit_set, rt, sign_bit); |
| @@ -2610,6 +2615,39 @@ void LCodeGen::DoDivByPowerOf2I(LDivByPowerOf2I* instr) { |
| } |
| +void LCodeGen::DoDivByConstI(LDivByConstI* instr) { |
| + Register dividend = ToRegister32(instr->dividend()); |
| + int32_t divisor = instr->divisor(); |
| + Register result = ToRegister32(instr->result()); |
| + ASSERT(!AreAliased(dividend, result)); |
| + |
| + if (divisor == 0) { |
| + Deoptimize(instr->environment()); |
| + return; |
| + } |
| + |
| + // Check for (0 / -x) that will produce negative zero. |
| + HDiv* hdiv = instr->hydrogen(); |
| + if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && |
| + hdiv->left()->RangeCanInclude(0) && divisor < 0) { |
| + __ Cmp(dividend, 0); |
|
m.m.capewell
2014/03/07 11:37:29
DeoptimizeIfZero()
|
| + DeoptimizeIf(eq, instr->environment()); |
| + } |
| + |
| + __ FlooringDiv(result, dividend, Abs(divisor)); |
| + if (divisor < 0) __ Neg(result, result); |
| + |
| + if (!hdiv->CheckFlag(HInstruction::kAllUsesTruncatingToInt32)) { |
| + Register temp = ToRegister32(instr->temp()); |
| + ASSERT(!AreAliased(dividend, result, temp)); |
| + __ Sxtw(dividend.X(), dividend); |
| + __ Mov(temp, divisor); |
| + __ Smsubl(temp.X(), result, temp, dividend.X()); |
| + DeoptimizeIfNotZero(temp, instr->environment()); |
| + } |
| +} |
| + |
| + |
| void LCodeGen::DoDivI(LDivI* instr) { |
| Register dividend = ToRegister32(instr->left()); |
| Register divisor = ToRegister32(instr->right()); |
| @@ -3820,6 +3858,29 @@ void LCodeGen::DoFlooringDivByPowerOf2I(LFlooringDivByPowerOf2I* instr) { |
| } |
| +void LCodeGen::DoFlooringDivByConstI(LFlooringDivByConstI* instr) { |
| + Register dividend = ToRegister32(instr->dividend()); |
| + int32_t divisor = instr->divisor(); |
| + Register result = ToRegister32(instr->result()); |
| + ASSERT(!AreAliased(dividend, result)); |
| + |
| + if (divisor == 0) { |
| + Deoptimize(instr->environment()); |
| + return; |
| + } |
| + |
| + // Check for (0 / -x) that will produce negative zero. |
| + HMathFloorOfDiv* hdiv = instr->hydrogen(); |
| + if (hdiv->CheckFlag(HValue::kBailoutOnMinusZero) && |
| + hdiv->left()->RangeCanInclude(0) && divisor < 0) { |
| + __ Cmp(dividend, 0); |
| + DeoptimizeIf(eq, instr->environment()); |
| + } |
| + |
| + __ FlooringDiv(result, dividend, divisor); |
| +} |
| + |
| + |
| void LCodeGen::DoFlooringDivI(LFlooringDivI* instr) { |
| Register dividend = ToRegister32(instr->dividend()); |
| Register divisor = ToRegister32(instr->divisor()); |
| @@ -4079,6 +4140,35 @@ void LCodeGen::DoModByPowerOf2I(LModByPowerOf2I* instr) { |
| } |
| +void LCodeGen::DoModByConstI(LModByConstI* instr) { |
| + Register dividend = ToRegister32(instr->dividend()); |
| + int32_t divisor = instr->divisor(); |
| + Register result = ToRegister32(instr->result()); |
| + Register temp = ToRegister32(instr->temp()); |
| + ASSERT(!AreAliased(dividend, result, temp)); |
| + |
| + if (divisor == 0) { |
| + Deoptimize(instr->environment()); |
| + return; |
| + } |
| + |
| + __ FlooringDiv(result, dividend, Abs(divisor)); |
| + __ Sxtw(dividend.X(), dividend); |
| + __ Mov(temp, Abs(divisor)); |
| + __ Smsubl(result.X(), result, temp, dividend.X()); |
| + |
| + // Check for negative zero. |
| + HMod* hmod = instr->hydrogen(); |
| + if (hmod->CheckFlag(HValue::kBailoutOnMinusZero) && |
| + hmod->left()->CanBeNegative()) { |
| + Label remainder_not_zero; |
| + __ Cbnz(result, &remainder_not_zero); |
| + DeoptimizeIfNegative(dividend, instr->environment()); |
| + __ bind(&remainder_not_zero); |
| + } |
| +} |
| + |
| + |
| void LCodeGen::DoModI(LModI* instr) { |
| Register dividend = ToRegister32(instr->left()); |
| Register divisor = ToRegister32(instr->right()); |