diff --git a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp index c12374f8e8..0060738dad 100644 --- a/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPUCommonRecompiler.cpp @@ -2304,6 +2304,49 @@ std::vector spu_thread::discover_functions(u32 base_addr, std::span= base_addr && next < std::min(base_addr + ::size32(ls), 0x3FFF0); it--, next += 4) + { + const spu_opcode_t test_op{read_from_ptr>(ls, next - base_addr)}; + const auto type = g_spu_itype.decode(test_op.opcode); + + if (type & spu_itype::branch && type != spu_itype::BR) + { + break; + } + + if (type == spu_itype::UNK || !test_op.opcode) + { + break; + } + + if (type != spu_itype::BR) + { + continue; + } + + const u32 target = op_branch_targets(next, op)[0]; + + if (target == umax || addr + 4 == target || target == addr || std::count(addrs.begin(), addrs.end(), target)) + { + break; + } + + // Detect backwards branch to the block in examination + if (target >= func && target <= next) + { + break; + } + + if (!is_exec_code(target, ls, base_addr, true)) + { + break; + } + + addrs.push_back(target); + break; + } } for (u32 addr : branches) @@ -2329,6 +2372,11 @@ std::vector spu_thread::discover_functions(u32 base_addr, std::span