| Index: src/arm/lithium-arm.cc
|
| diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
|
| index 548da2e40904f936f6b1940d390a2fd188e70287..d9f9053afb622d60c9198db0f48c138f167ea0c9 100644
|
| --- a/src/arm/lithium-arm.cc
|
| +++ b/src/arm/lithium-arm.cc
|
| @@ -1446,43 +1446,61 @@ LInstruction* LChunkBuilder::DoMathFloorOfDiv(HMathFloorOfDiv* instr) {
|
|
|
|
|
| LInstruction* LChunkBuilder::DoMod(HMod* instr) {
|
| + HValue* left = instr->left();
|
| + HValue* right = instr->right();
|
| if (instr->representation().IsInteger32()) {
|
| - ASSERT(instr->left()->representation().IsInteger32());
|
| - ASSERT(instr->right()->representation().IsInteger32());
|
| -
|
| - LModI* mod;
|
| + ASSERT(left->representation().IsInteger32());
|
| + ASSERT(right->representation().IsInteger32());
|
| if (instr->HasPowerOf2Divisor()) {
|
| - ASSERT(!instr->CheckFlag(HValue::kCanBeDivByZero));
|
| - LOperand* value = UseRegisterAtStart(instr->left());
|
| - mod = new(zone()) LModI(value, UseOrConstant(instr->right()));
|
| - } else {
|
| - LOperand* dividend = UseRegister(instr->left());
|
| - LOperand* divisor = UseRegister(instr->right());
|
| - mod = new(zone()) LModI(dividend,
|
| - divisor,
|
| - TempRegister(),
|
| - FixedTemp(d10),
|
| - FixedTemp(d11));
|
| - }
|
| -
|
| - if (instr->CheckFlag(HValue::kBailoutOnMinusZero) ||
|
| - instr->CheckFlag(HValue::kCanBeDivByZero) ||
|
| - instr->CheckFlag(HValue::kCanOverflow)) {
|
| + ASSERT(!right->CanBeZero());
|
| + LModI* mod = new(zone()) LModI(UseRegisterAtStart(left),
|
| + UseOrConstant(right));
|
| + LInstruction* result = DefineAsRegister(mod);
|
| + return (left->CanBeNegative() &&
|
| + instr->CheckFlag(HValue::kBailoutOnMinusZero))
|
| + ? AssignEnvironment(result)
|
| + : result;
|
| + } else if (instr->has_fixed_right_arg()) {
|
| + LModI* mod = new(zone()) LModI(UseRegisterAtStart(left),
|
| + UseRegisterAtStart(right));
|
| return AssignEnvironment(DefineAsRegister(mod));
|
| + } else if (CpuFeatures::IsSupported(SUDIV)) {
|
| + LModI* mod = new(zone()) LModI(UseRegister(left),
|
| + UseRegister(right));
|
| + LInstruction* result = DefineAsRegister(mod);
|
| + return (right->CanBeZero() ||
|
| + (left->RangeCanInclude(kMinInt) &&
|
| + right->RangeCanInclude(-1) &&
|
| + instr->CheckFlag(HValue::kBailoutOnMinusZero)) ||
|
| + (left->CanBeNegative() &&
|
| + instr->CanBeZero() &&
|
| + instr->CheckFlag(HValue::kBailoutOnMinusZero)))
|
| + ? AssignEnvironment(result)
|
| + : result;
|
| } else {
|
| - return DefineAsRegister(mod);
|
| + LModI* mod = new(zone()) LModI(UseRegister(left),
|
| + UseRegister(right),
|
| + FixedTemp(d10),
|
| + FixedTemp(d11));
|
| + LInstruction* result = DefineAsRegister(mod);
|
| + return (right->CanBeZero() ||
|
| + (left->CanBeNegative() &&
|
| + instr->CanBeZero() &&
|
| + instr->CheckFlag(HValue::kBailoutOnMinusZero)))
|
| + ? AssignEnvironment(result)
|
| + : result;
|
| }
|
| } else if (instr->representation().IsSmiOrTagged()) {
|
| return DoArithmeticT(Token::MOD, instr);
|
| } else {
|
| ASSERT(instr->representation().IsDouble());
|
| - // We call a C function for double modulo. It can't trigger a GC.
|
| - // We need to use fixed result register for the call.
|
| + // We call a C function for double modulo. It can't trigger a GC. We need
|
| + // to use fixed result register for the call.
|
| // TODO(fschneider): Allow any register as input registers.
|
| - LOperand* left = UseFixedDouble(instr->left(), d1);
|
| - LOperand* right = UseFixedDouble(instr->right(), d2);
|
| - LArithmeticD* result = new(zone()) LArithmeticD(Token::MOD, left, right);
|
| - return MarkAsCall(DefineFixedDouble(result, d1), instr);
|
| + LArithmeticD* mod = new(zone()) LArithmeticD(Token::MOD,
|
| + UseFixedDouble(left, d1),
|
| + UseFixedDouble(right, d2));
|
| + return MarkAsCall(DefineFixedDouble(mod, d1), instr);
|
| }
|
| }
|
|
|
|
|