From 4ea7628204ef48ff641d2c3d9fe3050d42ac3d38 Mon Sep 17 00:00:00 2001 From: Eladash Date: Sun, 25 Oct 2020 09:08:50 +0200 Subject: [PATCH] SPU: Fix LS capture entry point --- rpcs3/Emu/Cell/SPUThread.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 5302c79d04..b8b567d5ef 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -20,6 +20,7 @@ #include "Emu/Cell/lv2/sys_interrupt.h" #include "Emu/Cell/SPUDisAsm.h" +#include "Emu/Cell/SPUAnalyser.h" #include "Emu/Cell/SPUThread.h" #include "Emu/Cell/SPUInterpreter.h" #include "Emu/Cell/SPURecompiler.h" @@ -226,6 +227,8 @@ void do_cell_atomic_128_store(u32 addr, const void* to_write); extern thread_local u64 g_tls_fault_spu; +constexpr spu_decoder s_spu_itype; + namespace spu { namespace scheduler @@ -3901,7 +3904,20 @@ bool spu_thread::capture_local_storage() const fmt::append(name, "RawSPU.%u", lv2_id); } - spu_exec.header.e_entry = pc; + u32 pc0 = pc; + + for (; pc0; pc0 -= 4) + { + const u32 op = *std::launder(reinterpret_cast*>(prog.bin.data() + pc0 - 4)); + + // Try to find function entry (if they are placed sequentially search for BI $LR of previous function) + if (!op || op == 0x35000000u || s_spu_itype.decode(op) == spu_itype::UNK) + { + break; + } + } + + spu_exec.header.e_entry = pc0; name = vfs::escape(name, true); std::replace(name.begin(), name.end(), ' ', '_');