Commit c9c9ea67 authored by yangguo@chromium.org's avatar yangguo@chromium.org

Porting Math.pow changes to x64.

TEST=math-pow.js, regress-397.js

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10185 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent b5b91b5a
This diff is collapsed.
......@@ -2991,12 +2991,12 @@ void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) {
void LCodeGen::DoPower(LPower* instr) {
Representation exponent_type = instr->hydrogen()->right()->representation();
// Having marked this as a call, we can use any registers.
// Just make sure that the input registers are the expected ones.
// Just make sure that the input/output registers are the expected ones.
ASSERT(!instr->InputAt(1)->IsDoubleRegister() ||
ToDoubleRegister(instr->InputAt(1)).is(xmm2));
ToDoubleRegister(instr->InputAt(1)).is(xmm1));
ASSERT(!instr->InputAt(1)->IsRegister() ||
ToRegister(instr->InputAt(1)).is(eax));
ASSERT(ToDoubleRegister(instr->InputAt(0)).is(xmm1));
ASSERT(ToDoubleRegister(instr->InputAt(0)).is(xmm2));
ASSERT(ToDoubleRegister(instr->result()).is(xmm3));
if (exponent_type.IsTagged()) {
......
......@@ -1446,9 +1446,9 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) {
// 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(), xmm1);
LOperand* left = UseFixedDouble(instr->left(), xmm2);
LOperand* right = exponent_type.IsDouble() ?
UseFixedDouble(instr->right(), xmm2) :
UseFixedDouble(instr->right(), xmm1) :
UseFixed(instr->right(), eax);
LPower* result = new(zone()) LPower(left, right);
return MarkAsCall(DefineFixedDouble(result, xmm3), instr,
......
......@@ -2307,6 +2307,27 @@ void Assembler::fyl2x() {
}
void Assembler::f2xm1() {
EnsureSpace ensure_space(this);
emit(0xD9);
emit(0xF0);
}
void Assembler::fscale() {
EnsureSpace ensure_space(this);
emit(0xD9);
emit(0xFD);
}
void Assembler::fninit() {
EnsureSpace ensure_space(this);
emit(0xDB);
emit(0xE3);
}
void Assembler::fadd(int i) {
EnsureSpace ensure_space(this);
emit_farith(0xDC, 0xC0, i);
......
......@@ -1277,6 +1277,9 @@ class Assembler : public AssemblerBase {
void fcos();
void fptan();
void fyl2x();
void f2xm1();
void fscale();
void fninit();
void frndint();
......
This diff is collapsed.
......@@ -911,15 +911,19 @@ int DisassemblerX64::RegisterFPUInstruction(int escape_opcode,
switch (modrm_byte) {
case 0xE0: mnem = "fchs"; break;
case 0xE1: mnem = "fabs"; break;
case 0xE3: mnem = "fninit"; break;
case 0xE4: mnem = "ftst"; break;
case 0xE8: mnem = "fld1"; break;
case 0xEB: mnem = "fldpi"; break;
case 0xED: mnem = "fldln2"; break;
case 0xEE: mnem = "fldz"; break;
case 0xF0: mnem = "f2xm1"; break;
case 0xF1: mnem = "fyl2x"; break;
case 0xF2: mnem = "fptan"; break;
case 0xF5: mnem = "fprem1"; break;
case 0xF7: mnem = "fincstp"; break;
case 0xF8: mnem = "fprem"; break;
case 0xFD: mnem = "fscale"; break;
case 0xFE: mnem = "fsin"; break;
case 0xFF: mnem = "fcos"; break;
default: UnimplementedInstruction();
......
......@@ -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));
}
......
......@@ -1397,7 +1397,7 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) {
UseFixed(instr->right(), rdi);
#endif
LPower* result = new LPower(left, right);
return MarkAsCall(DefineFixedDouble(result, xmm1), instr,
return MarkAsCall(DefineFixedDouble(result, xmm3), 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