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