From ee508f85b4a78e3b0c4b8f4175e8f49135c92864 Mon Sep 17 00:00:00 2001 From: Andrew Church Date: Sun, 18 Jan 2015 07:01:52 +0900 Subject: [PATCH] Fix handling of VRSAVE, and remove references to nonexistent USPRG registers. --- rpcs3/Emu/Cell/PPUInterpreter.h | 20 ++++---------------- rpcs3/Emu/Cell/PPULLVMRecompiler.cpp | 22 ++++++++++++---------- rpcs3/Emu/Cell/PPULLVMRecompiler.h | 8 ++++---- rpcs3/Emu/Cell/PPUThread.cpp | 2 +- rpcs3/Emu/Cell/PPUThread.h | 3 ++- 5 files changed, 23 insertions(+), 32 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index 6b22273d14..cee189cf89 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -144,14 +144,8 @@ private: case 0x001: return CPU.XER.XER; case 0x008: return CPU.LR; case 0x009: return CPU.CTR; - case 0x100: - case 0x101: - case 0x102: - case 0x103: - case 0x104: - case 0x105: - case 0x106: - case 0x107: return CPU.USPRG[n - 0x100]; + case 0x100: return CPU.VRSAVE; + case 0x103: return CPU.SPRG[3]; case 0x10C: CPU.TB = get_time(); return CPU.TB; case 0x10D: CPU.TB = get_time(); return CPU.TBH; @@ -178,14 +172,8 @@ private: case 0x001: CPU.XER.XER = value; return; case 0x008: CPU.LR = value; return; case 0x009: CPU.CTR = value; return; - case 0x100: - case 0x101: - case 0x102: - case 0x103: - case 0x104: - case 0x105: - case 0x106: - case 0x107: CPU.USPRG[n - 0x100] = value; return; + case 0x100: CPU.VRSAVE = (u32)value; return; + case 0x103: throw fmt::Format("WriteSPR(0x103, 0x%llx): Write to read-only SPR", value); case 0x10C: throw fmt::Format("WriteSPR(0x10C, 0x%llx): Write to time-based SPR", value); case 0x10D: throw fmt::Format("WriteSPR(0x10D, 0x%llx): Write to time-based SPR", value); diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp index 8442c33d6d..c14d0a4131 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp @@ -3311,7 +3311,7 @@ void Compiler::MFSPR(u32 rd, u32 spr) { rd_i64 = GetCtr(); break; case 0x100: - rd_i64 = GetUsprg0(); + rd_i64 = GetVrsave(); break; case 0x10C: rd_i64 = Call("get_time", get_time); @@ -3503,7 +3503,7 @@ void Compiler::MTSPR(u32 spr, u32 rs) { SetCtr(rs_i64); break; case 0x100: - SetUsprg0(rs_i64); + SetVrsave(rs_i64); break; default: assert(0); @@ -5278,17 +5278,19 @@ void Compiler::SetXerSo(Value * so) { SetXer(xer_i64); } -Value * Compiler::GetUsprg0() { - auto usrpg0_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, USPRG)); - auto usprg0_i64_ptr = m_ir_builder->CreateBitCast(usrpg0_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - return m_ir_builder->CreateAlignedLoad(usprg0_i64_ptr, 8); +Value * Compiler::GetVrsave() { + auto vrsave_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VRSAVE)); + auto vrsave_i32_ptr = m_ir_builder->CreateBitCast(vrsave_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + auto val_i32 = m_ir_builder->CreateAlignedLoad(vrsave_i32_ptr, 4); + return m_ir_builder->CreateZExtOrTrunc(val_i32, m_ir_builder->getInt64Ty()); } -void Compiler::SetUsprg0(Value * val_x64) { +void Compiler::SetVrsave(Value * val_x64) { auto val_i64 = m_ir_builder->CreateBitCast(val_x64, m_ir_builder->getInt64Ty()); - auto usprg0_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, USPRG)); - auto usprg0_i64_ptr = m_ir_builder->CreateBitCast(usprg0_i8_ptr, m_ir_builder->getInt64Ty()->getPointerTo()); - m_ir_builder->CreateAlignedStore(val_i64, usprg0_i64_ptr, 8); + auto val_i32 = m_ir_builder->CreateZExtOrTrunc(val_i64, m_ir_builder->getInt32Ty()); + auto vrsave_i8_ptr = m_ir_builder->CreateConstGEP1_32(m_state.args[CompileTaskState::Args::State], (unsigned int)offsetof(PPUThread, VRSAVE)); + auto vrsave_i32_ptr = m_ir_builder->CreateBitCast(vrsave_i8_ptr, m_ir_builder->getInt32Ty()->getPointerTo()); + m_ir_builder->CreateAlignedStore(val_i32, vrsave_i32_ptr, 8); } Value * Compiler::GetFpscr() { diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.h b/rpcs3/Emu/Cell/PPULLVMRecompiler.h index c4bdeb6b6b..715e9f08ab 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.h +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.h @@ -860,11 +860,11 @@ namespace ppu_recompiler_llvm { /// Set the SO bit of XER void SetXerSo(llvm::Value * so); - /// Get USPRG0 - llvm::Value * GetUsprg0(); + /// Get VRSAVE + llvm::Value * GetVrsave(); - /// Set USPRG0 - void SetUsprg0(llvm::Value * val_x64); + /// Set VRSAVE + void SetVrsave(llvm::Value * val_x64); /// Load FPSCR llvm::Value * GetFpscr(); diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index f84095e683..9e5588276a 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -43,7 +43,6 @@ void PPUThread::DoReset() memset(FPR, 0, sizeof(FPR)); memset(GPR, 0, sizeof(GPR)); memset(SPRG, 0, sizeof(SPRG)); - memset(USPRG, 0, sizeof(USPRG)); CR.CR = 0; LR = 0; @@ -52,6 +51,7 @@ void PPUThread::DoReset() XER.XER = 0; FPSCR.FPSCR = 0; VSCR.VSCR = 0; + VRSAVE = 0; cycle = 0; } diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 659b81443e..f107f1db03 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -531,7 +531,8 @@ public: u64 LR; //SPR 0x008 : Link Register u64 CTR; //SPR 0x009 : Count Register - u64 USPRG[8]; //SPR 0x100 - 0x107: User-SPR General-Purpose Registers + u32 VRSAVE; //SPR 0x100: VR Save/Restore Register (32 bits) + u64 SPRG[8]; //SPR 0x110 - 0x117 : SPR General-Purpose Registers //TBR : Time-Base Registers