From f0e73a652fb6259ce9ac4e458543ed199c57a9df Mon Sep 17 00:00:00 2001 From: Peter Tissen Date: Thu, 20 Mar 2014 02:48:02 +0100 Subject: [PATCH] stswi and lswi instructions --- rpcs3/Emu/Cell/PPUDisAsm.h | 8 +++++ rpcs3/Emu/Cell/PPUInstrTable.h | 2 ++ rpcs3/Emu/Cell/PPUInterpreter.h | 56 +++++++++++++++++++++++++++++++++ rpcs3/Emu/Cell/PPUOpcodes.h | 4 +++ 4 files changed, 70 insertions(+) diff --git a/rpcs3/Emu/Cell/PPUDisAsm.h b/rpcs3/Emu/Cell/PPUDisAsm.h index c9239e6b6c..3ca2a3a7f4 100644 --- a/rpcs3/Emu/Cell/PPUDisAsm.h +++ b/rpcs3/Emu/Cell/PPUDisAsm.h @@ -1645,6 +1645,10 @@ private: { DisAsm_V1_R2("lvrx", vd, ra, rb); } + void LSWI(u32 rd, u32 ra, u32 nb) + { + DisAsm_R2_INT1("lswi", rd, ra, nb); + } void LFSUX(u32 frd, u32 ra, u32 rb) { DisAsm_F1_R2("lfsux", frd, ra, rb); @@ -1677,6 +1681,10 @@ private: { DisAsm_V1_R2("stvrx", sd, ra, rb); } + void STSWI(u32 rd, u32 ra, u32 nb) + { + DisAsm_R2_INT1("stswi", rd, ra, nb); + } void STFDX(u32 frs, u32 ra, u32 rb) { DisAsm_F1_R2("stfdx", frs, ra, rb); diff --git a/rpcs3/Emu/Cell/PPUInstrTable.h b/rpcs3/Emu/Cell/PPUInstrTable.h index aaa03dfc43..52767e92bc 100644 --- a/rpcs3/Emu/Cell/PPUInstrTable.h +++ b/rpcs3/Emu/Cell/PPUInstrTable.h @@ -537,6 +537,7 @@ namespace PPU_instr /*0x21b*/bind_instr(g1f_list, SRD, RA, RS, RB, RC); /*0x227*/bind_instr(g1f_list, LVRX, VD, RA, RB); /*0x237*/bind_instr(g1f_list, LFSUX, FRD, RA, RB); + /*0x255*/bind_instr(g1f_list, LSWI, RD, RA, NB); /*0x256*/bind_instr(g1f_list, SYNC, L_9_10); /*0x257*/bind_instr(g1f_list, LFDX, FRD, RA, RB); /*0x277*/bind_instr(g1f_list, LFDUX, FRD, RA, RB); @@ -544,6 +545,7 @@ namespace PPU_instr /*0x296*/bind_instr(g1f_list, STWBRX, RS, RA, RB); /*0x297*/bind_instr(g1f_list, STFSX, FRS, RA, RB); /*0x2a7*/bind_instr(g1f_list, STVRX, VS, RA, RB); + /*0x2d5*/bind_instr(g1f_list, STSWI, RD, RA, NB); /*0x2d7*/bind_instr(g1f_list, STFDX, FRS, RA, RB); /*0x307*/bind_instr(g1f_list, LVLXL, VD, RA, RB); /*0x316*/bind_instr(g1f_list, LHBRX, RD, RA, RB); diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index de17f60470..6904a68703 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -3046,6 +3046,34 @@ private: Memory.ReadRight(CPU.VPR[vd]._u8, addr & ~0xf, eb); } + void LSWI(u32 rd, u32 ra, u32 nb) + { + u64 EA = ra ? CPU.GPR[ra] : 0; + u64 N = nb ? nb : 32; + u8 reg = CPU.GPR[rd]; + + while (N > 0) + { + if (N > 3) + { + CPU.GPR[reg] = Memory.Read32(EA); + EA += 4; + N -= 4; + } + else + { + u32 buf = 0; + while (N > 0) + { + N = N - 1; + buf |= Memory.Read8(EA) <<(N*8) ; + EA = EA + 1; + } + CPU.GPR[reg] = buf; + } + reg = (reg + 1) % 32; + } + } void LFSUX(u32 frd, u32 ra, u32 rb) { const u64 addr = CPU.GPR[ra] + CPU.GPR[rb]; @@ -3089,6 +3117,34 @@ private: Memory.WriteRight(addr - eb, eb, CPU.VPR[vs]._u8); } + void STSWI(u32 rd, u32 ra, u32 nb) + { + u64 EA = ra ? CPU.GPR[ra] : 0; + u64 N = nb ? nb : 32; + u8 reg = CPU.GPR[rd]; + + while (N > 0) + { + if (N > 3) + { + Memory.Write32(EA, CPU.GPR[reg]); + EA += 4; + N -= 4; + } + else + { + u32 buf = CPU.GPR[reg]; + while (N > 0) + { + N = N - 1; + Memory.Write8(EA, (0xFF000000 & buf) >> 24); + buf <<= 8; + EA = EA + 1; + } + } + reg = (reg + 1) % 32; + } + } void STFDX(u32 frs, u32 ra, u32 rb) { Memory.Write64((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]), (u64&)CPU.FPR[frs]); diff --git a/rpcs3/Emu/Cell/PPUOpcodes.h b/rpcs3/Emu/Cell/PPUOpcodes.h index fa679e6e48..b0ef854bfa 100644 --- a/rpcs3/Emu/Cell/PPUOpcodes.h +++ b/rpcs3/Emu/Cell/PPUOpcodes.h @@ -350,6 +350,7 @@ namespace PPU_opcodes SRD = 0x21b, LVRX = 0x227, //Load Vector Right Indexed LFSUX = 0x237, + LSWI = 0x255, SYNC = 0x256, LFDX = 0x257, LFDUX = 0x277, @@ -357,6 +358,7 @@ namespace PPU_opcodes STWBRX = 0x296, STFSX = 0x297, STVRX = 0x2a7, //Store Vector Right Indexed + STSWI = 0x2d5, STFDX = 0x2d7, //Store Floating-Point Double Indexed LVLXL = 0x307, //Load Vector Left Indexed Last LHBRX = 0x316, @@ -742,6 +744,7 @@ public: virtual void SRW(u32 ra, u32 rs, u32 rb, bool rc) = 0; virtual void SRD(u32 ra, u32 rs, u32 rb, bool rc) = 0; virtual void LVRX(u32 vd, u32 ra, u32 rb) = 0; + virtual void LSWI(u32 rd, u32 ra, u32 nb) = 0; virtual void LFSUX(u32 frd, u32 ra, u32 rb) = 0; virtual void SYNC(u32 l) = 0; virtual void LFDX(u32 frd, u32 ra, u32 rb) = 0; @@ -750,6 +753,7 @@ public: virtual void STWBRX(u32 rs, u32 ra, u32 rb) = 0; virtual void STFSX(u32 frs, u32 ra, u32 rb) = 0; virtual void STVRX(u32 vs, u32 ra, u32 rb) = 0; + virtual void STSWI(u32 rd, u32 ra, u32 nb) = 0; virtual void STFDX(u32 frs, u32 ra, u32 rb) = 0; virtual void LVLXL(u32 vd, u32 ra, u32 rb) = 0; virtual void LHBRX(u32 rd, u32 ra, u32 rb) = 0;