Skip to content

Commit ff4485d

Browse files
committed
PPU LLVM: Patch unregistered BLRs
Fixes "Unregistered PPU Function" in "Jak and Daxter Collection"
1 parent eacfa36 commit ff4485d

File tree

1 file changed

+26
-0
lines changed

1 file changed

+26
-0
lines changed

rpcs3/Emu/Cell/PPUThread.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4662,6 +4662,9 @@ bool ppu_initialize(const ppu_module& info, bool check_only)
46624662
#ifdef __APPLE__
46634663
pthread_jit_write_protect_np(false);
46644664
#endif
4665+
// Try to patch all single and unregistered BLRs with the same function (TODO: Maybe generalize it into PIC code detection and patching)
4666+
ppu_intrp_func_t BLR_func = nullptr;
4667+
46654668
if (jit && !jit_mod.init)
46664669
{
46674670
jit->fin();
@@ -4675,6 +4678,11 @@ bool ppu_initialize(const ppu_module& info, bool check_only)
46754678
const auto addr = ensure(reinterpret_cast<ppu_intrp_func_t>(jit->get(name)));
46764679
jit_mod.funcs.emplace_back(addr);
46774680

4681+
if (func.size == 4 & !BLR_func && *info.get_ptr<u32>(func.addr) == ppu_instructions::BLR())
4682+
{
4683+
BLR_func = addr;
4684+
}
4685+
46784686
ppu_register_function_at(func.addr, 4, addr);
46794687

46804688
if (g_cfg.core.ppu_debug)
@@ -4694,6 +4702,11 @@ bool ppu_initialize(const ppu_module& info, bool check_only)
46944702

46954703
const u64 addr = reinterpret_cast<uptr>(ensure(jit_mod.funcs[index++]));
46964704

4705+
if (func.size == 4 & !BLR_func && *info.get_ptr<u32>(func.addr) == ppu_instructions::BLR())
4706+
{
4707+
BLR_func = reinterpret_cast<ppu_intrp_func_t>(addr);
4708+
}
4709+
46974710
ppu_register_function_at(func.addr, 4, addr);
46984711

46994712
if (g_cfg.core.ppu_debug)
@@ -4703,6 +4716,19 @@ bool ppu_initialize(const ppu_module& info, bool check_only)
47034716
index = 0;
47044717
}
47054718

4719+
if (BLR_func)
4720+
{
4721+
auto inst_ptr = info.get_ptr<u32>(info.segs[0].addr);
4722+
4723+
for (u32 addr = info.segs[0].addr; addr < info.segs[0].addr + info.segs[0].size; addr += 4, inst_ptr++)
4724+
{
4725+
if (*inst_ptr == ppu_instructions::BLR() && (reinterpret_cast<uptr>(ppu_ref(addr)) << 16 >> 16) == reinterpret_cast<uptr>(ppu_recompiler_fallback_ghc))
4726+
{
4727+
ppu_register_function_at(addr, 4, BLR_func);
4728+
}
4729+
}
4730+
}
4731+
47064732
return compiled_new;
47074733
#else
47084734
fmt::throw_exception("LLVM is not available in this build.");

0 commit comments

Comments
 (0)