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