From 2ddee26d834347441e9d5405ac045d392eec525d Mon Sep 17 00:00:00 2001 From: Peter Tissen Date: Tue, 18 Mar 2014 23:58:42 +0100 Subject: [PATCH 1/2] add experimental subfme and subfze support and fix cache folder creation --- rpcs3/Emu/Cell/PPUDisAsm.h | 8 ++++++++ rpcs3/Emu/Cell/PPUInstrTable.h | 2 ++ rpcs3/Emu/Cell/PPUInterpreter.h | 18 +++++++++++++++++- rpcs3/Emu/Cell/PPUOpcodes.h | 10 +++++++--- rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp | 2 +- 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUDisAsm.h b/rpcs3/Emu/Cell/PPUDisAsm.h index a5cbf1775b..490c0826b2 100644 --- a/rpcs3/Emu/Cell/PPUDisAsm.h +++ b/rpcs3/Emu/Cell/PPUDisAsm.h @@ -1411,6 +1411,10 @@ private: { DisAsm_V1_R2("stvewx", vs, ra, rb); } + void SUBFZE(u32 rd, u32 ra, u32 oe, bool rc) + { + DisAsm_R2_OE_RC("subfze", rd, ra, oe, rc); + } void ADDZE(u32 rd, u32 ra, u32 oe, bool rc) { DisAsm_R2_OE_RC("addze", rd, ra, oe, rc); @@ -1427,6 +1431,10 @@ private: { DisAsm_V1_R2("stvx", vd, ra, rb); } + void SUBFME(u32 rd, u32 ra, u32 oe, bool rc) + { + DisAsm_R2_OE_RC("subfme", rd, ra, oe, rc); + } void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { DisAsm_R3_OE_RC("mulld", rd, ra, rb, oe, rc); diff --git a/rpcs3/Emu/Cell/PPUInstrTable.h b/rpcs3/Emu/Cell/PPUInstrTable.h index e82c02abdb..9e8bd1baf3 100644 --- a/rpcs3/Emu/Cell/PPUInstrTable.h +++ b/rpcs3/Emu/Cell/PPUInstrTable.h @@ -488,10 +488,12 @@ namespace PPU_instr /*0x0b5*/bind_instr(g1f_list, STDUX, RS, RA, RB); /*0x0b7*/bind_instr(g1f_list, STWUX, RS, RA, RB); /*0x0c7*/bind_instr(g1f_list, STVEWX, VS, RA, RB); + /*0x0c8*/bind_instr(g1f_list, SUBFZE, RD, RA, OE, RC); /*0x0ca*/bind_instr(g1f_list, ADDZE, RD, RA, OE, RC); /*0x0d6*/bind_instr(g1f_list, STDCX_, RS, RA, RB); /*0x0d7*/bind_instr(g1f_list, STBX, RS, RA, RB); /*0x0e7*/bind_instr(g1f_list, STVX, VS, RA, RB); + /*0x0e8*/bind_instr(g1f_list, SUBFME, RD, RA, OE, RC); /*0x0e9*/bind_instr(g1f_list, MULLD, RD, RA, RB, OE, RC); /*0x0ea*/bind_instr(g1f_list, ADDME, RD, RA, OE, RC); /*0x0eb*/bind_instr(g1f_list, MULLW, RD, RA, RB, OE, RC); diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index ea916d43b1..e57375f822 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -2604,7 +2604,7 @@ private: { const s64 RA = CPU.GPR[ra]; const s64 RB = CPU.GPR[rb]; - CPU.GPR[ra] = ~RA + RB + CPU.XER.CA; + CPU.GPR[rd] = ~RA + RB + CPU.XER.CA; CPU.XER.CA = ((u64)~RA + CPU.XER.CA > ~(u64)RB) | ((RA == 0) & CPU.XER.CA); if(rc) CPU.UpdateCR0(CPU.GPR[rd]); if(oe) UNK("subfeo"); @@ -2724,6 +2724,14 @@ private: if(oe) ConLog.Warning("addzeo"); if(rc) CPU.UpdateCR0(CPU.GPR[rd]); } + void SUBFZE(u32 rd, u32 ra, u32 oe, bool rc) + { + const u64 nRA = ~CPU.GPR[ra]; + CPU.GPR[rd] = nRA + CPU.XER.CA; + CPU.XER.CA = CPU.IsCarry(nRA, CPU.XER.CA); + if (oe) ConLog.Warning("subfzeo"); + if (rc) CPU.UpdateCR0(CPU.GPR[rd]); + } void STDCX_(u32 rs, u32 ra, u32 rb) { const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]; @@ -2749,6 +2757,14 @@ private: { Memory.Write128((ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb]) & ~0xfULL, CPU.VPR[vs]._u128); } + void SUBFME(u32 rd, u32 ra, u32 oe, bool rc) + { + const u64 nRA = ~CPU.GPR[ra]; + CPU.GPR[rd] = nRA + CPU.XER.CA + 0xFFFFFFFF; + CPU.XER.CA = CPU.IsCarry(nRA, CPU.XER.CA) || CPU.IsCarry(nRA, CPU.XER.CA + 0xFFFFFFFF); + if (oe) ConLog.Warning("subfmeo"); + if (rc) CPU.UpdateCR0(CPU.GPR[rd]); + } void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { CPU.GPR[rd] = (s64)((s64)CPU.GPR[ra] * (s64)CPU.GPR[rb]); diff --git a/rpcs3/Emu/Cell/PPUOpcodes.h b/rpcs3/Emu/Cell/PPUOpcodes.h index 71a8d3b2f1..7e00a3e2cd 100644 --- a/rpcs3/Emu/Cell/PPUOpcodes.h +++ b/rpcs3/Emu/Cell/PPUOpcodes.h @@ -300,11 +300,13 @@ namespace PPU_opcodes STDUX = 0x0b5, STWUX = 0x0b7, STVEWX = 0x0c7, //Store Vector Element Word Indexed - ADDZE = 0x0ca, + SUBFZE = 0x0c8, + ADDZE = 0x0ca, STDCX_ = 0x0d6, STBX = 0x0d7, STVX = 0x0e7, - MULLD = 0x0e9, + SUBFME = 0x0e8, + MULLD = 0x0e9, ADDME = 0x0ea, MULLW = 0x0eb, DCBTST = 0x0f6, @@ -345,7 +347,7 @@ namespace PPU_opcodes SRW = 0x218, SRD = 0x21b, LVRX = 0x227, //Load Vector Right Indexed - LFSUX = 0x237, + LFSUX = 0x237, SYNC = 0x256, LFDX = 0x257, LFDUX = 0x277, @@ -690,11 +692,13 @@ public: virtual void STDUX(u32 rs, u32 ra, u32 rb) = 0; virtual void STWUX(u32 rs, u32 ra, u32 rb) = 0; virtual void STVEWX(u32 vs, u32 ra, u32 rb) = 0; + virtual void SUBFZE(u32 rd, u32 ra, u32 oe, bool rc) = 0; virtual void ADDZE(u32 rd, u32 ra, u32 oe, bool rc) = 0; virtual void STDCX_(u32 rs, u32 ra, u32 rb) = 0; virtual void STBX(u32 rs, u32 ra, u32 rb) = 0; virtual void STVX(u32 vs, u32 ra, u32 rb) = 0; virtual void MULLD(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0; + virtual void SUBFME(u32 rd, u32 ra, u32 oe, bool rc) = 0; virtual void ADDME(u32 rd, u32 ra, u32 oe, bool rc) = 0; virtual void MULLW(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) = 0; virtual void DCBTST(u32 th, u32 ra, u32 rb) = 0; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index 033dec04c5..eed6b8346a 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -973,7 +973,7 @@ int cellSysCacheMount(mem_ptr_t param) char id[CELL_SYSCACHE_ID_SIZE]; strncpy(id, param->cacheId, CELL_SYSCACHE_ID_SIZE); strncpy(param->getCachePath, ("/dev_hdd1/cache/" + std::string(id) + "/").c_str(), CELL_SYSCACHE_PATH_MAX); - Emu.GetVFS().CreateFile(wxString(param->getCachePath)); + Emu.GetVFS().CreateDir(wxString(param->getCachePath)); return CELL_SYSCACHE_RET_OK_RELAYED; } From acf955635f168f2c8d7a32cbead545edbe227296 Mon Sep 17 00:00:00 2001 From: Peter Tissen Date: Wed, 19 Mar 2014 18:13:52 +0100 Subject: [PATCH 2/2] correct the subtraction instructions and try something more sensible for overflow detection --- rpcs3/Emu/Cell/PPUInterpreter.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index e05d396100..c507b1aaa5 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -2612,10 +2612,10 @@ private: } void SUBFE(u32 rd, u32 ra, u32 rb, u32 oe, bool rc) { - const s64 RA = CPU.GPR[ra]; - const s64 RB = CPU.GPR[rb]; + const u64 RA = CPU.GPR[ra]; + const u64 RB = CPU.GPR[rb]; CPU.GPR[rd] = ~RA + RB + CPU.XER.CA; - CPU.XER.CA = ((u64)~RA + CPU.XER.CA > ~(u64)RB) | ((RA == 0) & CPU.XER.CA); + CPU.XER.CA = (~RA + CPU.XER.CA > ~RB) | ((RA == 0) & CPU.XER.CA); if(rc) CPU.UpdateCR0(CPU.GPR[rd]); if(oe) UNK("subfeo"); } @@ -2736,9 +2736,9 @@ private: } void SUBFZE(u32 rd, u32 ra, u32 oe, bool rc) { - const u64 nRA = ~CPU.GPR[ra]; - CPU.GPR[rd] = nRA + CPU.XER.CA; - CPU.XER.CA = CPU.IsCarry(nRA, CPU.XER.CA); + const u64 RA = CPU.GPR[ra]; + CPU.GPR[rd] = ~RA + CPU.XER.CA; + CPU.XER.CA = (0x8000000000000000 & RA) && (0x8000000000000000 & CPU.GPR[rd]);//RA <= 0ull; if (oe) ConLog.Warning("subfzeo"); if (rc) CPU.UpdateCR0(CPU.GPR[rd]); } @@ -2769,9 +2769,9 @@ private: } void SUBFME(u32 rd, u32 ra, u32 oe, bool rc) { - const u64 nRA = ~CPU.GPR[ra]; - CPU.GPR[rd] = nRA + CPU.XER.CA + 0xFFFFFFFF; - CPU.XER.CA = CPU.IsCarry(nRA, CPU.XER.CA) || CPU.IsCarry(nRA, CPU.XER.CA + 0xFFFFFFFF); + const u64 RA = CPU.GPR[ra]; + CPU.GPR[rd] = ~RA + CPU.XER.CA + 0xFFFFFFFFFFFFFFFF; + CPU.XER.CA = !(0x8000000000000000 & RA) && !(0x8000000000000000 & CPU.GPR[rd]); if (oe) ConLog.Warning("subfmeo"); if (rc) CPU.UpdateCR0(CPU.GPR[rd]); }