From e6320dada595a3c51fe5c068996502b70239c376 Mon Sep 17 00:00:00 2001 From: Ben Vanik Date: Fri, 24 May 2013 16:16:39 -0700 Subject: [PATCH] Most of the memory instructions. Not sure this is correct, as it crashes pretty early on. --- src/xenia/cpu/x64/x64_emit_alu.cc | 10 +- src/xenia/cpu/x64/x64_emit_control.cc | 6 +- src/xenia/cpu/x64/x64_emit_memory.cc | 1717 +++++++++++++------------ src/xenia/cpu/x64/x64_emitter.cc | 375 +++--- src/xenia/cpu/x64/x64_emitter.h | 8 +- 5 files changed, 1120 insertions(+), 996 deletions(-) diff --git a/src/xenia/cpu/x64/x64_emit_alu.cc b/src/xenia/cpu/x64/x64_emit_alu.cc index 01bff2234..cd14a52cc 100644 --- a/src/xenia/cpu/x64/x64_emit_alu.cc +++ b/src/xenia/cpu/x64/x64_emit_alu.cc @@ -642,7 +642,7 @@ XEEMITTER(andisx, 0x74000000, D )(X64Emitter& e, X86Compiler& c, InstrDat GpVar v(c.newGpVar()); c.mov(v, e.gpr_value(i.D.RT)); - c.and_(v, imm(((uint64_t)i.D.DS) << 16)); + c.and_(v, imm(i.D.DS << 16)); e.update_gpr_value(i.D.RA, v); // With cr0 update. @@ -764,7 +764,7 @@ XEEMITTER(ori, 0x60000000, D )(X64Emitter& e, X86Compiler& c, InstrDat GpVar v(c.newGpVar()); c.mov(v, e.gpr_value(i.D.RT)); - c.or_(v, imm((uint64_t)i.D.DS)); + c.or_(v, imm(i.D.DS)); e.update_gpr_value(i.D.RA, v); return 0; @@ -775,7 +775,7 @@ XEEMITTER(oris, 0x64000000, D )(X64Emitter& e, X86Compiler& c, InstrDat GpVar v(c.newGpVar()); c.mov(v, e.gpr_value(i.D.RT)); - c.or_(v, imm(((uint64_t)i.D.DS) << 16)); + c.or_(v, imm(i.D.DS << 16)); e.update_gpr_value(i.D.RA, v); return 0; @@ -802,7 +802,7 @@ XEEMITTER(xori, 0x68000000, D )(X64Emitter& e, X86Compiler& c, InstrDat GpVar v(c.newGpVar()); c.mov(v, e.gpr_value(i.D.RT)); - c.xor_(v, imm((uint64_t)i.D.DS)); + c.xor_(v, imm(i.D.DS)); e.update_gpr_value(i.D.RA, v); return 0; @@ -813,7 +813,7 @@ XEEMITTER(xoris, 0x6C000000, D )(X64Emitter& e, X86Compiler& c, InstrDat GpVar v(c.newGpVar()); c.mov(v, e.gpr_value(i.D.RT)); - c.xor_(v, imm(((uint64_t)i.D.DS) << 16)); + c.xor_(v, imm(i.D.DS << 16)); e.update_gpr_value(i.D.RA, v); return 0; diff --git a/src/xenia/cpu/x64/x64_emit_control.cc b/src/xenia/cpu/x64/x64_emit_control.cc index 3b341ea30..29f2b898b 100644 --- a/src/xenia/cpu/x64/x64_emit_control.cc +++ b/src/xenia/cpu/x64/x64_emit_control.cc @@ -561,8 +561,8 @@ XEEMITTER(tw, 0x7C000008, X )(X64Emitter& e, X86Compiler& c, InstrDat // if (a = b) & TO[2] then TRAP // if (a u b) & TO[4] then TRAP - GpVar va = e.sign_extend(e.trunc(e.gpr_value(i.X.RA), 4), 8); - GpVar vb = e.sign_extend(e.trunc(e.gpr_value(i.X.RA), 4), 8); + GpVar va = e.sign_extend(e.gpr_value(i.X.RA), 4, 8); + GpVar vb = e.sign_extend(e.gpr_value(i.X.RA), 4, 8); return XeEmitTrap(e, c, i, va, vb, i.X.RT); } @@ -573,7 +573,7 @@ XEEMITTER(twi, 0x0C000000, D )(X64Emitter& e, X86Compiler& c, InstrDat // if (a = EXTS(SI)) & TO[2] then TRAP // if (a u EXTS(SI)) & TO[4] then TRAP - GpVar va = e.sign_extend(e.trunc(e.gpr_value(i.D.RA), 4), 8); + GpVar va = e.sign_extend(e.gpr_value(i.D.RA), 4, 8); GpVar vb(c.newGpVar()); c.mov(vb, imm(XEEXTS16(i.D.DS))); return XeEmitTrap(e, c, i, va, vb, i.D.RT); diff --git a/src/xenia/cpu/x64/x64_emit_memory.cc b/src/xenia/cpu/x64/x64_emit_memory.cc index d97960a7d..95e5b54ae 100644 --- a/src/xenia/cpu/x64/x64_emit_memory.cc +++ b/src/xenia/cpu/x64/x64_emit_memory.cc @@ -23,734 +23,809 @@ namespace cpu { namespace x64 { -// // Integer load (A-13) - -// XEEMITTER(lbz, 0x88000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + EXTS(D) -// // RT <- i56.0 || MEM(EA, 1) - -// jit_value_t ea = e.get_int64(XEEXTS16(i.D.DS)); -// if (i.D.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.D.RA), ea); -// } -// jit_value_t v = e.ReadMemory(i.address, ea, 1, false); -// e.update_gpr_value(i.D.RT, v); - -// return 0; -// } - -// XEEMITTER(lbzu, 0x8C000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // EA <- (RA) + EXTS(D) -// // RT <- i56.0 || MEM(EA, 1) -// // RA <- EA - -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.D.RA), -// e.get_int64(XEEXTS16(i.D.DS))); -// jit_value_t v = e.ReadMemory(i.address, ea, 1, false); -// e.update_gpr_value(i.D.RT, v); -// e.update_gpr_value(i.D.RA, ea); - -// return 0; -// } - -// XEEMITTER(lbzux, 0x7C0000EE, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // EA <- (RA) + (RB) -// // RT <- i56.0 || MEM(EA, 1) -// // RA <- EA - -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// jit_value_t v = e.ReadMemory(i.address, ea, 1, false); -// e.update_gpr_value(i.X.RT, v); -// e.update_gpr_value(i.X.RA, ea); - -// return 0; -// } - -// XEEMITTER(lbzx, 0x7C0000AE, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + (RB) -// // RT <- i56.0 || MEM(EA, 1) - -// jit_value_t ea = e.gpr_value(i.X.RB); -// if (i.X.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.X.RA), ea); -// } -// jit_value_t v = e.ReadMemory(i.address, ea, 1, false); -// e.update_gpr_value(i.X.RT, v); - -// return 0; -// } - -// XEEMITTER(ld, 0xE8000000, DS )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + EXTS(DS || 0b00) -// // RT <- MEM(EA, 8) - -// jit_value_t ea = e.get_int64(XEEXTS16(i.DS.DS << 2)); -// if (i.DS.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.DS.RA), ea); -// } -// jit_value_t v = e.ReadMemory(i.address, ea, 8, false); -// e.update_gpr_value(i.DS.RT, v); - -// return 0; -// } - -// XEEMITTER(ldu, 0xE8000001, DS )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // EA <- (RA) + EXTS(DS || 0b00) -// // RT <- MEM(EA, 8) -// // RA <- EA - -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.DS.RA), -// e.get_int64(XEEXTS16(i.DS.DS << 2))); -// jit_value_t v = e.ReadMemory(i.address, ea, 8, false); -// e.update_gpr_value(i.DS.RT, v); -// e.update_gpr_value(i.DS.RA, ea); - -// return 0; -// } - -// XEEMITTER(ldux, 0x7C00006A, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// XEINSTRNOTIMPLEMENTED(); -// return 1; -// } - -// XEEMITTER(ldx, 0x7C00002A, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// XEINSTRNOTIMPLEMENTED(); -// return 1; -// } - -// XEEMITTER(lha, 0xA8000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + EXTS(D) -// // RT <- EXTS(MEM(EA, 2)) - -// jit_value_t ea = e.get_int64(XEEXTS16(i.D.DS)); -// if (i.D.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.D.RA), ea); -// } -// jit_value_t v = e.sign_extend(e.ReadMemory(i.address, ea, 2, false), -// jit_type_nuint); -// e.update_gpr_value(i.D.RT, v); - -// return 0; -// } - -// XEEMITTER(lhau, 0xAC000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// XEINSTRNOTIMPLEMENTED(); -// return 1; -// } - -// XEEMITTER(lhaux, 0x7C0002EE, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// XEINSTRNOTIMPLEMENTED(); -// return 1; -// } - -// XEEMITTER(lhax, 0x7C0002AE, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + (RB) -// // RT <- EXTS(MEM(EA, 2)) - -// jit_value_t ea = e.gpr_value(i.X.RB); -// if (i.X.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.X.RA), ea); -// } -// jit_value_t v = e.sign_extend(e.ReadMemory(i.address, ea, 2, false), -// jit_type_nuint); -// e.update_gpr_value(i.X.RT, v); - -// return 0; -// } - -// XEEMITTER(lhz, 0xA0000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + EXTS(D) -// // RT <- i48.0 || MEM(EA, 2) - -// jit_value_t ea = e.get_int64(XEEXTS16(i.D.DS)); -// if (i.D.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.D.RA), ea); -// } -// jit_value_t v = e.ReadMemory(i.address, ea, 2, false); -// e.update_gpr_value(i.D.RT, v); - -// return 0; -// } - -// XEEMITTER(lhzu, 0xA4000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // EA <- (RA) + EXTS(D) -// // RT <- i48.0 || MEM(EA, 2) -// // RA <- EA - -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.D.RA), -// e.get_int64(XEEXTS16(i.D.DS))); -// jit_value_t v = e.ReadMemory(i.address, ea, 2, false); -// e.update_gpr_value(i.D.RT, v); -// e.update_gpr_value(i.D.RA, ea); - -// return 0; -// } - -// XEEMITTER(lhzux, 0x7C00026E, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // EA <- (RA) + (RB) -// // RT <- i48.0 || MEM(EA, 2) -// // RA <- EA - -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// jit_value_t v = e.ReadMemory(i.address, ea, 2, false); -// e.update_gpr_value(i.X.RT, v); -// e.update_gpr_value(i.X.RA, ea); - -// return 0; -// } - -// XEEMITTER(lhzx, 0x7C00022E, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + (RB) -// // RT <- i48.0 || MEM(EA, 2) - -// jit_value_t ea = e.gpr_value(i.X.RB); -// if (i.X.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.X.RA), ea); -// } -// jit_value_t v = e.ReadMemory(i.address, ea, 2, false); -// e.update_gpr_value(i.X.RT, v); - -// return 0; -// } - -// XEEMITTER(lwa, 0xE8000002, DS )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + EXTS(D || 00) -// // RT <- EXTS(MEM(EA, 4)) - -// jit_value_t ea = e.get_int64(XEEXTS16(i.DS.DS << 2)); -// if (i.DS.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.DS.RA), ea); -// } -// jit_value_t v = e.sign_extend(e.ReadMemory(i.address, ea, 4, false), -// jit_type_nuint); -// e.update_gpr_value(i.DS.RT, v); - -// return 0; -// } - -// XEEMITTER(lwaux, 0x7C0002EA, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // EA <- (RA) + (RB) -// // RT <- EXTS(MEM(EA, 4)) -// // RA <- EA - -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// jit_value_t v = e.sign_extend(e.ReadMemory(i.address, ea, 4, false), -// jit_type_nuint); -// e.update_gpr_value(i.X.RT, v); -// e.update_gpr_value(i.X.RA, ea); - -// return 0; -// } - -// XEEMITTER(lwax, 0x7C0002AA, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + (RB) -// // RT <- EXTS(MEM(EA, 4)) - -// jit_value_t ea = e.gpr_value(i.X.RB); -// if (i.X.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.X.RA), ea); -// } -// jit_value_t v = e.sign_extend(e.ReadMemory(i.address, ea, 4, false), -// jit_type_nuint); -// e.update_gpr_value(i.X.RT, v); - -// return 0; -// } - -// XEEMITTER(lwz, 0x80000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + EXTS(D) -// // RT <- i32.0 || MEM(EA, 4) - -// jit_value_t ea = e.get_int64(XEEXTS16(i.D.DS)); -// if (i.D.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.D.RA), ea); -// } -// jit_value_t v = e.ReadMemory(i.address, ea, 4, false); -// e.update_gpr_value(i.D.RT, v); - -// return 0; -// } - -// XEEMITTER(lwzu, 0x84000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // EA <- (RA) + EXTS(D) -// // RT <- i32.0 || MEM(EA, 4) -// // RA <- EA - -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.D.RA), -// e.get_int64(XEEXTS16(i.D.DS))); -// jit_value_t v = e.ReadMemory(i.address, ea, 4, false); -// e.update_gpr_value(i.D.RT, v); -// e.update_gpr_value(i.D.RA, ea); - -// return 0; -// } - -// XEEMITTER(lwzux, 0x7C00006E, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // EA <- (RA) + (RB) -// // RT <- i32.0 || MEM(EA, 4) -// // RA <- EA - -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// jit_value_t v = e.ReadMemory(i.address, ea, 4, false); -// e.update_gpr_value(i.X.RT, v); -// e.update_gpr_value(i.X.RA, ea); - -// return 0; -// } - -// XEEMITTER(lwzx, 0x7C00002E, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + (RB) -// // RT <- i32.0 || MEM(EA, 4) - -// jit_value_t ea = e.gpr_value(i.X.RB); -// if (i.X.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.X.RA), ea); -// } -// jit_value_t v = e.ReadMemory(i.address, ea, 4, false); -// e.update_gpr_value(i.X.RT, v); - -// return 0; -// } - - -// // Integer store (A-14) - -// XEEMITTER(stb, 0x98000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + EXTS(D) -// // MEM(EA, 1) <- (RS)[56:63] - -// jit_value_t ea = e.get_int64(XEEXTS16(i.D.DS)); -// if (i.D.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.D.RA), ea); -// } -// jit_value_t v = e.gpr_value(i.D.RT); -// e.WriteMemory(i.address, ea, 1, v); - -// return 0; -// } - -// XEEMITTER(stbu, 0x9C000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // EA <- (RA) + EXTS(D) -// // MEM(EA, 1) <- (RS)[56:63] -// // RA <- EA - -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.D.RA), -// e.get_int64(XEEXTS16(i.D.DS))); -// jit_value_t v = e.gpr_value(i.D.RT); -// e.WriteMemory(i.address, ea, 1, v); -// e.update_gpr_value(i.D.RA, ea); - -// return 0; -// } - -// XEEMITTER(stbux, 0x7C0001EE, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // EA <- (RA) + (RB) -// // MEM(EA, 1) <- (RS)[56:63] -// // RA <- EA - -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// jit_value_t v = e.gpr_value(i.X.RT); -// e.WriteMemory(i.address, ea, 1, v); -// e.update_gpr_value(i.X.RA, ea); - -// return 0; -// } - -// XEEMITTER(stbx, 0x7C0001AE, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + (RB) -// // MEM(EA, 1) <- (RS)[56:63] - -// jit_value_t ea = e.gpr_value(i.X.RB); -// if (i.D.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.X.RA), ea); -// } -// jit_value_t v = e.gpr_value(i.X.RT); -// e.WriteMemory(i.address, ea, 1, v); - -// return 0; -// } - -// XEEMITTER(std, 0xF8000000, DS )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + EXTS(DS || 0b00) -// // MEM(EA, 8) <- (RS) - -// jit_value_t ea = e.get_int64(XEEXTS16(i.DS.DS << 2)); -// if (i.DS.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.DS.RA), ea); -// } -// jit_value_t v = e.gpr_value(i.DS.RT); -// e.WriteMemory(i.address, ea, 8, v); - -// return 0; -// } - -// XEEMITTER(stdu, 0xF8000001, DS )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // EA <- (RA) + EXTS(DS || 0b00) -// // MEM(EA, 8) <- (RS) -// // RA <- EA - -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.DS.RA), -// e.get_int64(XEEXTS16(i.DS.DS << 2))); -// jit_value_t v = e.gpr_value(i.DS.RT); -// e.WriteMemory(i.address, ea, 8, v); -// e.update_gpr_value(i.DS.RA, ea); - -// return 0; -// } - -// XEEMITTER(stdux, 0x7C00016A, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + (RB) -// // MEM(EA, 8) <- (RS) - -// jit_value_t ea = e.gpr_value(i.X.RB); -// if (i.X.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.X.RA), ea); -// } -// jit_value_t v = e.gpr_value(i.X.RT); -// e.WriteMemory(i.address, ea, 8, v); - -// return 0; -// } - -// XEEMITTER(stdx, 0x7C00012A, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // EA <- (RA) + (RB) -// // MEM(EA, 8) <- (RS) -// // RA <- EA - -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// jit_value_t v = e.gpr_value(i.X.RT); -// e.WriteMemory(i.address, ea, 8, v); -// e.update_gpr_value(i.X.RA, ea); - -// return 0; -// } - -// XEEMITTER(sth, 0xB0000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + EXTS(D) -// // MEM(EA, 2) <- (RS)[48:63] - -// jit_value_t ea = e.get_int64(XEEXTS16(i.D.DS)); -// if (i.D.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.D.RA), ea); -// } -// jit_value_t v = e.gpr_value(i.D.RT); -// e.WriteMemory(i.address, ea, 2, v); - -// return 0; -// } - -// XEEMITTER(sthu, 0xB4000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // EA <- (RA) + EXTS(D) -// // MEM(EA, 2) <- (RS)[48:63] -// // RA <- EA - -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.D.RA), -// e.get_int64(XEEXTS16(i.D.DS))); -// jit_value_t v = e.gpr_value(i.D.RT); -// e.WriteMemory(i.address, ea, 2, v); -// e.update_gpr_value(i.D.RA, ea); - -// return 0; -// } - -// XEEMITTER(sthux, 0x7C00036E, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // EA <- (RA) + (RB) -// // MEM(EA, 2) <- (RS)[48:63] -// // RA <- EA - -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// jit_value_t v = e.gpr_value(i.X.RT); -// e.WriteMemory(i.address, ea, 2, v); -// e.update_gpr_value(i.X.RA, ea); - -// return 0; -// } - -// XEEMITTER(sthx, 0x7C00032E, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + (RB) -// // MEM(EA, 2) <- (RS)[48:63] - -// jit_value_t ea = e.gpr_value(i.X.RB); -// if (i.D.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.X.RA), ea); -// } -// jit_value_t v = e.gpr_value(i.X.RT); -// e.WriteMemory(i.address, ea, 2, v); - -// return 0; -// } - -// XEEMITTER(stw, 0x90000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + EXTS(D) -// // MEM(EA, 4) <- (RS)[32:63] - -// jit_value_t ea = e.get_int64(XEEXTS16(i.D.DS)); -// if (i.D.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.D.RA), ea); -// } -// jit_value_t v = e.gpr_value(i.D.RT); -// e.WriteMemory(i.address, ea, 4, v); - -// return 0; -// } - -// XEEMITTER(stwu, 0x94000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // EA <- (RA) + EXTS(D) -// // MEM(EA, 4) <- (RS)[32:63] -// // RA <- EA - -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.D.RA), -// e.get_int64(XEEXTS16(i.D.DS))); -// jit_value_t v = e.gpr_value(i.D.RT); -// e.WriteMemory(i.address, ea, 4, v); -// e.update_gpr_value(i.D.RA, ea); - -// return 0; -// } - -// XEEMITTER(stwux, 0x7C00016E, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // EA <- (RA) + (RB) -// // MEM(EA, 4) <- (RS)[32:63] -// // RA <- EA - -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// jit_value_t v = e.gpr_value(i.X.RT); -// e.WriteMemory(i.address, ea, 4, v); -// e.update_gpr_value(i.X.RA, ea); - -// return 0; -// } - -// XEEMITTER(stwx, 0x7C00012E, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + (RB) -// // MEM(EA, 4) <- (RS)[32:63] - -// jit_value_t ea = e.gpr_value(i.X.RB); -// if (i.X.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.X.RA), ea); -// } -// jit_value_t v = e.gpr_value(i.X.RT); -// e.WriteMemory(i.address, ea, 4, v); - -// return 0; -// } - - -// // Integer load and store with byte reverse (A-1 - -// XEEMITTER(lhbrx, 0x7C00062C, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// XEINSTRNOTIMPLEMENTED(); -// return 1; -// } - -// XEEMITTER(lwbrx, 0x7C00042C, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// XEINSTRNOTIMPLEMENTED(); -// return 1; -// } - -// XEEMITTER(ldbrx, 0x7C000428, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// XEINSTRNOTIMPLEMENTED(); -// return 1; -// } - -// XEEMITTER(sthbrx, 0x7C00072C, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// XEINSTRNOTIMPLEMENTED(); -// return 1; -// } - -// XEEMITTER(stwbrx, 0x7C00052C, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// XEINSTRNOTIMPLEMENTED(); -// return 1; -// } - -// XEEMITTER(stdbrx, 0x7C000528, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// XEINSTRNOTIMPLEMENTED(); -// return 1; -// } - - -// // Integer load and store multiple (A-16) - -// XEEMITTER(lmw, 0xB8000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// XEINSTRNOTIMPLEMENTED(); -// return 1; -// } - -// XEEMITTER(stmw, 0xBC000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// XEINSTRNOTIMPLEMENTED(); -// return 1; -// } - - -// // Integer load and store string (A-17) - -// XEEMITTER(lswi, 0x7C0004AA, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// XEINSTRNOTIMPLEMENTED(); -// return 1; -// } - -// XEEMITTER(lswx, 0x7C00042A, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// XEINSTRNOTIMPLEMENTED(); -// return 1; -// } - -// XEEMITTER(stswi, 0x7C0005AA, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// XEINSTRNOTIMPLEMENTED(); -// return 1; -// } - -// XEEMITTER(stswx, 0x7C00052A, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// XEINSTRNOTIMPLEMENTED(); -// return 1; -// } - - -// // Memory synchronization (A-18) - -// XEEMITTER(eieio, 0x7C0006AC, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// XEINSTRNOTIMPLEMENTED(); -// return 1; -// } - -// XEEMITTER(isync, 0x4C00012C, XL )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// XEINSTRNOTIMPLEMENTED(); -// return 1; -// } - -// XEEMITTER(ldarx, 0x7C0000A8, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// XEINSTRNOTIMPLEMENTED(); -// return 1; -// } - -// XEEMITTER(lwarx, 0x7C000028, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + (RB) -// // RESERVE <- 1 -// // RESERVE_LENGTH <- 4 -// // RESERVE_ADDR <- real_addr(EA) -// // RT <- i32.0 || MEM(EA, 4) - -// // TODO(benvanik): make this right - -// jit_value_t ea = e.gpr_value(i.X.RB); -// if (i.X.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.X.RA), ea); -// } -// jit_value_t v = e.ReadMemory(i.address, ea, 4, /* acquire */ true); -// e.update_gpr_value(i.X.RT, v); - -// return 0; -// } - -// XEEMITTER(stdcx, 0x7C0001AD, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// XEINSTRNOTIMPLEMENTED(); -// return 1; -// } - -// XEEMITTER(stwcx, 0x7C00012D, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { -// // if RA = 0 then -// // b <- 0 -// // else -// // b <- (RA) -// // EA <- b + (RB) -// // RESERVE stuff... -// // MEM(EA, 4) <- (RS)[32:63] -// // n <- 1 if store performed -// // CR0[LT GT EQ SO] = 0b00 || n || XER[SO] - -// // TODO(benvanik): make this right - -// jit_value_t ea = e.get_int64(XEEXTS16(i.D.DS)); -// if (i.D.RA) { -// ea = jit_insn_add(f, e.gpr_value(i.D.RA), ea); -// } -// jit_value_t v = e.gpr_value(i.D.RT); -// e.WriteMemory(i.address, ea, 4, v, /* release */ true); - -// // We always succeed. -// e.update_cr_value(0, e.get_int64(1 << 2)); - -// return 0; -// } +// Integer load (A-13) + +XEEMITTER(lbz, 0x88000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + EXTS(D) + // RT <- i56.0 || MEM(EA, 1) + + 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, 1, false); + e.update_gpr_value(i.D.RT, v); + + return 0; +} + +XEEMITTER(lbzu, 0x8C000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // EA <- (RA) + EXTS(D) + // RT <- i56.0 || MEM(EA, 1) + // RA <- EA + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.D.RA)); + c.add(ea, imm(XEEXTS16(i.D.DS))); + GpVar v = e.ReadMemory(i.address, ea, 1, false); + e.update_gpr_value(i.D.RT, v); + e.update_gpr_value(i.D.RA, ea); + + return 0; +} + +XEEMITTER(lbzux, 0x7C0000EE, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // EA <- (RA) + (RB) + // RT <- i56.0 || MEM(EA, 1) + // RA <- EA + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.X.RA)); + c.add(ea, e.gpr_value(i.X.RB)); + GpVar v = e.ReadMemory(i.address, ea, 1, false); + e.update_gpr_value(i.X.RT, v); + e.update_gpr_value(i.X.RA, ea); + + return 0; +} + +XEEMITTER(lbzx, 0x7C0000AE, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + (RB) + // RT <- i56.0 || MEM(EA, 1) + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.X.RB)); + if (i.X.RA) { + c.add(ea, e.gpr_value(i.X.RA)); + } + GpVar v = e.ReadMemory(i.address, ea, 1, false); + e.update_gpr_value(i.X.RT, v); + + return 0; +} + +XEEMITTER(ld, 0xE8000000, DS )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + EXTS(DS || 0b00) + // RT <- MEM(EA, 8) + + GpVar ea(c.newGpVar()); + if (i.DS.RA) { + c.mov(ea, e.gpr_value(i.DS.RA)); + c.add(ea, imm(XEEXTS16(i.DS.DS << 2))); + } else { + c.mov(ea, imm(XEEXTS16(i.DS.DS << 2))); + } + GpVar v = e.ReadMemory(i.address, ea, 8, false); + e.update_gpr_value(i.DS.RT, v); + + return 0; +} + +XEEMITTER(ldu, 0xE8000001, DS )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // EA <- (RA) + EXTS(DS || 0b00) + // RT <- MEM(EA, 8) + // RA <- EA + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.DS.RA)); + c.add(ea, imm(XEEXTS16(i.DS.DS << 2))); + GpVar v = e.ReadMemory(i.address, ea, 8, false); + e.update_gpr_value(i.DS.RT, v); + e.update_gpr_value(i.DS.RA, ea); + + return 0; +} + +XEEMITTER(ldux, 0x7C00006A, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + XEINSTRNOTIMPLEMENTED(); + return 1; +} + +XEEMITTER(ldx, 0x7C00002A, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + XEINSTRNOTIMPLEMENTED(); + return 1; +} + +XEEMITTER(lha, 0xA8000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + EXTS(D) + // RT <- EXTS(MEM(EA, 2)) + + 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, 2, false); + v = e.sign_extend(v, 2, 8); + e.update_gpr_value(i.D.RT, v); + + return 0; +} + +XEEMITTER(lhau, 0xAC000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { + XEINSTRNOTIMPLEMENTED(); + return 1; +} + +XEEMITTER(lhaux, 0x7C0002EE, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + XEINSTRNOTIMPLEMENTED(); + return 1; +} + +XEEMITTER(lhax, 0x7C0002AE, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + (RB) + // RT <- EXTS(MEM(EA, 2)) + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.X.RB)); + if (i.X.RA) { + c.add(ea, e.gpr_value(i.X.RA)); + } + GpVar v = e.ReadMemory(i.address, ea, 2, false); + v = e.sign_extend(v, 2, 8); + e.update_gpr_value(i.X.RT, v); + + return 0; +} + +XEEMITTER(lhz, 0xA0000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + EXTS(D) + // RT <- i48.0 || MEM(EA, 2) + + 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, 2, false); + // Zero extend done by ReadMemory. + e.update_gpr_value(i.D.RT, v); + + return 0; +} + +XEEMITTER(lhzu, 0xA4000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // EA <- (RA) + EXTS(D) + // RT <- i48.0 || MEM(EA, 2) + // RA <- EA + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.D.RA)); + c.add(ea, imm(XEEXTS16(i.D.DS))); + GpVar v = e.ReadMemory(i.address, ea, 2, false); + // Zero extend done by ReadMemory. + e.update_gpr_value(i.D.RT, v); + e.update_gpr_value(i.D.RA, ea); + + return 0; +} + +XEEMITTER(lhzux, 0x7C00026E, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // EA <- (RA) + (RB) + // RT <- i48.0 || MEM(EA, 2) + // RA <- EA + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.X.RA)); + c.add(ea, imm(XEEXTS16(i.X.RB))); + GpVar v = e.ReadMemory(i.address, ea, 2, false); + // Zero extend done by ReadMemory. + e.update_gpr_value(i.X.RT, v); + e.update_gpr_value(i.X.RA, ea); + + return 0; +} + +XEEMITTER(lhzx, 0x7C00022E, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + (RB) + // RT <- i48.0 || MEM(EA, 2) + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.X.RB)); + if (i.X.RA) { + c.add(ea, e.gpr_value(i.X.RA)); + } + GpVar v = e.ReadMemory(i.address, ea, 2, false); + // Zero extend done by ReadMemory. + e.update_gpr_value(i.X.RT, v); + + return 0; +} + +XEEMITTER(lwa, 0xE8000002, DS )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + EXTS(D || 00) + // RT <- EXTS(MEM(EA, 4)) + + GpVar ea(c.newGpVar()); + if (i.DS.RA) { + c.mov(ea, e.gpr_value(i.DS.RA)); + c.add(ea, imm(XEEXTS16(i.DS.DS << 2))); + } else { + c.mov(ea, imm(XEEXTS16(i.DS.DS << 2))); + } + GpVar v = e.ReadMemory(i.address, ea, 4, false); + v = e.sign_extend(v, 4, 8); + e.update_gpr_value(i.DS.RT, v); + + return 0; +} + +XEEMITTER(lwaux, 0x7C0002EA, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // EA <- (RA) + (RB) + // RT <- EXTS(MEM(EA, 4)) + // RA <- EA + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.X.RA)); + c.add(ea, e.gpr_value(i.X.RB)); + GpVar v = e.ReadMemory(i.address, ea, 4, false); + v = e.sign_extend(v, 4, 8); + e.update_gpr_value(i.X.RT, v); + e.update_gpr_value(i.X.RA, ea); + + return 0; +} + +XEEMITTER(lwax, 0x7C0002AA, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + (RB) + // RT <- EXTS(MEM(EA, 4)) + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.X.RB)); + if (i.X.RA) { + c.add(ea, e.gpr_value(i.X.RA)); + } + GpVar v = e.ReadMemory(i.address, ea, 4, false); + v = e.sign_extend(v, 4, 8); + e.update_gpr_value(i.X.RT, v); + + return 0; +} + +XEEMITTER(lwz, 0x80000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + EXTS(D) + // RT <- i32.0 || MEM(EA, 4) + + 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, 4, false); + // Zero extend done by ReadMemory. + e.update_gpr_value(i.D.RT, v); + + return 0; +} + +XEEMITTER(lwzu, 0x84000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // EA <- (RA) + EXTS(D) + // RT <- i32.0 || MEM(EA, 4) + // RA <- EA + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.D.RA)); + c.add(ea, imm(XEEXTS16(i.D.DS))); + GpVar v = e.ReadMemory(i.address, ea, 4, false); + // Zero extend done by ReadMemory. + e.update_gpr_value(i.D.RT, v); + e.update_gpr_value(i.D.RA, ea); + + return 0; +} + +XEEMITTER(lwzux, 0x7C00006E, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // EA <- (RA) + (RB) + // RT <- i32.0 || MEM(EA, 4) + // RA <- EA + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.X.RA)); + c.add(ea, e.gpr_value(i.X.RB)); + GpVar v = e.ReadMemory(i.address, ea, 4, false); + // Zero extend done by ReadMemory. + e.update_gpr_value(i.X.RT, v); + e.update_gpr_value(i.X.RA, ea); + + return 0; +} + +XEEMITTER(lwzx, 0x7C00002E, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + (RB) + // RT <- i32.0 || MEM(EA, 4) + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.X.RB)); + if (i.X.RA) { + c.add(ea, e.gpr_value(i.X.RA)); + } + GpVar v = e.ReadMemory(i.address, ea, 4, false); + // Zero extend done by ReadMemory. + e.update_gpr_value(i.X.RT, v); + + return 0; +} + + +// Integer store (A-14) + +XEEMITTER(stb, 0x98000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + EXTS(D) + // MEM(EA, 1) <- (RS)[56:63] + + 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.gpr_value(i.D.RT); + e.WriteMemory(i.address, ea, 1, v); + + return 0; +} + +XEEMITTER(stbu, 0x9C000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // EA <- (RA) + EXTS(D) + // MEM(EA, 1) <- (RS)[56:63] + // RA <- EA + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.D.RA)); + c.add(ea, imm(XEEXTS16(i.D.DS))); + GpVar v = e.gpr_value(i.D.RT); + e.WriteMemory(i.address, ea, 1, v); + e.update_gpr_value(i.D.RA, ea); + + return 0; +} + +XEEMITTER(stbux, 0x7C0001EE, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // EA <- (RA) + (RB) + // MEM(EA, 1) <- (RS)[56:63] + // RA <- EA + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.X.RA)); + c.add(ea, e.gpr_value(i.X.RB)); + GpVar v = e.gpr_value(i.X.RT); + e.WriteMemory(i.address, ea, 1, v); + e.update_gpr_value(i.X.RA, ea); + + return 0; +} + +XEEMITTER(stbx, 0x7C0001AE, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + (RB) + // MEM(EA, 1) <- (RS)[56:63] + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.X.RB)); + if (i.D.RA) { + c.add(ea, e.gpr_value(i.X.RA)); + } + GpVar v = e.gpr_value(i.X.RT); + e.WriteMemory(i.address, ea, 1, v); + + return 0; +} + +XEEMITTER(std, 0xF8000000, DS )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + EXTS(DS || 0b00) + // MEM(EA, 8) <- (RS) + + GpVar ea(c.newGpVar()); + if (i.DS.RA) { + c.mov(ea, e.gpr_value(i.DS.RA)); + c.add(ea, imm(XEEXTS16(i.DS.DS << 2))); + } else { + c.mov(ea, imm(XEEXTS16(i.DS.DS << 2))); + } + GpVar v = e.gpr_value(i.DS.RT); + e.WriteMemory(i.address, ea, 8, v); + + return 0; +} + +XEEMITTER(stdu, 0xF8000001, DS )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // EA <- (RA) + EXTS(DS || 0b00) + // MEM(EA, 8) <- (RS) + // RA <- EA + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.DS.RA)); + c.add(ea, imm(XEEXTS16(i.DS.DS << 2))); + GpVar v = e.gpr_value(i.DS.RT); + e.WriteMemory(i.address, ea, 8, v); + e.update_gpr_value(i.DS.RA, ea); + + return 0; +} + +XEEMITTER(stdux, 0x7C00016A, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + (RB) + // MEM(EA, 8) <- (RS) + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.X.RB)); + if (i.X.RA) { + c.add(ea, e.gpr_value(i.X.RA)); + } + GpVar v = e.gpr_value(i.X.RT); + e.WriteMemory(i.address, ea, 8, v); + + return 0; +} + +XEEMITTER(stdx, 0x7C00012A, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // EA <- (RA) + (RB) + // MEM(EA, 8) <- (RS) + // RA <- EA + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.X.RA)); + c.add(ea, e.gpr_value(i.X.RB)); + GpVar v = e.gpr_value(i.X.RT); + e.WriteMemory(i.address, ea, 8, v); + e.update_gpr_value(i.X.RA, ea); + + return 0; +} + +XEEMITTER(sth, 0xB0000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + EXTS(D) + // MEM(EA, 2) <- (RS)[48:63] + + 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.gpr_value(i.D.RT); + e.WriteMemory(i.address, ea, 2, v); + + return 0; +} + +XEEMITTER(sthu, 0xB4000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // EA <- (RA) + EXTS(D) + // MEM(EA, 2) <- (RS)[48:63] + // RA <- EA + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.D.RA)); + c.add(ea, imm(XEEXTS16(i.D.DS))); + GpVar v = e.gpr_value(i.D.RT); + e.WriteMemory(i.address, ea, 2, v); + e.update_gpr_value(i.D.RA, ea); + + return 0; +} + +XEEMITTER(sthux, 0x7C00036E, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // EA <- (RA) + (RB) + // MEM(EA, 2) <- (RS)[48:63] + // RA <- EA + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.X.RA)); + c.add(ea, e.gpr_value(i.X.RB)); + GpVar v = e.gpr_value(i.X.RT); + e.WriteMemory(i.address, ea, 2, v); + e.update_gpr_value(i.X.RA, ea); + + return 0; +} + +XEEMITTER(sthx, 0x7C00032E, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + (RB) + // MEM(EA, 2) <- (RS)[48:63] + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.X.RB)); + if (i.D.RA) { + c.add(ea, e.gpr_value(i.X.RA)); + } + GpVar v = e.gpr_value(i.X.RT); + e.WriteMemory(i.address, ea, 2, v); + + return 0; +} + +XEEMITTER(stw, 0x90000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + EXTS(D) + // MEM(EA, 4) <- (RS)[32:63] + + 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.gpr_value(i.D.RT); + e.WriteMemory(i.address, ea, 4, v); + + return 0; +} + +XEEMITTER(stwu, 0x94000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // EA <- (RA) + EXTS(D) + // MEM(EA, 4) <- (RS)[32:63] + // RA <- EA + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.D.RA)); + c.add(ea, imm(XEEXTS16(i.D.DS))); + GpVar v = e.gpr_value(i.D.RT); + e.WriteMemory(i.address, ea, 4, v); + e.update_gpr_value(i.D.RA, ea); + + return 0; +} + +XEEMITTER(stwux, 0x7C00016E, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // EA <- (RA) + (RB) + // MEM(EA, 4) <- (RS)[32:63] + // RA <- EA + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.X.RA)); + c.add(ea, e.gpr_value(i.X.RB)); + GpVar v = e.gpr_value(i.X.RT); + e.WriteMemory(i.address, ea, 4, v); + e.update_gpr_value(i.X.RA, ea); + + return 0; +} + +XEEMITTER(stwx, 0x7C00012E, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + (RB) + // MEM(EA, 4) <- (RS)[32:63] + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.X.RB)); + if (i.X.RA) { + c.add(ea, e.gpr_value(i.X.RA)); + } + GpVar v = e.gpr_value(i.X.RT); + e.WriteMemory(i.address, ea, 4, v); + + return 0; +} + + +// Integer load and store with byte reverse (A-1 + +XEEMITTER(lhbrx, 0x7C00062C, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + XEINSTRNOTIMPLEMENTED(); + return 1; +} + +XEEMITTER(lwbrx, 0x7C00042C, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + XEINSTRNOTIMPLEMENTED(); + return 1; +} + +XEEMITTER(ldbrx, 0x7C000428, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + XEINSTRNOTIMPLEMENTED(); + return 1; +} + +XEEMITTER(sthbrx, 0x7C00072C, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + XEINSTRNOTIMPLEMENTED(); + return 1; +} + +XEEMITTER(stwbrx, 0x7C00052C, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + XEINSTRNOTIMPLEMENTED(); + return 1; +} + +XEEMITTER(stdbrx, 0x7C000528, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + XEINSTRNOTIMPLEMENTED(); + return 1; +} + + +// Integer load and store multiple (A-16) + +XEEMITTER(lmw, 0xB8000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { + XEINSTRNOTIMPLEMENTED(); + return 1; +} + +XEEMITTER(stmw, 0xBC000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { + XEINSTRNOTIMPLEMENTED(); + return 1; +} + + +// Integer load and store string (A-17) + +XEEMITTER(lswi, 0x7C0004AA, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + XEINSTRNOTIMPLEMENTED(); + return 1; +} + +XEEMITTER(lswx, 0x7C00042A, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + XEINSTRNOTIMPLEMENTED(); + return 1; +} + +XEEMITTER(stswi, 0x7C0005AA, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + XEINSTRNOTIMPLEMENTED(); + return 1; +} + +XEEMITTER(stswx, 0x7C00052A, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + XEINSTRNOTIMPLEMENTED(); + return 1; +} + + +// Memory synchronization (A-18) + +XEEMITTER(eieio, 0x7C0006AC, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + XEINSTRNOTIMPLEMENTED(); + return 1; +} + +XEEMITTER(isync, 0x4C00012C, XL )(X64Emitter& e, X86Compiler& c, InstrData& i) { + XEINSTRNOTIMPLEMENTED(); + return 1; +} + +XEEMITTER(ldarx, 0x7C0000A8, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + XEINSTRNOTIMPLEMENTED(); + return 1; +} + +XEEMITTER(lwarx, 0x7C000028, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + (RB) + // RESERVE <- 1 + // RESERVE_LENGTH <- 4 + // RESERVE_ADDR <- real_addr(EA) + // RT <- i32.0 || MEM(EA, 4) + + // TODO(benvanik): make this right + + GpVar ea(c.newGpVar()); + c.mov(ea, e.gpr_value(i.X.RB)); + if (i.X.RA) { + c.add(ea, e.gpr_value(i.X.RA)); + } + GpVar v = e.ReadMemory(i.address, ea, 4, /* acquire */ true); + e.update_gpr_value(i.X.RT, v); + + return 0; +} + +XEEMITTER(stdcx, 0x7C0001AD, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + XEINSTRNOTIMPLEMENTED(); + return 1; +} + +XEEMITTER(stwcx, 0x7C00012D, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { + // if RA = 0 then + // b <- 0 + // else + // b <- (RA) + // EA <- b + (RB) + // RESERVE stuff... + // MEM(EA, 4) <- (RS)[32:63] + // n <- 1 if store performed + // CR0[LT GT EQ SO] = 0b00 || n || XER[SO] + + // TODO(benvanik): make this right + + 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.gpr_value(i.D.RT); + e.WriteMemory(i.address, ea, 4, v, /* release */ true); + + // We always succeed. + e.update_cr_value(0, e.get_uint64(1 << 2)); + + return 0; +} XEEMITTER(sync, 0x7C0004AC, X )(X64Emitter& e, X86Compiler& c, InstrData& i) { XEINSTRNOTIMPLEMENTED(); @@ -758,7 +833,7 @@ XEEMITTER(sync, 0x7C0004AC, X )(X64Emitter& e, X86Compiler& c, InstrDat } -// // Floating-point load (A-19) +// Floating-point load (A-19) // XEEMITTER(lfd, 0xC8000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { // // if RA = 0 then @@ -768,11 +843,11 @@ XEEMITTER(sync, 0x7C0004AC, X )(X64Emitter& e, X86Compiler& c, InstrDat // // EA <- b + EXTS(D) // // FRT <- MEM(EA, 8) -// jit_value_t ea = e.get_int64(XEEXTS16(i.D.DS)); +// 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); // } -// jit_value_t v = e.ReadMemory(i.address, ea, 8, false); +// GpVar v = e.ReadMemory(i.address, ea, 8, false); // v = b.CreateBitCast(v, jit_type_float64); // e.update_fpr_value(i.D.RT, v); @@ -784,8 +859,8 @@ XEEMITTER(sync, 0x7C0004AC, X )(X64Emitter& e, X86Compiler& c, InstrDat // // FRT <- MEM(EA, 8) // // RA <- EA -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.D.RA), e.get_int64(XEEXTS16(i.D.DS))); -// jit_value_t v = e.ReadMemory(i.address, ea, 8, false); +// GpVar ea = jit_insn_add(f, e.gpr_value(i.D.RA), e.get_int64(XEEXTS16(i.D.DS))); +// GpVar v = e.ReadMemory(i.address, ea, 8, false); // v = b.CreateBitCast(v, jit_type_float64); // e.update_fpr_value(i.D.RT, v); // e.update_gpr_value(i.D.RA, ea); @@ -798,8 +873,8 @@ XEEMITTER(sync, 0x7C0004AC, X )(X64Emitter& e, X86Compiler& c, InstrDat // // FRT <- MEM(EA, 8) // // RA <- EA -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// jit_value_t v = e.ReadMemory(i.address, ea, 8, false); +// GpVar ea = jit_insn_add(f, e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); +// GpVar v = e.ReadMemory(i.address, ea, 8, false); // v = b.CreateBitCast(v, jit_type_float64); // e.update_fpr_value(i.X.RT, v); // e.update_gpr_value(i.X.RA, ea); @@ -815,11 +890,11 @@ XEEMITTER(sync, 0x7C0004AC, X )(X64Emitter& e, X86Compiler& c, InstrDat // // EA <- b + (RB) // // FRT <- MEM(EA, 8) -// jit_value_t ea = e.gpr_value(i.X.RB); +// GpVar ea = e.gpr_value(i.X.RB); // if (i.X.RA) { // ea = jit_insn_add(f, e.gpr_value(i.X.RA), ea); // } -// jit_value_t v = e.ReadMemory(i.address, ea, 8, false); +// GpVar v = e.ReadMemory(i.address, ea, 8, false); // v = b.CreateBitCast(v, jit_type_float64); // e.update_fpr_value(i.X.RT, v); @@ -834,11 +909,11 @@ XEEMITTER(sync, 0x7C0004AC, X )(X64Emitter& e, X86Compiler& c, InstrDat // // EA <- b + EXTS(D) // // FRT <- DOUBLE(MEM(EA, 4)) -// jit_value_t ea = e.get_int64(XEEXTS16(i.D.DS)); +// 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); // } -// jit_value_t v = e.ReadMemory(i.address, ea, 4, false); +// GpVar v = e.ReadMemory(i.address, ea, 4, false); // v = b.CreateFPExt(b.CreateBitCast(v, b.getFloatTy()), jit_type_float64); // e.update_fpr_value(i.D.RT, v); @@ -850,8 +925,8 @@ XEEMITTER(sync, 0x7C0004AC, X )(X64Emitter& e, X86Compiler& c, InstrDat // // FRT <- DOUBLE(MEM(EA, 4)) // // RA <- EA -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.D.RA), e.get_int64(XEEXTS16(i.D.DS))); -// jit_value_t v = e.ReadMemory(i.address, ea, 4, false); +// GpVar ea = jit_insn_add(f, e.gpr_value(i.D.RA), e.get_int64(XEEXTS16(i.D.DS))); +// GpVar v = e.ReadMemory(i.address, ea, 4, false); // v = b.CreateFPExt(b.CreateBitCast(v, b.getFloatTy()), jit_type_float64); // e.update_fpr_value(i.D.RT, v); // e.update_gpr_value(i.D.RA, ea); @@ -864,8 +939,8 @@ XEEMITTER(sync, 0x7C0004AC, X )(X64Emitter& e, X86Compiler& c, InstrDat // // FRT <- DOUBLE(MEM(EA, 4)) // // RA <- EA -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// jit_value_t v = e.ReadMemory(i.address, ea, 4, false); +// GpVar ea = jit_insn_add(f, e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); +// GpVar v = e.ReadMemory(i.address, ea, 4, false); // v = b.CreateFPExt(b.CreateBitCast(v, b.getFloatTy()), jit_type_float64); // e.update_fpr_value(i.X.RT, v); // e.update_gpr_value(i.X.RA, ea); @@ -881,11 +956,11 @@ XEEMITTER(sync, 0x7C0004AC, X )(X64Emitter& e, X86Compiler& c, InstrDat // // EA <- b + (RB) // // FRT <- DOUBLE(MEM(EA, 4)) -// jit_value_t ea = e.gpr_value(i.X.RB); +// GpVar ea = e.gpr_value(i.X.RB); // if (i.X.RA) { // ea = jit_insn_add(f, e.gpr_value(i.X.RA), ea); // } -// jit_value_t v = e.ReadMemory(i.address, ea, 4, false); +// GpVar v = e.ReadMemory(i.address, ea, 4, false); // v = b.CreateFPExt(b.CreateBitCast(v, b.getFloatTy()), jit_type_float64); // e.update_fpr_value(i.X.RT, v); @@ -893,7 +968,7 @@ XEEMITTER(sync, 0x7C0004AC, X )(X64Emitter& e, X86Compiler& c, InstrDat // } -// // Floating-point store (A-20) +// Floating-point store (A-20) // XEEMITTER(stfd, 0xD8000000, D )(X64Emitter& e, X86Compiler& c, InstrData& i) { // // if RA = 0 then @@ -903,11 +978,11 @@ XEEMITTER(sync, 0x7C0004AC, X )(X64Emitter& e, X86Compiler& c, InstrDat // // EA <- b + EXTS(D) // // MEM(EA, 8) <- (FRS) -// jit_value_t ea = e.get_int64(XEEXTS16(i.D.DS)); +// 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); // } -// jit_value_t v = e.fpr_value(i.D.RT); +// GpVar v = e.fpr_value(i.D.RT); // v = b.CreateBitCast(v, jit_type_nint); // e.WriteMemory(i.address, ea, 8, v); @@ -919,9 +994,9 @@ XEEMITTER(sync, 0x7C0004AC, X )(X64Emitter& e, X86Compiler& c, InstrDat // // MEM(EA, 8) <- (FRS) // // RA <- EA -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.D.RA), +// GpVar ea = jit_insn_add(f, e.gpr_value(i.D.RA), // e.get_int64(XEEXTS16(i.D.DS))); -// jit_value_t v = e.fpr_value(i.D.RT); +// GpVar v = e.fpr_value(i.D.RT); // v = b.CreateBitCast(v, jit_type_nint); // e.WriteMemory(i.address, ea, 8, v); // e.update_gpr_value(i.D.RA, ea); @@ -934,8 +1009,8 @@ XEEMITTER(sync, 0x7C0004AC, X )(X64Emitter& e, X86Compiler& c, InstrDat // // MEM(EA, 8) <- (FRS) // // RA <- EA -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// jit_value_t v = e.fpr_value(i.X.RT); +// GpVar ea = jit_insn_add(f, e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); +// GpVar v = e.fpr_value(i.X.RT); // v = b.CreateBitCast(v, jit_type_nint); // e.WriteMemory(i.address, ea, 8, v); // e.update_gpr_value(i.X.RA, ea); @@ -951,11 +1026,11 @@ XEEMITTER(sync, 0x7C0004AC, X )(X64Emitter& e, X86Compiler& c, InstrDat // // EA <- b + (RB) // // MEM(EA, 8) <- (FRS) -// jit_value_t ea = e.gpr_value(i.X.RB); +// GpVar ea = e.gpr_value(i.X.RB); // if (i.X.RA) { // ea = jit_insn_add(f, e.gpr_value(i.X.RA), ea); // } -// jit_value_t v = e.fpr_value(i.X.RT); +// GpVar v = e.fpr_value(i.X.RT); // v = b.CreateBitCast(v, jit_type_nint); // e.WriteMemory(i.address, ea, 8, v); @@ -970,11 +1045,11 @@ XEEMITTER(sync, 0x7C0004AC, X )(X64Emitter& e, X86Compiler& c, InstrDat // // EA <- b + (RB) // // MEM(EA, 4) <- (FRS)[32:63] -// jit_value_t ea = e.gpr_value(i.X.RB); +// GpVar ea = e.gpr_value(i.X.RB); // if (i.X.RA) { // ea = jit_insn_add(f, e.gpr_value(i.D.RA), ea); // } -// jit_value_t v = e.fpr_value(i.X.RT); +// GpVar v = e.fpr_value(i.X.RT); // v = b.CreateBitCast(v, jit_type_nint); // e.WriteMemory(i.address, ea, 4, v); @@ -989,11 +1064,11 @@ XEEMITTER(sync, 0x7C0004AC, X )(X64Emitter& e, X86Compiler& c, InstrDat // // EA <- b + EXTS(D) // // MEM(EA, 4) <- SINGLE(FRS) -// jit_value_t ea = e.get_int64(XEEXTS16(i.D.DS)); +// 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); // } -// jit_value_t v = e.fpr_value(i.D.RT); +// GpVar v = e.fpr_value(i.D.RT); // v = b.CreateBitCast(b.CreateFPTrunc(v, b.getFloatTy()), b.getInt32Ty()); // e.WriteMemory(i.address, ea, 4, v); @@ -1005,9 +1080,9 @@ XEEMITTER(sync, 0x7C0004AC, X )(X64Emitter& e, X86Compiler& c, InstrDat // // MEM(EA, 4) <- SINGLE(FRS) // // RA <- EA -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.D.RA), +// GpVar ea = jit_insn_add(f, e.gpr_value(i.D.RA), // e.get_int64(XEEXTS16(i.D.DS))); -// jit_value_t v = e.fpr_value(i.D.RT); +// GpVar v = e.fpr_value(i.D.RT); // v = b.CreateBitCast(b.CreateFPTrunc(v, b.getFloatTy()), b.getInt32Ty()); // e.WriteMemory(i.address, ea, 4, v); // e.update_gpr_value(i.D.RA, ea); @@ -1020,8 +1095,8 @@ XEEMITTER(sync, 0x7C0004AC, X )(X64Emitter& e, X86Compiler& c, InstrDat // // MEM(EA, 4) <- SINGLE(FRS) // // RA <- EA -// jit_value_t ea = jit_insn_add(f, e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); -// jit_value_t v = e.fpr_value(i.X.RT); +// GpVar ea = jit_insn_add(f, e.gpr_value(i.X.RA), e.gpr_value(i.X.RB)); +// GpVar v = e.fpr_value(i.X.RT); // v = b.CreateBitCast(b.CreateFPTrunc(v, b.getFloatTy()), b.getInt32Ty()); // e.WriteMemory(i.address, ea, 4, v); // e.update_gpr_value(i.X.RA, ea); @@ -1037,11 +1112,11 @@ XEEMITTER(sync, 0x7C0004AC, X )(X64Emitter& e, X86Compiler& c, InstrDat // // EA <- b + (RB) // // MEM(EA, 4) <- SINGLE(FRS) -// jit_value_t ea = e.gpr_value(i.X.RB); +// GpVar ea = e.gpr_value(i.X.RB); // if (i.X.RA) { // ea = jit_insn_add(f, e.gpr_value(i.X.RA), ea); // } -// jit_value_t v = e.fpr_value(i.X.RT); +// GpVar v = e.fpr_value(i.X.RT); // v = b.CreateBitCast(b.CreateFPTrunc(v, b.getFloatTy()), b.getInt32Ty()); // e.WriteMemory(i.address, ea, 4, v); @@ -1086,63 +1161,63 @@ XEEMITTER(icbi, 0x7C0007AC, X )(X64Emitter& e, X86Compiler& c, InstrDat void X64RegisterEmitCategoryMemory() { - // XEREGISTERINSTR(lbz, 0x88000000); - // XEREGISTERINSTR(lbzu, 0x8C000000); - // XEREGISTERINSTR(lbzux, 0x7C0000EE); - // XEREGISTERINSTR(lbzx, 0x7C0000AE); - // XEREGISTERINSTR(ld, 0xE8000000); - // XEREGISTERINSTR(ldu, 0xE8000001); - // XEREGISTERINSTR(ldux, 0x7C00006A); - // XEREGISTERINSTR(ldx, 0x7C00002A); - // XEREGISTERINSTR(lha, 0xA8000000); - // XEREGISTERINSTR(lhau, 0xAC000000); - // XEREGISTERINSTR(lhaux, 0x7C0002EE); - // XEREGISTERINSTR(lhax, 0x7C0002AE); - // XEREGISTERINSTR(lhz, 0xA0000000); - // XEREGISTERINSTR(lhzu, 0xA4000000); - // XEREGISTERINSTR(lhzux, 0x7C00026E); - // XEREGISTERINSTR(lhzx, 0x7C00022E); - // XEREGISTERINSTR(lwa, 0xE8000002); - // XEREGISTERINSTR(lwaux, 0x7C0002EA); - // XEREGISTERINSTR(lwax, 0x7C0002AA); - // XEREGISTERINSTR(lwz, 0x80000000); - // XEREGISTERINSTR(lwzu, 0x84000000); - // XEREGISTERINSTR(lwzux, 0x7C00006E); - // XEREGISTERINSTR(lwzx, 0x7C00002E); - // XEREGISTERINSTR(stb, 0x98000000); - // XEREGISTERINSTR(stbu, 0x9C000000); - // XEREGISTERINSTR(stbux, 0x7C0001EE); - // XEREGISTERINSTR(stbx, 0x7C0001AE); - // XEREGISTERINSTR(std, 0xF8000000); - // XEREGISTERINSTR(stdu, 0xF8000001); - // XEREGISTERINSTR(stdux, 0x7C00016A); - // XEREGISTERINSTR(stdx, 0x7C00012A); - // XEREGISTERINSTR(sth, 0xB0000000); - // XEREGISTERINSTR(sthu, 0xB4000000); - // XEREGISTERINSTR(sthux, 0x7C00036E); - // XEREGISTERINSTR(sthx, 0x7C00032E); - // XEREGISTERINSTR(stw, 0x90000000); - // XEREGISTERINSTR(stwu, 0x94000000); - // XEREGISTERINSTR(stwux, 0x7C00016E); - // XEREGISTERINSTR(stwx, 0x7C00012E); - // XEREGISTERINSTR(lhbrx, 0x7C00062C); - // XEREGISTERINSTR(lwbrx, 0x7C00042C); - // XEREGISTERINSTR(ldbrx, 0x7C000428); - // XEREGISTERINSTR(sthbrx, 0x7C00072C); - // XEREGISTERINSTR(stwbrx, 0x7C00052C); - // XEREGISTERINSTR(stdbrx, 0x7C000528); - // XEREGISTERINSTR(lmw, 0xB8000000); - // XEREGISTERINSTR(stmw, 0xBC000000); - // XEREGISTERINSTR(lswi, 0x7C0004AA); - // XEREGISTERINSTR(lswx, 0x7C00042A); - // XEREGISTERINSTR(stswi, 0x7C0005AA); - // XEREGISTERINSTR(stswx, 0x7C00052A); - // XEREGISTERINSTR(eieio, 0x7C0006AC); - // XEREGISTERINSTR(isync, 0x4C00012C); - // XEREGISTERINSTR(ldarx, 0x7C0000A8); - // XEREGISTERINSTR(lwarx, 0x7C000028); - // XEREGISTERINSTR(stdcx, 0x7C0001AD); - // XEREGISTERINSTR(stwcx, 0x7C00012D); + XEREGISTERINSTR(lbz, 0x88000000); + XEREGISTERINSTR(lbzu, 0x8C000000); + XEREGISTERINSTR(lbzux, 0x7C0000EE); + XEREGISTERINSTR(lbzx, 0x7C0000AE); + XEREGISTERINSTR(ld, 0xE8000000); + XEREGISTERINSTR(ldu, 0xE8000001); + XEREGISTERINSTR(ldux, 0x7C00006A); + XEREGISTERINSTR(ldx, 0x7C00002A); + XEREGISTERINSTR(lha, 0xA8000000); + XEREGISTERINSTR(lhau, 0xAC000000); + XEREGISTERINSTR(lhaux, 0x7C0002EE); + XEREGISTERINSTR(lhax, 0x7C0002AE); + XEREGISTERINSTR(lhz, 0xA0000000); + XEREGISTERINSTR(lhzu, 0xA4000000); + XEREGISTERINSTR(lhzux, 0x7C00026E); + XEREGISTERINSTR(lhzx, 0x7C00022E); + XEREGISTERINSTR(lwa, 0xE8000002); + XEREGISTERINSTR(lwaux, 0x7C0002EA); + XEREGISTERINSTR(lwax, 0x7C0002AA); + XEREGISTERINSTR(lwz, 0x80000000); + XEREGISTERINSTR(lwzu, 0x84000000); + XEREGISTERINSTR(lwzux, 0x7C00006E); + XEREGISTERINSTR(lwzx, 0x7C00002E); + XEREGISTERINSTR(stb, 0x98000000); + XEREGISTERINSTR(stbu, 0x9C000000); + XEREGISTERINSTR(stbux, 0x7C0001EE); + XEREGISTERINSTR(stbx, 0x7C0001AE); + XEREGISTERINSTR(std, 0xF8000000); + XEREGISTERINSTR(stdu, 0xF8000001); + XEREGISTERINSTR(stdux, 0x7C00016A); + XEREGISTERINSTR(stdx, 0x7C00012A); + XEREGISTERINSTR(sth, 0xB0000000); + XEREGISTERINSTR(sthu, 0xB4000000); + XEREGISTERINSTR(sthux, 0x7C00036E); + XEREGISTERINSTR(sthx, 0x7C00032E); + XEREGISTERINSTR(stw, 0x90000000); + XEREGISTERINSTR(stwu, 0x94000000); + XEREGISTERINSTR(stwux, 0x7C00016E); + XEREGISTERINSTR(stwx, 0x7C00012E); + XEREGISTERINSTR(lhbrx, 0x7C00062C); + XEREGISTERINSTR(lwbrx, 0x7C00042C); + XEREGISTERINSTR(ldbrx, 0x7C000428); + XEREGISTERINSTR(sthbrx, 0x7C00072C); + XEREGISTERINSTR(stwbrx, 0x7C00052C); + XEREGISTERINSTR(stdbrx, 0x7C000528); + XEREGISTERINSTR(lmw, 0xB8000000); + XEREGISTERINSTR(stmw, 0xBC000000); + XEREGISTERINSTR(lswi, 0x7C0004AA); + XEREGISTERINSTR(lswx, 0x7C00042A); + XEREGISTERINSTR(stswi, 0x7C0005AA); + XEREGISTERINSTR(stswx, 0x7C00052A); + XEREGISTERINSTR(eieio, 0x7C0006AC); + XEREGISTERINSTR(isync, 0x4C00012C); + XEREGISTERINSTR(ldarx, 0x7C0000A8); + XEREGISTERINSTR(lwarx, 0x7C000028); + XEREGISTERINSTR(stdcx, 0x7C0001AD); + XEREGISTERINSTR(stwcx, 0x7C00012D); XEREGISTERINSTR(sync, 0x7C0004AC); // XEREGISTERINSTR(lfd, 0xC8000000); // XEREGISTERINSTR(lfdu, 0xCC000000); diff --git a/src/xenia/cpu/x64/x64_emitter.cc b/src/xenia/cpu/x64/x64_emitter.cc index 174b7becf..db161fb7c 100644 --- a/src/xenia/cpu/x64/x64_emitter.cc +++ b/src/xenia/cpu/x64/x64_emitter.cc @@ -585,7 +585,7 @@ void X64Emitter::GenerateBasicBlock(FunctionBlock* block) { InstrEmitter emit = (InstrEmitter)i.type->emit; if (!i.type->emit || emit(*this, compiler_, i)) { // This printf is handy for sort/uniquify to find instructions. - //printf("unimplinstr %s\n", i.type->name); + printf("unimplinstr %s\n", i.type->name); XELOGCPU("Unimplemented instr %.8X %.8X %s", ia, i.code, i.type->name); @@ -1166,10 +1166,10 @@ void X64Emitter::update_xer_value(GpVar& value) { X86Compiler& c = compiler_; if (FLAGS_cache_registers) { XEASSERT(locals_.xer.getId() != kInvalidValue); - c.mov(locals_.xer, zero_extend(value, 8)); + c.mov(locals_.xer, zero_extend(value, 0, 8)); } else { c.mov(qword_ptr(c.getGpArg(0), offsetof(xe_ppc_state_t, xer)), - zero_extend(value, 8)); + zero_extend(value, 0, 8)); } } @@ -1180,7 +1180,7 @@ void X64Emitter::update_xer_with_overflow(GpVar& value) { // Expects a i1 indicating overflow. // Trust the caller that if it's larger than that it's already truncated. - value = zero_extend(value, 8); + value = zero_extend(value, 1, 8); GpVar& xer = xer_value(); xer = jit_insn_and(fn_, xer, get_uint64(0xFFFFFFFFBFFFFFFF)); // clear bit 30 @@ -1213,7 +1213,7 @@ void X64Emitter::update_xer_with_overflow_and_carry(GpVar& value) { // Expects a i1 indicating overflow. // Trust the caller that if it's larger than that it's already truncated. - value = zero_extend(value, jit_type_nuint); + value = zero_extend(value, 1, 8); // This is effectively an update_xer_with_overflow followed by an // update_xer_with_carry, but since the logic is largely the same share it. @@ -1244,10 +1244,10 @@ void X64Emitter::update_lr_value(GpVar& value) { X86Compiler& c = compiler_; if (FLAGS_cache_registers) { XEASSERT(locals_.lr.getId() != kInvalidValue); - c.mov(locals_.lr, zero_extend(value, 8)); + c.mov(locals_.lr, zero_extend(value, 0, 8)); } else { c.mov(qword_ptr(c.getGpArg(0), offsetof(xe_ppc_state_t, lr)), - zero_extend(value, 8)); + zero_extend(value, 0, 8)); } } @@ -1279,10 +1279,10 @@ void X64Emitter::update_ctr_value(GpVar& value) { X86Compiler& c = compiler_; if (FLAGS_cache_registers) { XEASSERT(locals_.ctr.getId() != kInvalidValue); - c.mov(locals_.ctr, zero_extend(value, 8)); + c.mov(locals_.ctr, zero_extend(value, 0, 8)); } else { c.mov(qword_ptr(c.getGpArg(0), offsetof(xe_ppc_state_t, ctr)), - zero_extend(value, 8)); + zero_extend(value, 0, 8)); } } @@ -1409,10 +1409,10 @@ void X64Emitter::update_gpr_value(uint32_t n, GpVar& value) { if (FLAGS_cache_registers) { XEASSERT(locals_.gpr[n].getId() != kInvalidValue); - c.mov(locals_.gpr[n], zero_extend(value, 8)); + c.mov(locals_.gpr[n], zero_extend(value, 0, 8)); } else { c.mov(qword_ptr(c.getGpArg(0), offsetof(xe_ppc_state_t, r) + 8 * n), - zero_extend(value, 8)); + zero_extend(value, 0, 8)); } } @@ -1442,135 +1442,126 @@ void X64Emitter::update_fpr_value(uint32_t n, GpVar& value) { } } -// GpVar& X64Emitter::TouchMemoryAddress(uint32_t cia, GpVar& addr) { -// // Input address is always in 32-bit space. -// addr = jit_insn_and(fn_, -// zero_extend(addr, jit_type_nuint), -// jit_value_create_nint_constant(fn_, jit_type_uint, UINT_MAX)); +GpVar X64Emitter::TouchMemoryAddress(uint32_t cia, GpVar& addr) { + X86Compiler& c = compiler_; -// // Add runtime memory address checks, if needed. -// // if (FLAGS_memory_address_verification) { -// // BasicBlock* invalid_bb = BasicBlock::Create(*context_, "", fn_); -// // BasicBlock* valid_bb = BasicBlock::Create(*context_, "", fn_); + // Input address is always in 32-bit space. + GpVar real_address(c.newGpVar()); + c.mov(real_address, addr.r32()); -// // // The heap starts at 0x1000 - if we write below that we're boned. -// // jit_value_t gt = b.CreateICmpUGE(addr, b.getInt64(0x00001000)); -// // b.CreateCondBr(gt, valid_bb, invalid_bb); + // Add runtime memory address checks, if needed. + if (FLAGS_memory_address_verification) { + // BasicBlock* invalid_bb = BasicBlock::Create(*context_, "", fn_); + // BasicBlock* valid_bb = BasicBlock::Create(*context_, "", fn_); -// // b.SetInsertPoint(invalid_bb); -// // jit_value_t access_violation = gen_module_->getFunction("XeAccessViolation"); -// // SpillRegisters(); -// // b.CreateCall3(access_violation, -// // fn_->arg_begin(), -// // b.getInt32(cia), -// // addr); -// // b.CreateBr(valid_bb); + // // The heap starts at 0x1000 - if we write below that we're boned. + // jit_value_t gt = b.CreateICmpUGE(addr, b.getInt64(0x00001000)); + // b.CreateCondBr(gt, valid_bb, invalid_bb); -// // b.SetInsertPoint(valid_bb); -// // } + // b.SetInsertPoint(invalid_bb); + // jit_value_t access_violation = gen_module_->getFunction("XeAccessViolation"); + // SpillRegisters(); + // b.CreateCall3(access_violation, + // fn_->arg_begin(), + // b.getInt32(cia), + // addr); + // b.CreateBr(valid_bb); -// // Rebase off of memory pointer. -// addr = jit_insn_add(fn_, -// addr, -// jit_value_create_nint_constant(fn_, -// jit_type_nuint, (jit_nuint)xe_memory_addr(memory_, 0))); + // b.SetInsertPoint(valid_bb); + } -// return addr; -// } + // Rebase off of memory pointer. + uint64_t membase = (uint64_t)xe_memory_addr(memory_, 0); + c.add(real_address, get_uint64(membase)); + return real_address; +} -// GpVar& X64Emitter::ReadMemory( -// uint32_t cia, GpVar& addr, uint32_t size, bool acquire) { -// jit_type_t data_type = NULL; -// bool needs_swap = false; -// switch (size) { -// case 1: -// data_type = jit_type_ubyte; -// break; -// case 2: -// data_type = jit_type_ushort; -// needs_swap = true; -// break; -// case 4: -// data_type = jit_type_uint; -// needs_swap = true; -// break; -// case 8: -// data_type = jit_type_ulong; -// needs_swap = true; -// break; -// default: -// XEASSERTALWAYS(); -// return NULL; -// } +GpVar X64Emitter::ReadMemory( + uint32_t cia, GpVar& addr, uint32_t size, bool acquire) { + X86Compiler& c = compiler_; -// // Rebase off of memory base pointer. -// jit_value_t address = TouchMemoryAddress(cia, addr); -// jit_value_t value = jit_insn_load_relative(fn_, address, 0, data_type); -// if (acquire) { -// // TODO(benvanik): acquire semantics. -// // load_value->setAlignment(size); -// // load_value->setVolatile(true); -// // load_value->setAtomic(Acquire); -// jit_value_set_volatile(value); -// } + // Rebase off of memory base pointer. + GpVar real_address = TouchMemoryAddress(cia, addr); -// // Swap after loading. -// // TODO(benvanik): find a way to avoid this! -// if (needs_swap) { -// value = jit_insn_bswap(fn_, value); -// } + if (acquire) { + // TODO(benvanik): acquire semantics. + // load_value->setAlignment(size); + // load_value->setVolatile(true); + // load_value->setAtomic(Acquire); + XELOGE("Ignoring acquire semantics on read -- TODO"); + } -// return value; -// } + GpVar value(c.newGpVar()); + bool needs_swap = false; + switch (size) { + case 1: + c.mov(value, byte_ptr(real_address)); + break; + case 2: + c.mov(value, word_ptr(real_address)); + c.xchg(value.r8Lo(), value.r8Hi()); + break; + case 4: + c.mov(value, dword_ptr(real_address)); + c.bswap(value.r32()); + break; + case 8: + c.mov(value, qword_ptr(real_address)); + c.bswap(value.r64()); + break; + default: + XEASSERTALWAYS(); + c.mov(value, imm(0xDEADBEEF)); + break; + } -// void X64Emitter::WriteMemory( -// uint32_t cia, GpVar& addr, uint32_t size, GpVar& value, -// bool release) { -// jit_type_t data_type = NULL; -// bool needs_swap = false; -// switch (size) { -// case 1: -// data_type = jit_type_ubyte; -// break; -// case 2: -// data_type = jit_type_ushort; -// needs_swap = true; -// break; -// case 4: -// data_type = jit_type_uint; -// needs_swap = true; -// break; -// case 8: -// data_type = jit_type_ulong; -// needs_swap = true; -// break; -// default: -// XEASSERTALWAYS(); -// return; -// } + return value; +} -// // Truncate, if required. -// if (jit_value_get_type(value) != data_type) { -// value = jit_insn_convert(fn_, value, data_type, 0); -// } +void X64Emitter::WriteMemory( + uint32_t cia, GpVar& addr, uint32_t size, GpVar& value, + bool release) { + X86Compiler& c = compiler_; -// // Swap before storing. -// // TODO(benvanik): find a way to avoid this! -// if (needs_swap) { -// value = jit_insn_bswap(fn_, value); -// } + // Rebase off of memory base pointer. + GpVar real_address = TouchMemoryAddress(cia, addr); -// // TODO(benvanik): release semantics -// // if (release) { -// // store_value->setAlignment(size); -// // store_value->setVolatile(true); -// // store_value->setAtomic(Release); -// // } + GpVar tmp; + switch (size) { + case 1: + c.mov(byte_ptr(real_address), value); + break; + case 2: + tmp = c.newGpVar(); + c.mov(tmp, value); + c.xchg(tmp.r8Lo(), tmp.r8Hi()); + c.mov(word_ptr(real_address), tmp); + break; + case 4: + tmp = c.newGpVar(); + c.mov(tmp, value); + c.bswap(tmp.r32()); + c.mov(dword_ptr(real_address), tmp); + break; + case 8: + tmp = c.newGpVar(); + c.mov(tmp, value); + c.bswap(tmp.r64()); + c.mov(qword_ptr(real_address), tmp); + break; + default: + XEASSERTALWAYS(); + return; + } -// // Rebase off of memory base pointer. -// jit_value_t address = TouchMemoryAddress(cia, addr); -// jit_insn_store_relative(fn_, address, 0, value); -// } + // TODO(benvanik): release semantics + if (release) { + // store_value->setAlignment(size); + // store_value->setVolatile(true); + // store_value->setAtomic(Release); + XELOGE("Ignoring release semantics on write -- TODO"); + } +} GpVar X64Emitter::get_uint64(uint64_t value) { X86Compiler& c = compiler_; @@ -1579,11 +1570,15 @@ GpVar X64Emitter::get_uint64(uint64_t value) { return v; } -GpVar X64Emitter::sign_extend(GpVar& value, int size) { +GpVar X64Emitter::sign_extend(GpVar& value, int from_size, int to_size) { X86Compiler& c = compiler_; + if (!from_size) { + from_size = value.getSize(); + } + // No-op if the same size. - if (value.getSize() == size) { + if (from_size == to_size) { return value; } @@ -1593,62 +1588,116 @@ GpVar X64Emitter::sign_extend(GpVar& value, int size) { // or, could use shift trick (may be slower): // shlq $(target_len-src_len), reg // sarq $(target_len-src_len), reg - GpVar tmp; - switch (size) { + GpVar tmp(c.newGpVar()); + switch (from_size) { case 1: - XEASSERTALWAYS(); - return value; - case 2: - XEASSERTALWAYS(); - return value; - case 4: - XEASSERTALWAYS(); - return value; - default: - case 8: - tmp = c.newGpVar(kX86VarTypeGpq); - c.mov(tmp, value); - switch (value.getSize()) { - case 1: c.cbw(value); // b->w->d->q - case 2: c.cwde(value); // w->d->q - case 4: c.cdqe(value); // d->q - break; + switch (to_size) { + case 1: XEASSERTALWAYS(); return value; + case 2: + c.mov(tmp, value); + c.cbw(tmp); // b->w + return tmp; + case 4: + c.mov(tmp, value); + c.cbw(tmp); // b->w + c.cwde(tmp); // w->d + return tmp; + case 8: + c.mov(tmp, value); + c.cbw(tmp); // b->w + c.cwde(tmp); // w->d + c.cdqe(tmp); // d->q + return tmp; } - return value; + break; + case 2: + switch (to_size) { + case 1: XEASSERTALWAYS(); return value; + case 2: XEASSERTALWAYS(); return value; + case 4: + c.mov(tmp, value); + c.cwde(tmp); // w->d + return tmp; + case 8: + c.mov(tmp, value); + c.cwde(tmp); // w->d + c.cdqe(tmp); // d->q + return tmp; + } + break; + case 4: + switch (to_size) { + case 1: XEASSERTALWAYS(); return value; + case 2: XEASSERTALWAYS(); return value; + case 4: XEASSERTALWAYS(); return value; + case 8: + c.mov(tmp, value); + c.cdqe(tmp); // d->q + return tmp; + } + break; + case 8: break; } + XEASSERTALWAYS(); + return value; } -GpVar X64Emitter::zero_extend(GpVar& value, int size) { +GpVar X64Emitter::zero_extend(GpVar& value, int from_size, int to_size) { X86Compiler& c = compiler_; + if (!from_size) { + from_size = value.getSize(); + } + // No-op if the same size. - if (value.getSize() == size) { + if (from_size == to_size) { return value; } // TODO(benvanik): use movzx if value is in memory. - GpVar tmp; - switch (size) { + GpVar tmp(c.newGpVar()); + switch (from_size) { case 1: - tmp = c.newGpVar(kX86VarTypeGpd); - c.mov(tmp, value.r8()); + switch (to_size) { + case 1: XEASSERTALWAYS(); return value; + case 2: + c.mov(tmp, value.r8()); + return tmp.r16(); + case 4: + c.mov(tmp, value.r8()); + return tmp.r32(); + case 8: + c.mov(tmp, value.r8()); + return tmp.r64(); + } break; case 2: - tmp = c.newGpVar(kX86VarTypeGpd); - c.mov(tmp, value.r16()); + switch (to_size) { + case 1: XEASSERTALWAYS(); return value; + case 2: XEASSERTALWAYS(); return value; + case 4: + c.mov(tmp, value.r16()); + return tmp.r32(); + case 8: + c.mov(tmp, value.r16()); + return tmp.r64(); + } break; case 4: - tmp = c.newGpVar(kX86VarTypeGpd); - c.mov(tmp, value.r32()); - break; - default: - case 8: - tmp = c.newGpVar(kX86VarTypeGpq); - c.mov(tmp, value.r64()); + switch (to_size) { + case 1: XEASSERTALWAYS(); return value; + case 2: XEASSERTALWAYS(); return value; + case 4: XEASSERTALWAYS(); return value; + case 8: + c.mov(tmp, value.r32()); + return tmp.r64(); + } break; + case 8: break; } - return tmp; + XEASSERTALWAYS(); + return value; } GpVar X64Emitter::trunc(GpVar& value, int size) { diff --git a/src/xenia/cpu/x64/x64_emitter.h b/src/xenia/cpu/x64/x64_emitter.h index bd45ed14b..2cf2ebffe 100644 --- a/src/xenia/cpu/x64/x64_emitter.h +++ b/src/xenia/cpu/x64/x64_emitter.h @@ -84,16 +84,16 @@ public: AsmJit::GpVar fpr_value(uint32_t n); void update_fpr_value(uint32_t n, AsmJit::GpVar& value); - AsmJit::GpVar& TouchMemoryAddress(uint32_t cia, AsmJit::GpVar& addr); - AsmJit::GpVar& ReadMemory( + AsmJit::GpVar TouchMemoryAddress(uint32_t cia, AsmJit::GpVar& addr); + AsmJit::GpVar ReadMemory( uint32_t cia, AsmJit::GpVar& addr, uint32_t size, bool acquire = false); void WriteMemory( uint32_t cia, AsmJit::GpVar& addr, uint32_t size, AsmJit::GpVar& value, bool release = false); AsmJit::GpVar get_uint64(uint64_t value); - AsmJit::GpVar sign_extend(AsmJit::GpVar& value, int size); - AsmJit::GpVar zero_extend(AsmJit::GpVar& value, int size); + AsmJit::GpVar sign_extend(AsmJit::GpVar& value, int from_size, int to_size); + AsmJit::GpVar zero_extend(AsmJit::GpVar& value, int from_size, int to_size); AsmJit::GpVar trunc(AsmJit::GpVar& value, int size); private: