Chromium Code Reviews| Index: src/arm/lithium-codegen-arm.cc |
| diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc |
| index d1d4fe053461b5bcce44db6d49b28046145de0ca..25c81970193d1799243f4525d370cf753da5e114 100644 |
| --- a/src/arm/lithium-codegen-arm.cc |
| +++ b/src/arm/lithium-codegen-arm.cc |
| @@ -1404,21 +1404,6 @@ void LCodeGen::EmitSignedIntegerDivisionByConstant( |
| void LCodeGen::DoDivI(LDivI* instr) { |
| - class DeferredDivI: public LDeferredCode { |
| - public: |
| - DeferredDivI(LCodeGen* codegen, LDivI* instr) |
| - : LDeferredCode(codegen), instr_(instr) { } |
| - virtual void Generate() { |
| - codegen()->DoDeferredBinaryOpStub(instr_->pointer_map(), |
| - instr_->left(), |
| - instr_->right(), |
| - Token::DIV); |
| - } |
| - virtual LInstruction* instr() { return instr_; } |
| - private: |
| - LDivI* instr_; |
| - }; |
| - |
| if (instr->hydrogen()->HasPowerOf2Divisor()) { |
| Register dividend = ToRegister(instr->left()); |
| int32_t divisor = |
| @@ -1485,40 +1470,32 @@ void LCodeGen::DoDivI(LDivI* instr) { |
| __ bind(&left_not_min_int); |
| } |
| - Label done, deoptimize; |
| - // Test for a few common cases first. |
| - __ cmp(right, Operand(1)); |
| - __ mov(result, left, LeaveCC, eq); |
| - __ b(eq, &done); |
| - |
| - __ cmp(right, Operand(2)); |
| - __ tst(left, Operand(1), eq); |
| - __ mov(result, Operand(left, ASR, 1), LeaveCC, eq); |
| - __ b(eq, &done); |
| - |
| - __ cmp(right, Operand(4)); |
| - __ tst(left, Operand(3), eq); |
| - __ mov(result, Operand(left, ASR, 2), LeaveCC, eq); |
| - __ b(eq, &done); |
| - |
| - // Call the stub. The numbers in r0 and r1 have |
| - // to be tagged to Smis. If that is not possible, deoptimize. |
| - DeferredDivI* deferred = new(zone()) DeferredDivI(this, instr); |
| - |
| - __ TrySmiTag(left, &deoptimize); |
| - __ TrySmiTag(right, &deoptimize); |
| - |
| - __ b(al, deferred->entry()); |
| - __ bind(deferred->exit()); |
| - |
| - // If the result in r0 is a Smi, untag it, else deoptimize. |
| - __ JumpIfNotSmi(result, &deoptimize); |
| - __ SmiUntag(result); |
| - __ b(&done); |
| + if (CpuFeatures::IsSupported(SUDIV)) { |
| + CpuFeatureScope scope(masm(), SUDIV); |
| + __ sdiv(result, left, right); |
| - __ bind(&deoptimize); |
| - DeoptimizeIf(al, instr->environment()); |
| - __ bind(&done); |
| + // Compute remainder and deopt if it's not zero. |
| + const Register remainder = scratch0(); |
| + __ mls(remainder, result, right, left); |
| + __ cmp(remainder, Operand::Zero()); |
| + DeoptimizeIf(ne, instr->environment()); |
| + } else { |
| + const DoubleRegister vleft = ToDoubleRegister(instr->temp()); |
| + const DoubleRegister vright = double_scratch0(); |
| + __ vmov(vleft.low(), left); |
| + __ vmov(vright.low(), right); |
| + __ vcvt_f64_s32(vleft, vleft.low()); |
| + __ vcvt_f64_s32(vright, vright.low()); |
| + __ vdiv(vleft, vleft, vright); // vleft now contains the result. |
| + |
| + // Convert back to integer32; deopt if exact conversion is not possible. |
| + // Use vright as scratch register. |
|
ulan
2013/06/10 11:18:33
I think we can use TryDoubleToInt32Exact() here.
Jakob Kummerow
2013/06/10 12:20:27
Good point, right now we could do that.
My next pa
|
| + __ vcvt_s32_f64(vright.low(), vleft); |
| + __ vmov(result, vright.low()); |
| + __ vcvt_f64_s32(vright, vright.low()); |
| + __ VFPCompareAndSetFlags(vleft, vright); |
| + DeoptimizeIf(ne, instr->environment()); |
| + } |
| } |
| @@ -1617,38 +1594,6 @@ void LCodeGen::DoMathFloorOfDiv(LMathFloorOfDiv* instr) { |
| } |
| -void LCodeGen::DoDeferredBinaryOpStub(LPointerMap* pointer_map, |
| - LOperand* left_argument, |
| - LOperand* right_argument, |
| - Token::Value op) { |
| - Register left = ToRegister(left_argument); |
| - Register right = ToRegister(right_argument); |
| - |
| - PushSafepointRegistersScope scope(this, Safepoint::kWithRegistersAndDoubles); |
| - // Move left to r1 and right to r0 for the stub call. |
| - if (left.is(r1)) { |
| - __ Move(r0, right); |
| - } else if (left.is(r0) && right.is(r1)) { |
| - __ Swap(r0, r1, r2); |
| - } else if (left.is(r0)) { |
| - ASSERT(!right.is(r1)); |
| - __ mov(r1, r0); |
| - __ mov(r0, right); |
| - } else { |
| - ASSERT(!left.is(r0) && !right.is(r0)); |
| - __ mov(r0, right); |
| - __ mov(r1, left); |
| - } |
| - BinaryOpStub stub(op, OVERWRITE_LEFT); |
| - __ CallStub(&stub); |
| - RecordSafepointWithRegistersAndDoubles(pointer_map, |
| - 0, |
| - Safepoint::kNoLazyDeopt); |
| - // Overwrite the stored value of r0 with the result of the stub. |
| - __ StoreToSafepointRegistersAndDoublesSlot(r0, r0); |
| -} |
| - |
| - |
| void LCodeGen::DoMulI(LMulI* instr) { |
| Register scratch = scratch0(); |
| Register result = ToRegister(instr->result()); |