| 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));
|
| }
|
|
|
|
|
|
|