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