Commit 83248ea0 authored by whesse@chromium.org's avatar whesse@chromium.org

X64 Crankshaft: Add DoPower to lithium compiler on x64 platform.

Review URL: http://codereview.chromium.org/6592038

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6980 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 8f78eb7d
......@@ -2480,7 +2480,54 @@ void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) {
void LCodeGen::DoPower(LPower* instr) {
Abort("Unimplemented: %s", "DoPower");
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
__ movsd(xmm0, left_reg);
ASSERT(ToDoubleRegister(right).is(xmm1));
__ CallCFunction(ExternalReference::power_double_double_function(), 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.
__ movsd(xmm0, left_reg);
#ifdef _WIN64
ASSERT(ToRegister(right).is(rdx));
#else
ASSERT(ToRegister(right).is(rdi));
#endif
__ CallCFunction(ExternalReference::power_double_int_function(), 2);
} else {
ASSERT(exponent_type.IsTagged());
CpuFeatures::Scope scope(SSE2);
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);
DeoptimizeIf(not_equal, instr->environment());
__ movsd(xmm1, FieldOperand(right_reg, HeapNumber::kValueOffset));
__ bind(&call);
__ PrepareCallCFunction(2);
// Move arguments to correct registers xmm0 and xmm1.
__ movsd(xmm0, left_reg);
// Right argument is already in xmm1.
__ CallCFunction(ExternalReference::power_double_double_function(), 2);
}
// Return value is in xmm0.
__ movsd(result_reg, xmm0);
}
......
......@@ -1436,8 +1436,22 @@ LInstruction* LChunkBuilder::DoAdd(HAdd* instr) {
LInstruction* LChunkBuilder::DoPower(HPower* instr) {
Abort("Unimplemented: %s", "DoPower");
return NULL;
ASSERT(instr->representation().IsDouble());
// We call a C function for double power. It can't trigger a GC.
// We need to use fixed result register for the call.
Representation exponent_type = instr->right()->representation();
ASSERT(instr->left()->representation().IsDouble());
LOperand* left = UseFixedDouble(instr->left(), xmm2);
LOperand* right = exponent_type.IsDouble() ?
UseFixedDouble(instr->right(), xmm1) :
#ifdef _WIN64
UseFixed(instr->right(), rdx);
#else
UseFixed(instr->right(), rdi);
#endif
LPower* result = new LPower(left, right);
return MarkAsCall(DefineFixedDouble(result, xmm1), instr,
CAN_DEOPTIMIZE_EAGERLY);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment