@@ -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