From 12b250bf0429bccb6253846164a0e37565d22328 Mon Sep 17 00:00:00 2001 From: "olivf@chromium.org" Date: Mon, 9 Sep 2013 16:57:35 +0000 Subject: [PATCH] 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 --- src/ia32/assembler-ia32.cc | 18 ++++++++++++++++++ src/ia32/assembler-ia32.h | 3 +++ src/ia32/disasm-ia32.cc | 12 +++++++++++- src/ia32/lithium-codegen-ia32.cc | 27 ++++++++++++++++++++++++++- 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc index 7ff6913..e5456da 100644 --- a/src/ia32/assembler-ia32.cc +++ b/src/ia32/assembler-ia32.cc @@ -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) { EnsureSpace ensure_space(this); 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) { EnsureSpace ensure_space(this); EMIT(0xDA); @@ -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) { EnsureSpace ensure_space(this); emit_farith(0xDE, 0xC0, i); diff --git a/src/ia32/assembler-ia32.h b/src/ia32/assembler-ia32.h index 551d031..55eff93 100644 --- a/src/ia32/assembler-ia32.h +++ b/src/ia32/assembler-ia32.h @@ -956,10 +956,13 @@ class Assembler : public AssemblerBase { void fninit(); void fadd(int i); + void fadd_i(int i); void fsub(int i); + void fsub_i(int i); void fmul(int i); void fmul_i(int i); void fdiv(int i); + void fdiv_i(int i); void fisub_s(const Operand& adr); diff --git a/src/ia32/disasm-ia32.cc b/src/ia32/disasm-ia32.cc index 293d428..a1d4e9d 100644 --- a/src/ia32/disasm-ia32.cc +++ b/src/ia32/disasm-ia32.cc @@ -743,7 +743,14 @@ int DisassemblerIA32::RegisterFPUInstruction(int escape_opcode, switch (escape_opcode) { 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; case 0xD9: @@ -767,6 +774,7 @@ int DisassemblerIA32::RegisterFPUInstruction(int escape_opcode, case 0xEE: mnem = "fldz"; break; case 0xF0: mnem = "f2xm1"; break; case 0xF1: mnem = "fyl2x"; break; + case 0xF4: mnem = "fxtract"; break; case 0xF5: mnem = "fprem1"; break; case 0xF7: mnem = "fincstp"; break; case 0xF8: mnem = "fprem"; break; @@ -815,6 +823,7 @@ int DisassemblerIA32::RegisterFPUInstruction(int escape_opcode, has_register = true; switch (modrm_byte & 0xF8) { case 0xC0: mnem = "ffree"; break; + case 0xD0: mnem = "fst"; break; case 0xD8: mnem = "fstp"; break; default: UnimplementedInstruction(); } @@ -1448,6 +1457,7 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector out_buffer, data += D1D3C1Instruction(data); break; + case 0xD8: // fall through case 0xD9: // fall through case 0xDA: // fall through case 0xDB: // fall through diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index b3b9813..536f952 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -2232,11 +2232,36 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) { X87Register left = ToX87Register(instr->left()); X87Register right = ToX87Register(instr->right()); X87Register result = ToX87Register(instr->result()); - X87PrepareBinaryOp(left, right, result); + if (instr->op() != Token::MOD) { + X87PrepareBinaryOp(left, right, result); + } switch (instr->op()) { + case Token::ADD: + __ fadd_i(1); + break; + case Token::SUB: + __ fsub_i(1); + break; case Token::MUL: __ fmul_i(1); 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: UNREACHABLE(); break; -- 2.7.4