From 721e55458c7ec0b993eccdba1624e24ea8809843 Mon Sep 17 00:00:00 2001 From: Elad Ashkenazi <18193363+elad335@users.noreply.github.com> Date: Fri, 7 Jun 2024 13:03:52 +0300 Subject: [PATCH] PPU Analyzer: Fixes --- rpcs3/Emu/Cell/PPUAnalyser.cpp | 19 ++++++++++--------- rpcs3/Emu/System.cpp | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUAnalyser.cpp b/rpcs3/Emu/Cell/PPUAnalyser.cpp index 62b7e5d936..08adadcd3b 100644 --- a/rpcs3/Emu/Cell/PPUAnalyser.cpp +++ b/rpcs3/Emu/Cell/PPUAnalyser.cpp @@ -930,6 +930,7 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b } bool used_fallback = false; + if (func_queue.empty() && segs[0].size >= 4u) { // Fallback, identify functions using callers (no jumptable detection, tail calls etc) @@ -945,9 +946,9 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b const ppu_opcode_t op{*ptr}; const ppu_itype::type type = s_ppu_itype.decode(op.opcode); - if (type == ppu_itype::B && op.lk && !op.aa) + if ((type == ppu_itype::B || type == ppu_itype::BC) && op.lk && (!op.aa || verify_func(iaddr))) { - const u32 target = iaddr + op.bt24; + const u32 target = (op.aa ? 0 : iaddr) + (type == ppu_itype::B ? +op.bt24 : +op.bt14); if (target >= start && target < end && target != iaddr && target != iaddr + 4) { @@ -1351,7 +1352,12 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b continue; } - const bool is_call = op.lk && target != iaddr; + if (!op.aa && target == _ptr.addr() && _ptr.addr() < func_end) + { + ppu_log.notice("[0x%x] Branch to next at 0x%x -> 0x%x", func.addr, iaddr, target); + } + + const bool is_call = op.lk && target != iaddr && target != _ptr.addr() && _ptr.addr() < func_end; const auto pfunc = is_call ? &add_func(target, 0, 0) : nullptr; if (pfunc && pfunc->blocks.empty()) @@ -2053,13 +2059,8 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b // Convert map to vector (destructive) for (auto&& [_, block] : as_rvalue(std::move(fmap))) { - if (block.attr & ppu_attr::no_size && block.size > 4) + if (block.attr & ppu_attr::no_size && block.size > 4 && !used_fallback) { - if (used_fallback) - { - continue; - } - ppu_log.warning("Block 0x%x will be compiled on per-instruction basis (size=0x%x)", block.addr, block.size); for (u32 addr = block.addr; addr < block.addr + block.size; addr += 4) diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 0eb8946513..2718b1970d 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -301,7 +301,7 @@ static void fixup_settings(const psf::registry* _psf) } } -void dump_executable(std::span data, main_ppu_module* _main, std::string_view title_id) +extern void dump_executable(std::span data, ppu_module* _main, std::string_view title_id) { // Format filename and directory name // Make each directory for each file so tools like IDA can work on it cleanly