From 5db254f3a56bb375eb37b279f1d2938d9db8541d Mon Sep 17 00:00:00 2001 From: S Gopal Rajagopal Date: Thu, 11 Dec 2014 19:13:17 +0530 Subject: [PATCH] PPU: Corrected SC instruction format to comply with the PowerISA --- rpcs3/Emu/Cell/PPUDisAsm.h | 11 +++++------ rpcs3/Emu/Cell/PPUInstrTable.h | 6 +++--- rpcs3/Emu/Cell/PPUInterpreter.h | 15 +++++++-------- rpcs3/Emu/Cell/PPULLVMRecompiler.cpp | 12 ++++++------ rpcs3/Emu/Cell/PPUOpcodes.h | 2 +- rpcs3/Emu/SysCalls/Modules.cpp | 2 +- rpcs3/Emu/SysCalls/Static.cpp | 2 +- rpcs3/Loader/ELF64.cpp | 8 ++++---- 8 files changed, 28 insertions(+), 30 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUDisAsm.h b/rpcs3/Emu/Cell/PPUDisAsm.h index 8a04164f2e..531b21bc37 100644 --- a/rpcs3/Emu/Cell/PPUDisAsm.h +++ b/rpcs3/Emu/Cell/PPUDisAsm.h @@ -1030,14 +1030,13 @@ private: Write(fmt::Format("bc [%x:%x:%x:%x:%x], cr%d[%x], 0x%x, %d, %d", bo0, bo1, bo2, bo3, bo4, bi/4, bi%4, bd, aa, lk)); } - void SC(u32 sc_code) + void SC(u32 lev) { - switch(sc_code) + switch (lev) { - case 0x1: Write("HyperCall"); break; - case 0x2: Write("sc"); break; - case 0x22: Write("HyperCall LV1"); break; - default: Write(fmt::Format("Unknown sc: 0x%x", sc_code)); + case 0x0: Write("sc"); break; + case 0x1: Write("HyperCall LV1"); break; + default: Write(fmt::Format("Unknown sc: 0x%x", lev)); } } void B(s32 ll, u32 aa, u32 lk) diff --git a/rpcs3/Emu/Cell/PPUInstrTable.h b/rpcs3/Emu/Cell/PPUInstrTable.h index 676f32fa79..c9f03c789d 100644 --- a/rpcs3/Emu/Cell/PPUInstrTable.h +++ b/rpcs3/Emu/Cell/PPUInstrTable.h @@ -162,8 +162,8 @@ namespace PPU_instr //This field mask is used to identify the CR fields that are to be updated by the mtcrf instruction. static CodeField<12, 19> CRM; - // - static CodeField<6, 31> SYS; + // This field is used to identify the system call level + static CodeField<20, 26> LEV; //Immediate field specifying a 16-bit signed two's complement integer that is sign-extended to 64 bits static CodeFieldSigned<16, 31> D; @@ -238,7 +238,7 @@ namespace PPU_instr bind_instr(main_list, ADDI, RD, RA, simm16); bind_instr(main_list, ADDIS, RD, RA, simm16); bind_instr(main_list, BC, BO, BI, BD, AA, LK); - bind_instr(main_list, SC, SYS); + bind_instr(main_list, SC, LEV); bind_instr(main_list, B, LI, AA, LK); bind_instr(main_list, RLWIMI, RA, RS, SH, MB, ME, RC); bind_instr(main_list, RLWINM, RA, RS, SH, MB, ME, RC); diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index 1fdfa88479..aec2a2882e 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -2164,13 +2164,13 @@ private: if(lk) CPU.LR = nextLR; } } - void SC(u32 sc_code) + void SC(u32 lev) { - switch(sc_code) + switch (lev) { - case 0x1: UNK(fmt::Format("HyperCall %d", CPU.GPR[0])); break; - case 0x2: SysCall(); break; - case 0x3: + case 0x0: SysCall(); break; + case 0x1: UNK("HyperCall LV1"); break; + case 0x2: Emu.GetSFuncManager().StaticExecute(CPU, (u32)CPU.GPR[11]); if (Ini.HLELogging.GetValue()) { @@ -2178,9 +2178,8 @@ private: Emu.GetSFuncManager()[CPU.GPR[11]]->name, CPU.GPR[3], CPU.PC); } break; - case 0x4: CPU.FastStop(); break; - case 0x22: UNK("HyperCall LV1"); break; - default: UNK(fmt::Format("Unknown sc: 0x%x", sc_code)); + case 0x3: CPU.FastStop(); break; + default: UNK(fmt::Format("Unknown sc: 0x%x", lev)); break; } } void B(s32 ll, u32 aa, u32 lk) diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp index 34b2fb9c05..1451a80c27 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp @@ -1995,20 +1995,20 @@ void Compiler::BC(u32 bo, u32 bi, s32 bd, u32 aa, u32 lk) { CreateBranch(CheckBranchCondition(bo, bi), target_i32, lk ? true : false); } -void Compiler::SC(u32 sc_code) { - switch (sc_code) { - case 2: +void Compiler::SC(u32 lev) { + switch (lev) { + case 0: Call("SysCalls.DoSyscall", SysCalls::DoSyscall, m_state.args[CompileTaskState::Args::State], GetGpr(11)); break; - case 3: + case 2: Call("StaticFuncManager.StaticExecute", &StaticFuncManager::StaticExecute, m_ir_builder->getInt64((u64)&Emu.GetSFuncManager()), m_state.args[CompileTaskState::Args::State], GetGpr(11, 32)); break; - case 4: + case 3: Call("PPUThread.FastStop", &PPUThread::FastStop, m_state.args[CompileTaskState::Args::State]); break; default: - CompilationError(fmt::Format("SC %u", sc_code)); + CompilationError(fmt::Format("SC %u", lev)); break; } } diff --git a/rpcs3/Emu/Cell/PPUOpcodes.h b/rpcs3/Emu/Cell/PPUOpcodes.h index 9fbe5e8d79..6c89edf81e 100644 --- a/rpcs3/Emu/Cell/PPUOpcodes.h +++ b/rpcs3/Emu/Cell/PPUOpcodes.h @@ -628,7 +628,7 @@ public: virtual void ADDI(u32 rd, u32 ra, s32 simm16) = 0; virtual void ADDIS(u32 rd, u32 ra, s32 simm16) = 0; virtual void BC(u32 bo, u32 bi, s32 bd, u32 aa, u32 lk) = 0; - virtual void SC(u32 sc_code) = 0; + virtual void SC(u32 lev) = 0; virtual void B(s32 ll, u32 aa, u32 lk) = 0; virtual void MCRF(u32 crfd, u32 crfs) = 0; virtual void BCLR(u32 bo, u32 bi, u32 bh, u32 lk) = 0; diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index 26b6931544..3de1be5414 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -188,7 +188,7 @@ void fix_import(Module* module, u32 func, u32 addr) *ptr++ = ORI(11, 11, func & 0xffff); *ptr++ = NOP(); ++ptr; - *ptr++ = SC(2); + *ptr++ = SC(0); *ptr++ = BLR(); *ptr++ = NOP(); *ptr++ = NOP(); diff --git a/rpcs3/Emu/SysCalls/Static.cpp b/rpcs3/Emu/SysCalls/Static.cpp index 9ea47550cb..677b32c970 100644 --- a/rpcs3/Emu/SysCalls/Static.cpp +++ b/rpcs3/Emu/SysCalls/Static.cpp @@ -85,7 +85,7 @@ void StaticFuncManager::StaticAnalyse(void* ptr, u32 size, u32 base) LOG_NOTICE(LOADER, "Function '%s' hooked (addr=0x%x)", m_static_funcs_list[j]->name, i * 4 + base); m_static_funcs_list[j]->found++; data[i+0] = re32(0x39600000 | j); // li r11, j - data[i+1] = se32(0x44000003); // sc 3 + data[i+1] = se32(0x44000042); // sc 2 data[i+2] = se32(0x4e800020); // blr i += 2; // skip modified code } diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index 09607fc407..874f455cde 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -343,17 +343,17 @@ namespace loader Emu.SetRSXCallback(rsx_callback_data.addr()); rsx_callback_data[0] = ADDI(r11, 0, 0x3ff); - rsx_callback_data[1] = SC(2); + rsx_callback_data[1] = SC(0); rsx_callback_data[2] = BLR(); auto ppu_thr_exit_data = vm::ptr::make(Memory.MainMem.AllocAlign(3 * 4)); ppu_thr_exit_data[0] = ADDI(r11, 0, 41); - ppu_thr_exit_data[1] = SC(2); + ppu_thr_exit_data[1] = SC(0); ppu_thr_exit_data[2] = BLR(); Emu.SetCPUThreadExit(ppu_thr_exit_data.addr()); auto ppu_thr_stop_data = vm::ptr::make(Memory.MainMem.AllocAlign(2 * 4)); - ppu_thr_stop_data[0] = SC(4); + ppu_thr_stop_data[0] = SC(3); ppu_thr_stop_data[1] = BLR(); Emu.SetCPUThreadStop(ppu_thr_stop_data.addr()); @@ -493,7 +493,7 @@ namespace loader static const stub_data = { be_t::make(MR(11, 2)), - be_t::make(SC(2)), + be_t::make(SC(0)), be_t::make(BLR()) };