| Index: src/arm/lithium-codegen-arm.cc | 
| diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc | 
| index 2c916f6ad67b847376a3656a5189f25d1cb0c18c..3350cf90f0d544e1df3308aae3acfd925f438652 100644 | 
| --- a/src/arm/lithium-codegen-arm.cc | 
| +++ b/src/arm/lithium-codegen-arm.cc | 
| @@ -1427,7 +1427,7 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) { | 
| __ vmov(r2, r3, right); | 
| __ CallCFunction(ExternalReference::double_fp_operation(Token::MOD), 4); | 
| // Move the result in the double result register. | 
| -      __ vmov(ToDoubleRegister(instr->result()), r0, r1); | 
| +      __ GetCFunctionDoubleResult(ToDoubleRegister(instr->result())); | 
|  | 
| // Restore r0-r3. | 
| __ ldm(ia_w, sp, r0.bit() | r1.bit() | r2.bit() | r3.bit()); | 
| @@ -2861,6 +2861,64 @@ void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { | 
| } | 
|  | 
|  | 
| +void LCodeGen::DoPower(LPower* instr) { | 
| +  LOperand* left = instr->InputAt(0); | 
| +  LOperand* right = instr->InputAt(1); | 
| +  Register scratch = scratch0(); | 
| +  DoubleRegister result_reg = ToDoubleRegister(instr->result()); | 
| +  Representation exponent_type = instr->hydrogen()->right()->representation(); | 
| +  if (exponent_type.IsDouble()) { | 
| +    // Prepare arguments and call C function. | 
| +    __ PrepareCallCFunction(4, scratch); | 
| +    __ vmov(r0, r1, ToDoubleRegister(left)); | 
| +    __ vmov(r2, r3, ToDoubleRegister(right)); | 
| +    __ CallCFunction(ExternalReference::power_double_double_function(), 4); | 
| +  } else if (exponent_type.IsInteger32()) { | 
| +    ASSERT(ToRegister(right).is(r0)); | 
| +    // Prepare arguments and call C function. | 
| +    __ PrepareCallCFunction(4, scratch); | 
| +    __ mov(r2, ToRegister(right)); | 
| +    __ vmov(r0, r1, ToDoubleRegister(left)); | 
| +    __ CallCFunction(ExternalReference::power_double_int_function(), 4); | 
| +  } else { | 
| +    ASSERT(exponent_type.IsTagged()); | 
| +    ASSERT(instr->hydrogen()->left()->representation().IsDouble()); | 
| + | 
| +    Register right_reg = ToRegister(right); | 
| + | 
| +    // Check for smi on the right hand side. | 
| +    Label non_smi, call; | 
| +    __ JumpIfNotSmi(right_reg, &non_smi); | 
| + | 
| +    // Untag smi and convert it to a double. | 
| +    __ SmiUntag(right_reg); | 
| +    SwVfpRegister single_scratch = double_scratch0().low(); | 
| +    __ vmov(single_scratch, right_reg); | 
| +    __ vcvt_f64_s32(result_reg, single_scratch); | 
| +    __ jmp(&call); | 
| + | 
| +    // Heap number map check. | 
| +    __ bind(&non_smi); | 
| +    __ ldr(scratch, FieldMemOperand(right_reg, HeapObject::kMapOffset)); | 
| +    __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 
| +    __ cmp(scratch, Operand(ip)); | 
| +    DeoptimizeIf(ne, instr->environment()); | 
| +    int32_t value_offset = HeapNumber::kValueOffset - kHeapObjectTag; | 
| +    __ add(scratch, right_reg, Operand(value_offset)); | 
| +    __ vldr(result_reg, scratch, 0); | 
| + | 
| +    // Prepare arguments and call C function. | 
| +    __ bind(&call); | 
| +    __ PrepareCallCFunction(4, scratch); | 
| +    __ vmov(r0, r1, ToDoubleRegister(left)); | 
| +    __ vmov(r2, r3, result_reg); | 
| +    __ CallCFunction(ExternalReference::power_double_double_function(), 4); | 
| +  } | 
| +  // Store the result in the result register. | 
| +  __ GetCFunctionDoubleResult(result_reg); | 
| +} | 
| + | 
| + | 
| void LCodeGen::DoUnaryMathOperation(LUnaryMathOperation* instr) { | 
| switch (instr->op()) { | 
| case kMathAbs: | 
|  |