Chromium Code Reviews| Index: src/arm/lithium-arm.cc |
| diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc |
| index 548da2e40904f936f6b1940d390a2fd188e70287..5bc6fa0f68df86579583aace5bddebdabb49fcd1 100644 |
| --- a/src/arm/lithium-arm.cc |
| +++ b/src/arm/lithium-arm.cc |
| @@ -1446,43 +1446,62 @@ 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), |
| + TempRegister(), |
| + 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), |
|
Rodolph Perfetta
2013/06/07 19:55:03
Technically not part of your patch but why are we
Sven Panne
2013/06/10 11:05:39
Good questions, but I don't have immediate answers
|
| + UseFixedDouble(right, d2)); |
| + return MarkAsCall(DefineFixedDouble(mod, d1), instr); |
| } |
| } |