From 82159b2b9d8cd25223e99cf1af5c3b5bc6c5974c Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Sun, 26 May 2013 07:19:09 -0700 Subject: [PATCH] Adding lfd. --- src/xenia/cpu/x64/x64_emit_memory.cc | 39 ++++++++++++++++------------ src/xenia/cpu/x64/x64_emitter.cc | 30 ++++++++++----------- src/xenia/cpu/x64/x64_emitter.h | 20 +++++++------- 3 files changed, 47 insertions(+), 42 deletions(-) diff --git a/src/xenia/cpu/x64/x64_emit_memory.cc b/src/xenia/cpu/x64/x64_emit_memory.cc index 95e5b54ae..b53cd3015 100644 --- a/src/xenia/cpu/x64/x64_emit_memory.cc +++ b/src/xenia/cpu/x64/x64_emit_memory.cc @@ -835,24 +835,29 @@ XEEMITTER(sync, 0x7C0004AC, X )(X64Emitter& e, X86Compiler& c, InstrDat // Floating-point load (A-19) -// XEEMITTER(lfd, 0xC8000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + EXTS(D) -// // FRT <- MEM(EA, 8) +XEEMITTER(lfd, 0xC8000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + EXTS(D) + // FRT <- MEM(EA, 8) -// GpVar ea = e.get_int64(XEEXTS16(i.D.DS)); -// if (i.D.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.D.RA), ea); -// } -// GpVar v = e.ReadMemory(i.address, ea, 8, false); -// v = b.CreateBitCast(v, jit_type_float64); -// e.update_fpr_value(i.D.RT, v); + GpVar ea(c.newGpVar()); + if (i.D.RA) { + c.mov(ea, e.gpr_value(i.D.RA)); + c.add(ea, imm(XEEXTS16(i.D.DS))); + } else { + c.mov(ea, imm(XEEXTS16(i.D.DS))); + } + GpVar v = e.ReadMemory(i.address, ea, 8, false); + XmmVar xmm_v(c.newXmmVar()); + c.save(v); // Force to memory. + c.movq(xmm_v, v.m64()); + e.update_fpr_value(i.D.RT, xmm_v); -// return 0; -// } + return 0; +} // XEEMITTER(lfdu, 0xCC000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { // // EA <- (RA) + EXTS(D) @@ -1219,7 +1224,7 @@ void X64RegisterEmitCategoryMemory() { XEREGISTERINSTR(stdcx, 0x7C0001AD); XEREGISTERINSTR(stwcx, 0x7C00012D); XEREGISTERINSTR(sync, 0x7C0004AC); - // XEREGISTERINSTR(lfd, 0xC8000000); + XEREGISTERINSTR(lfd, 0xC8000000); // XEREGISTERINSTR(lfdu, 0xCC000000); // XEREGISTERINSTR(lfdux, 0x7C0004EE); // XEREGISTERINSTR(lfdx, 0x7C0004AE); diff --git a/src/xenia/cpu/x64/x64_emitter.cc b/src/xenia/cpu/x64/x64_emitter.cc index 094cf8567..8d147432a 100644 --- a/src/xenia/cpu/x64/x64_emitter.cc +++ b/src/xenia/cpu/x64/x64_emitter.cc @@ -254,7 +254,7 @@ int X64Emitter::MakeFunction(FunctionSymbol* symbol) { locals_.gpr[n] = GpVar(); } for (size_t n = 0; n < XECOUNT(locals_.fpr); n++) { - locals_.fpr[n] = GpVar(); + locals_.fpr[n] = XmmVar(); } // Setup function. All share the same signature. @@ -1039,7 +1039,7 @@ void X64Emitter::SetupLocals() { for (int n = 0; n < 32; n++) { if (fpr_t & 3) { xesnprintfa(name, XECOUNT(name), "f%d", n); - locals_.fpr[n] = c.newGpVar(kX86VarTypeXmmSD, name); + locals_.fpr[n] = c.newXmmVar(kX86VarTypeXmmSD, name); } fpr_t >>= 2; } @@ -1126,8 +1126,8 @@ void X64Emitter::FillRegisters() { if (FLAGS_annotate_disassembly) { c.comment("Filling f%d", n); } - c.mov(locals_.fpr[n], - qword_ptr(c.getGpArg(0), offsetof(xe_ppc_state_t, f) + 8 * n)); + c.movq(locals_.fpr[n], + qword_ptr(c.getGpArg(0), offsetof(xe_ppc_state_t, f) + 8 * n)); } } } @@ -1212,13 +1212,13 @@ void X64Emitter::SpillRegisters() { } for (uint32_t n = 0; n < XECOUNT(locals_.fpr); n++) { - GpVar& v = locals_.fpr[n]; + XmmVar& v = locals_.fpr[n]; if (v.getId() != kInvalidValue) { if (FLAGS_annotate_disassembly) { c.comment("Spilling f%d", n); } - c.mov(qword_ptr(c.getGpArg(0), offsetof(xe_ppc_state_t, f) + 8 * n), - v); + c.movq(qword_ptr(c.getGpArg(0), offsetof(xe_ppc_state_t, f) + 8 * n), + v); } } } @@ -1501,29 +1501,29 @@ void X64Emitter::update_gpr_value(uint32_t n, GpVar& value) { } } -GpVar X64Emitter::fpr_value(uint32_t n) { +XmmVar X64Emitter::fpr_value(uint32_t n) { X86Compiler& c = compiler_; XEASSERT(n >= 0 && n < 32); if (FLAGS_cache_registers) { XEASSERT(locals_.fpr[n].getId() != kInvalidValue); return locals_.fpr[n]; } else { - GpVar value(c.newGpVar()); - c.mov(value, - qword_ptr(c.getGpArg(0), offsetof(xe_ppc_state_t, f) + 8 * n)); + XmmVar value(c.newXmmVar()); + c.movq(value, + qword_ptr(c.getGpArg(0), offsetof(xe_ppc_state_t, f) + 8 * n)); return value; } } -void X64Emitter::update_fpr_value(uint32_t n, GpVar& value) { +void X64Emitter::update_fpr_value(uint32_t n, XmmVar& value) { X86Compiler& c = compiler_; XEASSERT(n >= 0 && n < 32); if (FLAGS_cache_registers) { XEASSERT(locals_.fpr[n].getId() != kInvalidValue); - c.mov(locals_.fpr[n], value); + c.movq(locals_.fpr[n], value); } else { - c.mov(qword_ptr(c.getGpArg(0), offsetof(xe_ppc_state_t, f) + 8 * n), - value); + c.movq(qword_ptr(c.getGpArg(0), offsetof(xe_ppc_state_t, f) + 8 * n), + value); } } diff --git a/src/xenia/cpu/x64/x64_emitter.h b/src/xenia/cpu/x64/x64_emitter.h index d084436a8..dbc48051e 100644 --- a/src/xenia/cpu/x64/x64_emitter.h +++ b/src/xenia/cpu/x64/x64_emitter.h @@ -80,8 +80,8 @@ public: AsmJit::GpVar gpr_value(uint32_t n); void update_gpr_value(uint32_t n, AsmJit::GpVar& value); - AsmJit::GpVar fpr_value(uint32_t n); - void update_fpr_value(uint32_t n, AsmJit::GpVar& value); + AsmJit::XmmVar fpr_value(uint32_t n); + void update_fpr_value(uint32_t n, AsmJit::XmmVar& value); AsmJit::GpVar TouchMemoryAddress(uint32_t cia, AsmJit::GpVar& addr); AsmJit::GpVar ReadMemory( @@ -126,15 +126,15 @@ private: ppc::InstrAccessBits access_bits_; struct { - AsmJit::GpVar indirection_target; - AsmJit::GpVar indirection_cia; + AsmJit::GpVar indirection_target; + AsmJit::GpVar indirection_cia; - AsmJit::GpVar xer; - AsmJit::GpVar lr; - AsmJit::GpVar ctr; - AsmJit::GpVar cr[8]; - AsmJit::GpVar gpr[32]; - AsmJit::GpVar fpr[32]; + AsmJit::GpVar xer; + AsmJit::GpVar lr; + AsmJit::GpVar ctr; + AsmJit::GpVar cr[8]; + AsmJit::GpVar gpr[32]; + AsmJit::XmmVar fpr[32]; } locals_; };