Commit 9d89ec5c authored by whesse@chromium.org's avatar whesse@chromium.org

Add ArithmeticD(MOD) to x64 optimizing code generator. Minor changes to...

Add ArithmeticD(MOD) to x64 optimizing code generator.  Minor changes to ArithmeticD on other platforms.
Review URL: http://codereview.chromium.org/6594118

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7029 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 64191ccc
......@@ -873,6 +873,7 @@ LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op,
ASSERT(instr->representation().IsDouble());
ASSERT(instr->left()->representation().IsDouble());
ASSERT(instr->right()->representation().IsDouble());
ASSERT(op != Token::MOD);
LOperand* left = UseRegisterAtStart(instr->left());
LOperand* right = UseRegisterAtStart(instr->right());
LArithmeticD* result = new LArithmeticD(op, left, right);
......
......@@ -1148,35 +1148,36 @@ void LCodeGen::DoAddI(LAddI* instr) {
void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
LOperand* left = instr->InputAt(0);
LOperand* right = instr->InputAt(1);
XMMRegister left = ToDoubleRegister(instr->InputAt(0));
XMMRegister right = ToDoubleRegister(instr->InputAt(1));
XMMRegister result = ToDoubleRegister(instr->result());
// Modulo uses a fixed result register.
ASSERT(instr->op() == Token::MOD || left->Equals(instr->result()));
ASSERT(instr->op() == Token::MOD || left.is(result));
switch (instr->op()) {
case Token::ADD:
__ addsd(ToDoubleRegister(left), ToDoubleRegister(right));
__ addsd(left, right);
break;
case Token::SUB:
__ subsd(ToDoubleRegister(left), ToDoubleRegister(right));
__ subsd(left, right);
break;
case Token::MUL:
__ mulsd(ToDoubleRegister(left), ToDoubleRegister(right));
__ mulsd(left, right);
break;
case Token::DIV:
__ divsd(ToDoubleRegister(left), ToDoubleRegister(right));
__ divsd(left, right);
break;
case Token::MOD: {
// Pass two doubles as arguments on the stack.
__ PrepareCallCFunction(4, eax);
__ movdbl(Operand(esp, 0 * kDoubleSize), ToDoubleRegister(left));
__ movdbl(Operand(esp, 1 * kDoubleSize), ToDoubleRegister(right));
__ movdbl(Operand(esp, 0 * kDoubleSize), left);
__ movdbl(Operand(esp, 1 * kDoubleSize), right);
__ CallCFunction(ExternalReference::double_fp_operation(Token::MOD), 4);
// Return value is in st(0) on ia32.
// Store it into the (fixed) result register.
__ sub(Operand(esp), Immediate(kDoubleSize));
__ fstp_d(Operand(esp, 0));
__ movdbl(ToDoubleRegister(instr->result()), Operand(esp, 0));
__ movdbl(result, Operand(esp, 0));
__ add(Operand(esp), Immediate(kDoubleSize));
break;
}
......
......@@ -870,18 +870,11 @@ LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op,
ASSERT(instr->representation().IsDouble());
ASSERT(instr->left()->representation().IsDouble());
ASSERT(instr->right()->representation().IsDouble());
if (op == Token::MOD) {
LOperand* left = UseFixedDouble(instr->left(), xmm2);
LOperand* right = UseFixedDouble(instr->right(), xmm1);
LArithmeticD* result = new LArithmeticD(op, left, right);
return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
} else {
LOperand* left = UseRegisterAtStart(instr->left());
LOperand* right = UseRegisterAtStart(instr->right());
LArithmeticD* result = new LArithmeticD(op, left, right);
return DefineSameAsFirst(result);
}
ASSERT(op != Token::MOD);
LOperand* left = UseRegisterAtStart(instr->left());
LOperand* right = UseRegisterAtStart(instr->right());
LArithmeticD* result = new LArithmeticD(op, left, right);
return DefineSameAsFirst(result);
}
......@@ -1391,8 +1384,8 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) {
// We call a C function for double modulo. It can't trigger a GC.
// We need to use fixed result register for the call.
// TODO(fschneider): Allow any register as input registers.
LOperand* left = UseFixedDouble(instr->left(), xmm1);
LOperand* right = UseFixedDouble(instr->right(), xmm2);
LOperand* left = UseFixedDouble(instr->left(), xmm2);
LOperand* right = UseFixedDouble(instr->right(), xmm1);
LArithmeticD* result = new LArithmeticD(Token::MOD, left, right);
return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
}
......
......@@ -1114,25 +1114,31 @@ void LCodeGen::DoAddI(LAddI* instr) {
void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
LOperand* left = instr->InputAt(0);
LOperand* right = instr->InputAt(1);
XMMRegister left = ToDoubleRegister(instr->InputAt(0));
XMMRegister right = ToDoubleRegister(instr->InputAt(1));
XMMRegister result = ToDoubleRegister(instr->result());
// All operations except MOD are computed in-place.
ASSERT(instr->op() == Token::MOD || left->Equals(instr->result()));
ASSERT(instr->op() == Token::MOD || left.is(result));
switch (instr->op()) {
case Token::ADD:
__ addsd(ToDoubleRegister(left), ToDoubleRegister(right));
__ addsd(left, right);
break;
case Token::SUB:
__ subsd(ToDoubleRegister(left), ToDoubleRegister(right));
__ subsd(left, right);
break;
case Token::MUL:
__ mulsd(ToDoubleRegister(left), ToDoubleRegister(right));
__ mulsd(left, right);
break;
case Token::DIV:
__ divsd(ToDoubleRegister(left), ToDoubleRegister(right));
__ divsd(left, right);
break;
case Token::MOD:
Abort("Unimplemented: %s", "DoArithmeticD MOD");
__ PrepareCallCFunction(2);
__ movsd(xmm0, left);
ASSERT(right.is(xmm1));
__ CallCFunction(ExternalReference::double_fp_operation(Token::MOD), 2);
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
__ movsd(result, xmm0);
break;
default:
UNREACHABLE();
......
......@@ -871,9 +871,7 @@ LInstruction* LChunkBuilder::DoArithmeticD(Token::Value op,
ASSERT(instr->representation().IsDouble());
ASSERT(instr->left()->representation().IsDouble());
ASSERT(instr->right()->representation().IsDouble());
if (op == Token::MOD) {
Abort("Unimplemented: %s", "DoArithmeticD MOD");
}
ASSERT(op != Token::MOD);
LOperand* left = UseRegisterAtStart(instr->left());
LOperand* right = UseRegisterAtStart(instr->right());
LArithmeticD* result = new LArithmeticD(op, left, right);
......@@ -1366,8 +1364,8 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) {
// We call a C function for double modulo. It can't trigger a GC.
// We need to use fixed result register for the call.
// TODO(fschneider): Allow any register as input registers.
LOperand* left = UseFixedDouble(instr->left(), xmm1);
LOperand* right = UseFixedDouble(instr->right(), xmm2);
LOperand* left = UseFixedDouble(instr->left(), xmm2);
LOperand* right = UseFixedDouble(instr->right(), xmm1);
LArithmeticD* result = new LArithmeticD(Token::MOD, left, right);
return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
}
......
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