| Index: src/arm/lithium-codegen-arm.cc | 
| diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc | 
| index 434090fcdeeb2dff3fb5d3b35e166976361ada66..46e0754ddd0cd28f9f4274397f3f12af619f72ac 100644 | 
| --- a/src/arm/lithium-codegen-arm.cc | 
| +++ b/src/arm/lithium-codegen-arm.cc | 
| @@ -873,7 +873,6 @@ void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { | 
| void LCodeGen::DoModI(LModI* instr) { | 
| if (instr->hydrogen()->HasPowerOf2Divisor()) { | 
| Register dividend = ToRegister(instr->InputAt(0)); | 
| -    Register result = ToRegister(instr->result()); | 
|  | 
| int32_t divisor = | 
| HConstant::cast(instr->hydrogen()->right())->Integer32Value(); | 
| @@ -883,15 +882,17 @@ void LCodeGen::DoModI(LModI* instr) { | 
| Label positive_dividend, done; | 
| __ cmp(dividend, Operand(0)); | 
| __ b(pl, &positive_dividend); | 
| -    __ rsb(result, dividend, Operand(0)); | 
| -    __ and_(dividend, result, Operand(divisor - 1), SetCC); | 
| +    __ rsb(dividend, dividend, Operand(0)); | 
| +    __ and_(dividend, dividend, Operand(divisor - 1)); | 
| +    __ rsb(dividend, dividend, Operand(0), SetCC); | 
| if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 
| -      DeoptimizeIf(eq, instr->environment()); | 
| +      __ b(ne, &done); | 
| +      DeoptimizeIf(al, instr->environment()); | 
| +    } else { | 
| +      __ b(&done); | 
| } | 
| -    __ rsb(result, dividend, Operand(0)); | 
| -    __ b(&done); | 
| __ bind(&positive_dividend); | 
| -    __ and_(result, dividend, Operand(divisor - 1)); | 
| +    __ and_(dividend, dividend, Operand(divisor - 1)); | 
| __ bind(&done); | 
| return; | 
| } | 
| @@ -907,6 +908,8 @@ void LCodeGen::DoModI(LModI* instr) { | 
| DwVfpRegister divisor = ToDoubleRegister(instr->TempAt(2)); | 
| DwVfpRegister quotient = double_scratch0(); | 
|  | 
| +  ASSERT(result.is(left)); | 
| + | 
| ASSERT(!dividend.is(divisor)); | 
| ASSERT(!dividend.is(quotient)); | 
| ASSERT(!divisor.is(quotient)); | 
| @@ -922,8 +925,6 @@ void LCodeGen::DoModI(LModI* instr) { | 
| DeoptimizeIf(eq, instr->environment()); | 
| } | 
|  | 
| -  __ Move(result, left); | 
| - | 
| // (0 % x) must yield 0 (if x is finite, which is the case here). | 
| __ cmp(left, Operand(0)); | 
| __ b(eq, &done); | 
| @@ -1119,9 +1120,9 @@ void LCodeGen::DoDeferredBinaryOpStub(LTemplateInstruction<1, 2, T>* instr, | 
|  | 
|  | 
| void LCodeGen::DoMulI(LMulI* instr) { | 
| +  ASSERT(instr->result()->Equals(instr->InputAt(0))); | 
| Register scratch = scratch0(); | 
| Register result = ToRegister(instr->result()); | 
| -  // Note that result may alias left. | 
| Register left = ToRegister(instr->InputAt(0)); | 
| LOperand* right_op = instr->InputAt(1); | 
|  | 
| @@ -1154,7 +1155,7 @@ void LCodeGen::DoMulI(LMulI* instr) { | 
| __ mov(result, Operand(0)); | 
| break; | 
| case 1: | 
| -        __ Move(result, left); | 
| +        // Nothing to do. | 
| break; | 
| default: | 
| // Multiplying by powers of two and powers of two plus or minus | 
| @@ -1216,29 +1217,30 @@ void LCodeGen::DoMulI(LMulI* instr) { | 
|  | 
|  | 
| void LCodeGen::DoBitI(LBitI* instr) { | 
| -  LOperand* left_op = instr->InputAt(0); | 
| -  LOperand* right_op = instr->InputAt(1); | 
| -  ASSERT(left_op->IsRegister()); | 
| -  Register left = ToRegister(left_op); | 
| -  Register result = ToRegister(instr->result()); | 
| -  Operand right(no_reg); | 
| +  LOperand* left = instr->InputAt(0); | 
| +  LOperand* right = instr->InputAt(1); | 
| +  ASSERT(left->Equals(instr->result())); | 
| +  ASSERT(left->IsRegister()); | 
| +  Register result = ToRegister(left); | 
| +  Operand right_operand(no_reg); | 
|  | 
| -  if (right_op->IsStackSlot() || right_op->IsArgument()) { | 
| -    right = Operand(EmitLoadRegister(right_op, ip)); | 
| +  if (right->IsStackSlot() || right->IsArgument()) { | 
| +    Register right_reg = EmitLoadRegister(right, ip); | 
| +    right_operand = Operand(right_reg); | 
| } else { | 
| -    ASSERT(right_op->IsRegister() || right_op->IsConstantOperand()); | 
| -    right = ToOperand(right_op); | 
| +    ASSERT(right->IsRegister() || right->IsConstantOperand()); | 
| +    right_operand = ToOperand(right); | 
| } | 
|  | 
| switch (instr->op()) { | 
| case Token::BIT_AND: | 
| -      __ and_(result, left, right); | 
| +      __ and_(result, ToRegister(left), right_operand); | 
| break; | 
| case Token::BIT_OR: | 
| -      __ orr(result, left, right); | 
| +      __ orr(result, ToRegister(left), right_operand); | 
| break; | 
| case Token::BIT_XOR: | 
| -      __ eor(result, left, right); | 
| +      __ eor(result, ToRegister(left), right_operand); | 
| break; | 
| default: | 
| UNREACHABLE(); | 
| @@ -1248,62 +1250,54 @@ void LCodeGen::DoBitI(LBitI* instr) { | 
|  | 
|  | 
| void LCodeGen::DoShiftI(LShiftI* instr) { | 
| -  // Both 'left' and 'right' are "used at start" (see LCodeGen::DoShift), so | 
| -  // result may alias either of them. | 
| -  LOperand* right_op = instr->InputAt(1); | 
| -  Register left = ToRegister(instr->InputAt(0)); | 
| -  Register result = ToRegister(instr->result()); | 
| Register scratch = scratch0(); | 
| -  if (right_op->IsRegister()) { | 
| -    // Mask the right_op operand. | 
| -    __ and_(scratch, ToRegister(right_op), Operand(0x1F)); | 
| +  LOperand* left = instr->InputAt(0); | 
| +  LOperand* right = instr->InputAt(1); | 
| +  ASSERT(left->Equals(instr->result())); | 
| +  ASSERT(left->IsRegister()); | 
| +  Register result = ToRegister(left); | 
| +  if (right->IsRegister()) { | 
| +    // Mask the right operand. | 
| +    __ and_(scratch, ToRegister(right), Operand(0x1F)); | 
| switch (instr->op()) { | 
| case Token::SAR: | 
| -        __ mov(result, Operand(left, ASR, scratch)); | 
| +        __ mov(result, Operand(result, ASR, scratch)); | 
| break; | 
| case Token::SHR: | 
| if (instr->can_deopt()) { | 
| -          __ mov(result, Operand(left, LSR, scratch), SetCC); | 
| +          __ mov(result, Operand(result, LSR, scratch), SetCC); | 
| DeoptimizeIf(mi, instr->environment()); | 
| } else { | 
| -          __ mov(result, Operand(left, LSR, scratch)); | 
| +          __ mov(result, Operand(result, LSR, scratch)); | 
| } | 
| break; | 
| case Token::SHL: | 
| -        __ mov(result, Operand(left, LSL, scratch)); | 
| +        __ mov(result, Operand(result, LSL, scratch)); | 
| break; | 
| default: | 
| UNREACHABLE(); | 
| break; | 
| } | 
| } else { | 
| -    // Mask the right_op operand. | 
| -    int value = ToInteger32(LConstantOperand::cast(right_op)); | 
| +    int value = ToInteger32(LConstantOperand::cast(right)); | 
| uint8_t shift_count = static_cast<uint8_t>(value & 0x1F); | 
| switch (instr->op()) { | 
| case Token::SAR: | 
| if (shift_count != 0) { | 
| -          __ mov(result, Operand(left, ASR, shift_count)); | 
| -        } else { | 
| -          __ Move(result, left); | 
| +          __ mov(result, Operand(result, ASR, shift_count)); | 
| } | 
| break; | 
| case Token::SHR: | 
| -        if (shift_count != 0) { | 
| -          __ mov(result, Operand(left, LSR, shift_count)); | 
| +        if (shift_count == 0 && instr->can_deopt()) { | 
| +          __ tst(result, Operand(0x80000000)); | 
| +          DeoptimizeIf(ne, instr->environment()); | 
| } else { | 
| -          if (instr->can_deopt()) { | 
| -            __ tst(left, Operand(0x80000000)); | 
| -            DeoptimizeIf(ne, instr->environment()); | 
| -          } | 
| -          __ Move(result, left); | 
| +          __ mov(result, Operand(result, LSR, shift_count)); | 
| } | 
| break; | 
| case Token::SHL: | 
| if (shift_count != 0) { | 
| -          __ mov(result, Operand(left, LSL, shift_count)); | 
| -        } else { | 
| -          __ Move(result, left); | 
| +          __ mov(result, Operand(result, LSL, shift_count)); | 
| } | 
| break; | 
| default: | 
| @@ -1317,16 +1311,16 @@ void LCodeGen::DoShiftI(LShiftI* instr) { | 
| void LCodeGen::DoSubI(LSubI* instr) { | 
| LOperand* left = instr->InputAt(0); | 
| LOperand* right = instr->InputAt(1); | 
| -  LOperand* result = instr->result(); | 
| +  ASSERT(left->Equals(instr->result())); | 
| bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 
| SBit set_cond = can_overflow ? SetCC : LeaveCC; | 
|  | 
| if (right->IsStackSlot() || right->IsArgument()) { | 
| Register right_reg = EmitLoadRegister(right, ip); | 
| -    __ sub(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); | 
| +    __ sub(ToRegister(left), ToRegister(left), Operand(right_reg), set_cond); | 
| } else { | 
| ASSERT(right->IsRegister() || right->IsConstantOperand()); | 
| -    __ sub(ToRegister(result), ToRegister(left), ToOperand(right), set_cond); | 
| +    __ sub(ToRegister(left), ToRegister(left), ToOperand(right), set_cond); | 
| } | 
|  | 
| if (can_overflow) { | 
| @@ -1345,7 +1339,7 @@ void LCodeGen::DoConstantD(LConstantD* instr) { | 
| ASSERT(instr->result()->IsDoubleRegister()); | 
| DwVfpRegister result = ToDoubleRegister(instr->result()); | 
| double v = instr->value(); | 
| -  __ Vmov(result, v); | 
| +  __ vmov(result, v); | 
| } | 
|  | 
|  | 
| @@ -1394,16 +1388,14 @@ void LCodeGen::DoValueOf(LValueOf* instr) { | 
| Register input = ToRegister(instr->InputAt(0)); | 
| Register result = ToRegister(instr->result()); | 
| Register map = ToRegister(instr->TempAt(0)); | 
| +  ASSERT(input.is(result)); | 
| Label done; | 
|  | 
| // If the object is a smi return the object. | 
| -  __ tst(input, Operand(kSmiTagMask)); | 
| -  __ Move(result, input, eq); | 
| -  __ b(eq, &done); | 
| +  __ JumpIfSmi(input, &done); | 
|  | 
| // If the object is not a value type, return the object. | 
| __ CompareObjectType(input, map, map, JS_VALUE_TYPE); | 
| -  __ Move(result, input, ne); | 
| __ b(ne, &done); | 
| __ ldr(result, FieldMemOperand(input, JSValue::kValueOffset)); | 
|  | 
| @@ -1412,9 +1404,9 @@ void LCodeGen::DoValueOf(LValueOf* instr) { | 
|  | 
|  | 
| void LCodeGen::DoBitNotI(LBitNotI* instr) { | 
| -  Register input = ToRegister(instr->InputAt(0)); | 
| -  Register result = ToRegister(instr->result()); | 
| -  __ mvn(result, Operand(input)); | 
| +  LOperand* input = instr->InputAt(0); | 
| +  ASSERT(input->Equals(instr->result())); | 
| +  __ mvn(ToRegister(input), Operand(ToRegister(input))); | 
| } | 
|  | 
|  | 
| @@ -1432,16 +1424,16 @@ void LCodeGen::DoThrow(LThrow* instr) { | 
| void LCodeGen::DoAddI(LAddI* instr) { | 
| LOperand* left = instr->InputAt(0); | 
| LOperand* right = instr->InputAt(1); | 
| -  LOperand* result = instr->result(); | 
| +  ASSERT(left->Equals(instr->result())); | 
| bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow); | 
| SBit set_cond = can_overflow ? SetCC : LeaveCC; | 
|  | 
| if (right->IsStackSlot() || right->IsArgument()) { | 
| Register right_reg = EmitLoadRegister(right, ip); | 
| -    __ add(ToRegister(result), ToRegister(left), Operand(right_reg), set_cond); | 
| +    __ add(ToRegister(left), ToRegister(left), Operand(right_reg), set_cond); | 
| } else { | 
| ASSERT(right->IsRegister() || right->IsConstantOperand()); | 
| -    __ add(ToRegister(result), ToRegister(left), ToOperand(right), set_cond); | 
| +    __ add(ToRegister(left), ToRegister(left), ToOperand(right), set_cond); | 
| } | 
|  | 
| if (can_overflow) { | 
| @@ -1453,19 +1445,18 @@ void LCodeGen::DoAddI(LAddI* instr) { | 
| void LCodeGen::DoArithmeticD(LArithmeticD* instr) { | 
| DoubleRegister left = ToDoubleRegister(instr->InputAt(0)); | 
| DoubleRegister right = ToDoubleRegister(instr->InputAt(1)); | 
| -  DoubleRegister result = ToDoubleRegister(instr->result()); | 
| switch (instr->op()) { | 
| case Token::ADD: | 
| -      __ vadd(result, left, right); | 
| +      __ vadd(left, left, right); | 
| break; | 
| case Token::SUB: | 
| -      __ vsub(result, left, right); | 
| +      __ vsub(left, left, right); | 
| break; | 
| case Token::MUL: | 
| -      __ vmul(result, left, right); | 
| +      __ vmul(left, left, right); | 
| break; | 
| case Token::DIV: | 
| -      __ vdiv(result, left, right); | 
| +      __ vdiv(left, left, right); | 
| break; | 
| case Token::MOD: { | 
| // Save r0-r3 on the stack. | 
| @@ -1477,7 +1468,7 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) { | 
| ExternalReference::double_fp_operation(Token::MOD, isolate()), | 
| 0, 2); | 
| // Move the result in the double result register. | 
| -      __ GetCFunctionDoubleResult(result); | 
| +      __ GetCFunctionDoubleResult(ToDoubleRegister(instr->result())); | 
|  | 
| // Restore r0-r3. | 
| __ ldm(ia_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit()); | 
| @@ -1570,7 +1561,7 @@ void LCodeGen::DoBranch(LBranch* instr) { | 
|  | 
| // Test double values. Zero and NaN are false. | 
| Label call_stub; | 
| -      DoubleRegister dbl_scratch = double_scratch0(); | 
| +      DoubleRegister dbl_scratch = d0; | 
| Register scratch = scratch0(); | 
| __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); | 
| __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 
| @@ -2616,6 +2607,7 @@ void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { | 
| Register key = EmitLoadRegister(instr->key(), scratch0()); | 
| Register result = ToRegister(instr->result()); | 
| Register scratch = scratch0(); | 
| +  ASSERT(result.is(elements)); | 
|  | 
| // Load the result. | 
| __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); | 
| @@ -2935,8 +2927,8 @@ void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 
|  | 
|  | 
| void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 
| +  ASSERT(instr->InputAt(0)->Equals(instr->result())); | 
| Register input = ToRegister(instr->InputAt(0)); | 
| -  Register result = ToRegister(instr->result()); | 
| Register scratch = scratch0(); | 
|  | 
| // Deoptimize if not a heap number. | 
| @@ -2950,10 +2942,10 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 
| scratch = no_reg; | 
| __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); | 
| // Check the sign of the argument. If the argument is positive, just | 
| -  // return it. | 
| +  // return it. We do not need to patch the stack since |input| and | 
| +  // |result| are the same register and |input| would be restored | 
| +  // unchanged by popping safepoint registers. | 
| __ tst(exponent, Operand(HeapNumber::kSignMask)); | 
| -  // Move the input to the result if necessary. | 
| -  __ Move(result, input); | 
| __ b(eq, &done); | 
|  | 
| // Input is negative. Reverse its sign. | 
| @@ -2993,7 +2985,7 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 
| __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset)); | 
| __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset)); | 
|  | 
| -    __ StoreToSafepointRegisterSlot(tmp1, result); | 
| +    __ StoreToSafepointRegisterSlot(tmp1, input); | 
| } | 
|  | 
| __ bind(&done); | 
| @@ -3002,13 +2994,11 @@ void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 
|  | 
| void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { | 
| Register input = ToRegister(instr->InputAt(0)); | 
| -  Register result = ToRegister(instr->result()); | 
| __ cmp(input, Operand(0)); | 
| -  __ Move(result, input, pl); | 
| // We can make rsb conditional because the previous cmp instruction | 
| // will clear the V (overflow) flag and rsb won't set this flag | 
| // if input is positive. | 
| -  __ rsb(result, input, Operand(0), SetCC, mi); | 
| +  __ rsb(input, input, Operand(0), SetCC, mi); | 
| // Deoptimize on overflow. | 
| DeoptimizeIf(vs, instr->environment()); | 
| } | 
| @@ -3028,11 +3018,11 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { | 
| LUnaryMathOperation* instr_; | 
| }; | 
|  | 
| +  ASSERT(instr->InputAt(0)->Equals(instr->result())); | 
| Representation r = instr->hydrogen()->value()->representation(); | 
| if (r.IsDouble()) { | 
| DwVfpRegister input = ToDoubleRegister(instr->InputAt(0)); | 
| -    DwVfpRegister result = ToDoubleRegister(instr->result()); | 
| -    __ vabs(result, input); | 
| +    __ vabs(input, input); | 
| } else if (r.IsInteger32()) { | 
| EmitIntegerMathAbs(instr); | 
| } else { | 
| @@ -3110,7 +3100,7 @@ void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { | 
| // Save the original sign for later comparison. | 
| __ and_(scratch2, scratch1, Operand(HeapNumber::kSignMask)); | 
|  | 
| -  __ Vmov(double_scratch0(), 0.5); | 
| +  __ vmov(double_scratch0(), 0.5); | 
| __ vadd(input, input, double_scratch0()); | 
|  | 
| // Check sign of the result: if the sign changed, the input | 
| @@ -3147,17 +3137,24 @@ void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { | 
|  | 
| void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { | 
| DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); | 
| -  DoubleRegister result = ToDoubleRegister(instr->result()); | 
| -  __ vsqrt(result, input); | 
| +  ASSERT(ToDoubleRegister(instr->result()).is(input)); | 
| +  __ vsqrt(input, input); | 
| } | 
|  | 
|  | 
| void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { | 
| DoubleRegister input = ToDoubleRegister(instr->InputAt(0)); | 
| -  DoubleRegister result = ToDoubleRegister(instr->result()); | 
| +  Register scratch = scratch0(); | 
| +  SwVfpRegister single_scratch = double_scratch0().low(); | 
| +  DoubleRegister double_scratch = double_scratch0(); | 
| +  ASSERT(ToDoubleRegister(instr->result()).is(input)); | 
| + | 
| // Add +0 to convert -0 to +0. | 
| -  __ vadd(result, input, kDoubleRegZero); | 
| -  __ vsqrt(result, result); | 
| +  __ mov(scratch, Operand(0)); | 
| +  __ vmov(single_scratch, scratch); | 
| +  __ vcvt_f64_s32(double_scratch, single_scratch); | 
| +  __ vadd(input, input, double_scratch); | 
| +  __ vsqrt(input, input); | 
| } | 
|  | 
|  | 
| @@ -3756,8 +3753,8 @@ void LCodeGen::DoNumberTagI(LNumberTagI* instr) { | 
| void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { | 
| Label slow; | 
| Register reg = ToRegister(instr->InputAt(0)); | 
| -  DoubleRegister dbl_scratch = double_scratch0(); | 
| -  SwVfpRegister flt_scratch = dbl_scratch.low(); | 
| +  DoubleRegister dbl_scratch = d0; | 
| +  SwVfpRegister flt_scratch = s0; | 
|  | 
| // Preserve the value of all registers. | 
| PushSafepointRegistersScope scope(this, Safepoint::kWithRegisters); | 
| @@ -3866,8 +3863,8 @@ void LCodeGen::EmitNumberUntagD(Register input_reg, | 
| bool deoptimize_on_undefined, | 
| LEnvironment* env) { | 
| Register scratch = scratch0(); | 
| -  SwVfpRegister flt_scratch = double_scratch0().low(); | 
| -  ASSERT(!result_reg.is(double_scratch0())); | 
| +  SwVfpRegister flt_scratch = s0; | 
| +  ASSERT(!result_reg.is(d0)); | 
|  | 
| Label load_smi, heap_number, done; | 
|  | 
|  |