| Index: src/x64/lithium-codegen-x64.cc
 | 
| diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
 | 
| index c0d73d8f2f479f08eaef3d01abdf224407f2daa6..d617c17be8c43e69faa935539111cd29f9d55d0b 100644
 | 
| --- a/src/x64/lithium-codegen-x64.cc
 | 
| +++ b/src/x64/lithium-codegen-x64.cc
 | 
| @@ -2880,58 +2880,39 @@ void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
 | 
|  
 | 
|  
 | 
|  void LCodeGen::DoPower(LPower* instr) {
 | 
| -  LOperand* left = instr->InputAt(0);
 | 
| -  XMMRegister left_reg = ToDoubleRegister(left);
 | 
| -  ASSERT(!left_reg.is(xmm1));
 | 
| -  LOperand* right = instr->InputAt(1);
 | 
| -  XMMRegister result_reg = ToDoubleRegister(instr->result());
 | 
|    Representation exponent_type = instr->hydrogen()->right()->representation();
 | 
| -  if (exponent_type.IsDouble()) {
 | 
| -    __ PrepareCallCFunction(2);
 | 
| -    // Move arguments to correct registers
 | 
| -    __ movaps(xmm0, left_reg);
 | 
| -    ASSERT(ToDoubleRegister(right).is(xmm1));
 | 
| -    __ CallCFunction(
 | 
| -        ExternalReference::power_double_double_function(isolate()), 2);
 | 
| -  } else if (exponent_type.IsInteger32()) {
 | 
| -    __ PrepareCallCFunction(2);
 | 
| -    // Move arguments to correct registers: xmm0 and edi (not rdi).
 | 
| -    // On Windows, the registers are xmm0 and edx.
 | 
| -    __ movaps(xmm0, left_reg);
 | 
| +  // Having marked this as a call, we can use any registers.
 | 
| +  // Just make sure that the input/output registers are the expected ones.
 | 
| +
 | 
| +  // Choose register conforming to calling convention (when bailing out).
 | 
|  #ifdef _WIN64
 | 
| -    ASSERT(ToRegister(right).is(rdx));
 | 
| +  Register exponent = rdx;
 | 
|  #else
 | 
| -    ASSERT(ToRegister(right).is(rdi));
 | 
| +  Register exponent = rdi;
 | 
|  #endif
 | 
| -    __ CallCFunction(
 | 
| -        ExternalReference::power_double_int_function(isolate()), 2);
 | 
| -  } else {
 | 
| -    ASSERT(exponent_type.IsTagged());
 | 
| -    Register right_reg = ToRegister(right);
 | 
| -
 | 
| -    Label non_smi, call;
 | 
| -    __ JumpIfNotSmi(right_reg, &non_smi);
 | 
| -    __ SmiToInteger32(right_reg, right_reg);
 | 
| -    __ cvtlsi2sd(xmm1, right_reg);
 | 
| -    __ jmp(&call);
 | 
| -
 | 
| -    __ bind(&non_smi);
 | 
| -    __ CmpObjectType(right_reg, HEAP_NUMBER_TYPE , kScratchRegister);
 | 
| +  ASSERT(!instr->InputAt(1)->IsRegister() ||
 | 
| +         ToRegister(instr->InputAt(1)).is(exponent));
 | 
| +  ASSERT(!instr->InputAt(1)->IsDoubleRegister() ||
 | 
| +         ToDoubleRegister(instr->InputAt(1)).is(xmm1));
 | 
| +  ASSERT(ToDoubleRegister(instr->InputAt(0)).is(xmm2));
 | 
| +  ASSERT(ToDoubleRegister(instr->result()).is(xmm3));
 | 
| +
 | 
| +  if (exponent_type.IsTagged()) {
 | 
| +    Label no_deopt;
 | 
| +    __ JumpIfSmi(exponent, &no_deopt);
 | 
| +    __ CmpObjectType(exponent, HEAP_NUMBER_TYPE, rcx);
 | 
|      DeoptimizeIf(not_equal, instr->environment());
 | 
| -    __ movsd(xmm1, FieldOperand(right_reg, HeapNumber::kValueOffset));
 | 
| -
 | 
| -    __ bind(&call);
 | 
| -    __ PrepareCallCFunction(2);
 | 
| -    // Move arguments to correct registers xmm0 and xmm1.
 | 
| -    __ movaps(xmm0, left_reg);
 | 
| -    // Right argument is already in xmm1.
 | 
| -    __ CallCFunction(
 | 
| -        ExternalReference::power_double_double_function(isolate()), 2);
 | 
| +    __ bind(&no_deopt);
 | 
| +    MathPowStub stub(MathPowStub::TAGGED);
 | 
| +    __ CallStub(&stub);
 | 
| +  } else if (exponent_type.IsInteger32()) {
 | 
| +    MathPowStub stub(MathPowStub::INTEGER);
 | 
| +    __ CallStub(&stub);
 | 
| +  } else {
 | 
| +    ASSERT(exponent_type.IsDouble());
 | 
| +    MathPowStub stub(MathPowStub::DOUBLE);
 | 
| +    __ CallStub(&stub);
 | 
|    }
 | 
| -  // Return value is in xmm0.
 | 
| -  __ movaps(result_reg, xmm0);
 | 
| -  // Restore context register.
 | 
| -  __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
 | 
|  }
 | 
|  
 | 
|  
 | 
| 
 |