| Index: src/arm/lithium-codegen-arm.cc
 | 
| ===================================================================
 | 
| --- src/arm/lithium-codegen-arm.cc	(revision 13153)
 | 
| +++ src/arm/lithium-codegen-arm.cc	(working copy)
 | 
| @@ -1421,25 +1421,68 @@
 | 
|    const Register remainder = ToRegister(instr->temp());
 | 
|    const Register scratch = scratch0();
 | 
|  
 | 
| -  // We only optimize this for division by constants, because the standard
 | 
| -  // integer division routine is usually slower than transitionning to VFP.
 | 
| -  // This could be optimized on processors with SDIV available.
 | 
| -  ASSERT(instr->right()->IsConstantOperand());
 | 
| -  int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right()));
 | 
| -  if (divisor < 0) {
 | 
| -    __ cmp(left, Operand(0));
 | 
| +  if (!CpuFeatures::IsSupported(SUDIV)) {
 | 
| +    // If the CPU doesn't support sdiv instruction, we only optimize when we
 | 
| +    // have magic numbers for the divisor. The standard integer division routine
 | 
| +    // is usually slower than transitionning to VFP.
 | 
| +    ASSERT(instr->right()->IsConstantOperand());
 | 
| +    int32_t divisor = ToInteger32(LConstantOperand::cast(instr->right()));
 | 
| +    ASSERT(LChunkBuilder::HasMagicNumberForDivisor(divisor));
 | 
| +    if (divisor < 0) {
 | 
| +      __ cmp(left, Operand(0));
 | 
| +      DeoptimizeIf(eq, instr->environment());
 | 
| +    }
 | 
| +    EmitSignedIntegerDivisionByConstant(result,
 | 
| +                                        left,
 | 
| +                                        divisor,
 | 
| +                                        remainder,
 | 
| +                                        scratch,
 | 
| +                                        instr->environment());
 | 
| +    // We performed a truncating division. Correct the result if necessary.
 | 
| +    __ cmp(remainder, Operand(0));
 | 
| +    __ teq(remainder, Operand(divisor), ne);
 | 
| +    __ sub(result, result, Operand(1), LeaveCC, mi);
 | 
| +  } else {
 | 
| +    CpuFeatures::Scope scope(SUDIV);
 | 
| +    const Register right = ToRegister(instr->right());
 | 
| +
 | 
| +    // Check for x / 0.
 | 
| +    __ cmp(right, Operand(0));
 | 
|      DeoptimizeIf(eq, instr->environment());
 | 
| +
 | 
| +    // Check for (kMinInt / -1).
 | 
| +    if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
 | 
| +      Label left_not_min_int;
 | 
| +      __ cmp(left, Operand(kMinInt));
 | 
| +      __ b(ne, &left_not_min_int);
 | 
| +      __ cmp(right, Operand(-1));
 | 
| +      DeoptimizeIf(eq, instr->environment());
 | 
| +      __ bind(&left_not_min_int);
 | 
| +    }
 | 
| +
 | 
| +    // Check for (0 / -x) that will produce negative zero.
 | 
| +    if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
 | 
| +      __ cmp(right, Operand(0));
 | 
| +      __ cmp(left, Operand(0), mi);
 | 
| +      // "right" can't be null because the code would have already been
 | 
| +      // deoptimized. The Z flag is set only if (right < 0) and (left == 0).
 | 
| +      // In this case we need to deoptimize to produce a -0.
 | 
| +      DeoptimizeIf(eq, instr->environment());
 | 
| +    }
 | 
| +
 | 
| +    Label done;
 | 
| +    __ sdiv(result, left, right);
 | 
| +    // If both operands have the same sign then we are done.
 | 
| +    __ eor(remainder, left, Operand(right), SetCC);
 | 
| +    __ b(pl, &done);
 | 
| +
 | 
| +    // Check if the result needs to be corrected.
 | 
| +    __ mls(remainder, result, right, left);
 | 
| +    __ cmp(remainder, Operand(0));
 | 
| +    __ sub(result, result, Operand(1), LeaveCC, ne);
 | 
| +
 | 
| +    __ bind(&done);
 | 
|    }
 | 
| -  EmitSignedIntegerDivisionByConstant(result,
 | 
| -                                      left,
 | 
| -                                      divisor,
 | 
| -                                      remainder,
 | 
| -                                      scratch,
 | 
| -                                      instr->environment());
 | 
| -  // We operated a truncating division. Correct the result if necessary.
 | 
| -  __ cmp(remainder, Operand(0));
 | 
| -  __ teq(remainder, Operand(divisor), ne);
 | 
| -  __ sub(result, result, Operand(1), LeaveCC, mi);
 | 
|  }
 | 
|  
 | 
|  
 | 
| 
 |