diff --git a/rpcs3/Emu/Cell/PPUAnalyser.cpp b/rpcs3/Emu/Cell/PPUAnalyser.cpp index 4efe2a5291..ebda9c2580 100644 --- a/rpcs3/Emu/Cell/PPUAnalyser.cpp +++ b/rpcs3/Emu/Cell/PPUAnalyser.cpp @@ -78,7 +78,7 @@ void ppu_module::validate(u32 reloc) if (size && size != funcs[index].size) { - if (size + 4 != funcs[index].size || *ensure(get_ptr(addr + size)) != ppu_instructions::NOP()) + if (size + 4 != funcs[index].size || get_ref(addr + size) != ppu_instructions::NOP()) { ppu_validator.error("%s.yml : function size mismatch at 0x%x(size=0x%x) (0x%x, 0x%x)", path, found, funcs[index].size, addr, size); } @@ -733,7 +733,7 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b // Register TOC from entry point if (entry && !lib_toc) { - lib_toc = *ensure(get_ptr(entry)) ? *ensure(get_ptr(entry + 4)) : *ensure(get_ptr(entry + 20)); + lib_toc = get_ref(entry) ? get_ref(entry + 4) : get_ref(entry + 20); } // Secondary attempt @@ -1425,7 +1425,7 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b for (vm::cptr _ptr = vm::cast(block.first); _ptr.addr() < block.first + block.second;) { const u32 iaddr = _ptr.addr(); - const ppu_opcode_t op{*ensure(get_ptr(_ptr++))}; + const ppu_opcode_t op{get_ref(_ptr++)}; const ppu_itype::type type = s_ppu_itype.decode(op.opcode); if (type == ppu_itype::B || type == ppu_itype::BC) @@ -1499,7 +1499,7 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b for (vm::cptr _ptr = vm::cast(start); _ptr.addr() < next;) { const u32 addr = _ptr.addr(); - const ppu_opcode_t op{*ensure(get_ptr(_ptr++))}; + const ppu_opcode_t op{get_ref(_ptr++)}; const ppu_itype::type type = s_ppu_itype.decode(op.opcode); if (type == ppu_itype::UNK) @@ -1641,7 +1641,7 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b continue; } - const u32 target = *ensure(get_ptr(rel.addr)); + const u32 target = get_ref(rel.addr); if (target % 4 || target < start || target >= end) { @@ -1718,7 +1718,7 @@ bool ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end, const std::b for (; i_pos < lim; i_pos += 4) { - const u32 opc = *ensure(get_ptr(i_pos)); + const u32 opc = get_ref(i_pos); switch (auto type = s_ppu_itype.decode(opc)) { diff --git a/rpcs3/Emu/Cell/PPUAnalyser.h b/rpcs3/Emu/Cell/PPUAnalyser.h index 8c5330c2b3..d7e34e76a0 100644 --- a/rpcs3/Emu/Cell/PPUAnalyser.h +++ b/rpcs3/Emu/Cell/PPUAnalyser.h @@ -148,6 +148,40 @@ struct ppu_module constexpr usz size_element = std::is_void_v ? 0 : sizeof(std::conditional_t, char, T>); return get_ptr(addr.addr(), u32{size_element}); } + + template + to_be_t& get_ref(u32 addr, + u32 line = __builtin_LINE(), + u32 col = __builtin_COLUMN(), + const char* file = __builtin_FILE(), + const char* func = __builtin_FUNCTION()) const + { + constexpr usz size_element = std::is_void_v ? 0 : sizeof(std::conditional_t, char, T>); + if (auto ptr = get_ptr(addr, u32{size_element})) + { + return *ptr; + } + + fmt::throw_exception("get_ref(): Failure! (addr=0x%x)%s", addr, src_loc{line, col, file, func}); + return *std::add_pointer_t>{}; + } + + template requires requires (const U& obj) { +obj.size() * 0; } + to_be_t& get_ref(U&& addr, + u32 line = __builtin_LINE(), + u32 col = __builtin_COLUMN(), + const char* file = __builtin_FILE(), + const char* func = __builtin_FUNCTION()) const + { + constexpr usz size_element = std::is_void_v ? 0 : sizeof(std::conditional_t, char, T>); + if (auto ptr = get_ptr(addr.addr(), u32{size_element})) + { + return *ptr; + } + + fmt::throw_exception("get_ref(): Failure! (addr=0x%x)%s", addr.addr(), src_loc{line, col, file, func}); + return *std::add_pointer_t>{}; + } }; struct main_ppu_module : public ppu_module