diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index e5b38d103b..fe14360ac4 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -33,7 +33,7 @@ u32 add_ppu_func_sub(StaticFunc func) u32 add_ppu_func_sub(const char group[8], const u64 ops[], const char* name, Module* module, ppu_func_caller func) { StaticFunc sf; - sf.index = add_ppu_func(ModuleFunc(get_function_id(name), MFF_DONT_SAVE_RTOC, module, func)); + sf.index = add_ppu_func(ModuleFunc(get_function_id(name), 0, module, func)); sf.name = name; sf.group = *(u64*)group; sf.found = 0; @@ -71,6 +71,8 @@ ModuleFunc* get_ppu_func_by_nid(u32 nid, u32* out_index) ModuleFunc* get_ppu_func_by_index(u32 index) { + index &= ~EIF_FLAGS; + if (index >= g_ppu_func_list.size()) { return nullptr; @@ -83,18 +85,18 @@ void execute_ppu_func_by_index(PPUThread& CPU, u32 index) { if (auto func = get_ppu_func_by_index(index)) { - if ((!func->lle_func || CPU.PC != vm::read32(func->lle_func.addr())) && !(func->flags & MFF_DONT_SAVE_RTOC)) + auto old_last_syscall = CPU.m_last_syscall; + CPU.m_last_syscall = func->id; + + if (!(index & EIF_DONT_SAVE_RTOC)) { // save RTOC if necessary vm::write64(vm::cast(CPU.GPR[1] + 0x28), CPU.GPR[2]); } - auto old_last_syscall = CPU.m_last_syscall; - CPU.m_last_syscall = func->id; - if (func->lle_func && !(func->flags & MFF_FORCED_HLE)) { - // call LLE function if possible + // call LLE function if available func->lle_func(CPU); } else if (func->func) @@ -103,7 +105,7 @@ void execute_ppu_func_by_index(PPUThread& CPU, u32 index) } else { - LOG_ERROR(HLE, "Unimplemented function %s", SysCalls::GetHLEFuncName(func->id)); + LOG_ERROR(HLE, "Unimplemented function: %s", SysCalls::GetHLEFuncName(func->id)); CPU.GPR[3] = 0; } @@ -217,7 +219,7 @@ void hook_ppu_funcs(u32* base, u32 size) { LOG_NOTICE(LOADER, "Function '%s' hooked (addr=0x%x)", g_ppu_func_subs[j].name, vm::get_addr(base + i * 4)); g_ppu_func_subs[j].found++; - base[i + 0] = re32(0x04000000 | g_ppu_func_subs[j].index); // hack + base[i + 0] = re32(0x04000000 | g_ppu_func_subs[j].index | EIF_DONT_SAVE_RTOC); // hack base[i + 1] = se32(0x4e800020); // blr i += 1; // skip modified code } diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h index f0bbca1e8a..3167cfa09f 100644 --- a/rpcs3/Emu/SysCalls/Modules.h +++ b/rpcs3/Emu/SysCalls/Modules.h @@ -6,10 +6,18 @@ class Module; +// flags set in ModuleFunc enum : u32 { - MFF_DONT_SAVE_RTOC = (1 << 0), // don't save RTOC before calling - MFF_FORCED_HLE = (1 << 1), // always call HLE function + MFF_FORCED_HLE = (1 << 0), // always call HLE function +}; + +// flags passed with index +enum : u32 +{ + EIF_DONT_SAVE_RTOC = (1 << 25), // don't save RTOC before calling + + EIF_FLAGS = 0x2000000, // all flags }; struct ModuleFunc diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index 593590a666..7a5fd2ff88 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -423,7 +423,7 @@ namespace loader } else { - vm::write32(i_addr + 0, HACK(index)); + vm::write32(i_addr + 0, HACK(index | EIF_DONT_SAVE_RTOC)); vm::write32(i_addr + 4, BLR()); } }