Commit 12b250bf authored by olivf@chromium.org's avatar olivf@chromium.org

Extend assembler and codegen with more fpu arithmetic

BUG=
R=mvstanton@chromium.org

Review URL: https://codereview.chromium.org/21509003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16600 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 49d9555a
...@@ -1721,12 +1721,24 @@ void Assembler::fadd(int i) { ...@@ -1721,12 +1721,24 @@ void Assembler::fadd(int i) {
} }
void Assembler::fadd_i(int i) {
EnsureSpace ensure_space(this);
emit_farith(0xD8, 0xC0, i);
}
void Assembler::fsub(int i) { void Assembler::fsub(int i) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
emit_farith(0xDC, 0xE8, i); emit_farith(0xDC, 0xE8, i);
} }
void Assembler::fsub_i(int i) {
EnsureSpace ensure_space(this);
emit_farith(0xD8, 0xE0, i);
}
void Assembler::fisub_s(const Operand& adr) { void Assembler::fisub_s(const Operand& adr) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
EMIT(0xDA); EMIT(0xDA);
...@@ -1752,6 +1764,12 @@ void Assembler::fdiv(int i) { ...@@ -1752,6 +1764,12 @@ void Assembler::fdiv(int i) {
} }
void Assembler::fdiv_i(int i) {
EnsureSpace ensure_space(this);
emit_farith(0xD8, 0xF0, i);
}
void Assembler::faddp(int i) { void Assembler::faddp(int i) {
EnsureSpace ensure_space(this); EnsureSpace ensure_space(this);
emit_farith(0xDE, 0xC0, i); emit_farith(0xDE, 0xC0, i);
......
...@@ -956,10 +956,13 @@ class Assembler : public AssemblerBase { ...@@ -956,10 +956,13 @@ class Assembler : public AssemblerBase {
void fninit(); void fninit();
void fadd(int i); void fadd(int i);
void fadd_i(int i);
void fsub(int i); void fsub(int i);
void fsub_i(int i);
void fmul(int i); void fmul(int i);
void fmul_i(int i); void fmul_i(int i);
void fdiv(int i); void fdiv(int i);
void fdiv_i(int i);
void fisub_s(const Operand& adr); void fisub_s(const Operand& adr);
......
...@@ -743,7 +743,14 @@ int DisassemblerIA32::RegisterFPUInstruction(int escape_opcode, ...@@ -743,7 +743,14 @@ int DisassemblerIA32::RegisterFPUInstruction(int escape_opcode,
switch (escape_opcode) { switch (escape_opcode) {
case 0xD8: case 0xD8:
UnimplementedInstruction(); has_register = true;
switch (modrm_byte & 0xF8) {
case 0xC0: mnem = "fadd_i"; break;
case 0xE0: mnem = "fsub_i"; break;
case 0xC8: mnem = "fmul_i"; break;
case 0xF0: mnem = "fdiv_i"; break;
default: UnimplementedInstruction();
}
break; break;
case 0xD9: case 0xD9:
...@@ -767,6 +774,7 @@ int DisassemblerIA32::RegisterFPUInstruction(int escape_opcode, ...@@ -767,6 +774,7 @@ int DisassemblerIA32::RegisterFPUInstruction(int escape_opcode,
case 0xEE: mnem = "fldz"; break; case 0xEE: mnem = "fldz"; break;
case 0xF0: mnem = "f2xm1"; break; case 0xF0: mnem = "f2xm1"; break;
case 0xF1: mnem = "fyl2x"; break; case 0xF1: mnem = "fyl2x"; break;
case 0xF4: mnem = "fxtract"; break;
case 0xF5: mnem = "fprem1"; break; case 0xF5: mnem = "fprem1"; break;
case 0xF7: mnem = "fincstp"; break; case 0xF7: mnem = "fincstp"; break;
case 0xF8: mnem = "fprem"; break; case 0xF8: mnem = "fprem"; break;
...@@ -815,6 +823,7 @@ int DisassemblerIA32::RegisterFPUInstruction(int escape_opcode, ...@@ -815,6 +823,7 @@ int DisassemblerIA32::RegisterFPUInstruction(int escape_opcode,
has_register = true; has_register = true;
switch (modrm_byte & 0xF8) { switch (modrm_byte & 0xF8) {
case 0xC0: mnem = "ffree"; break; case 0xC0: mnem = "ffree"; break;
case 0xD0: mnem = "fst"; break;
case 0xD8: mnem = "fstp"; break; case 0xD8: mnem = "fstp"; break;
default: UnimplementedInstruction(); default: UnimplementedInstruction();
} }
...@@ -1448,6 +1457,7 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer, ...@@ -1448,6 +1457,7 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector<char> out_buffer,
data += D1D3C1Instruction(data); data += D1D3C1Instruction(data);
break; break;
case 0xD8: // fall through
case 0xD9: // fall through case 0xD9: // fall through
case 0xDA: // fall through case 0xDA: // fall through
case 0xDB: // fall through case 0xDB: // fall through
......
...@@ -2232,11 +2232,36 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) { ...@@ -2232,11 +2232,36 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) {
X87Register left = ToX87Register(instr->left()); X87Register left = ToX87Register(instr->left());
X87Register right = ToX87Register(instr->right()); X87Register right = ToX87Register(instr->right());
X87Register result = ToX87Register(instr->result()); X87Register result = ToX87Register(instr->result());
X87PrepareBinaryOp(left, right, result); if (instr->op() != Token::MOD) {
X87PrepareBinaryOp(left, right, result);
}
switch (instr->op()) { switch (instr->op()) {
case Token::ADD:
__ fadd_i(1);
break;
case Token::SUB:
__ fsub_i(1);
break;
case Token::MUL: case Token::MUL:
__ fmul_i(1); __ fmul_i(1);
break; break;
case Token::DIV:
__ fdiv_i(1);
break;
case Token::MOD: {
// Pass two doubles as arguments on the stack.
__ PrepareCallCFunction(4, eax);
X87Mov(Operand(esp, 1 * kDoubleSize), right);
X87Mov(Operand(esp, 0), left);
X87PrepareToWrite(result);
__ CallCFunction(
ExternalReference::double_fp_operation(Token::MOD, isolate()),
4);
// Return value is in st(0) on ia32.
X87CommitWrite(result);
break;
}
default: default:
UNREACHABLE(); UNREACHABLE();
break; break;
......
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