PPU Fixes

-CallFunction empty function/jump elision was never gone through as cond was always false
-MSelf duplicate offset detection never triggered because set was reset each loop
-Rel executable memory size calculation used wrong section type
This commit is contained in:
RipleyTom
2026-03-06 10:49:59 +02:00
committed by Elad
parent c57d6110c4
commit 2f9f79eea2
3 changed files with 7 additions and 8 deletions
+3 -3
View File
@@ -1004,7 +1004,7 @@ static import_result_t ppu_load_imports(const ppu_module<lv2_obj>& _module, std:
// Check address // Check address
// TODO: The address of use should be extracted from analyser instead // TODO: The address of use should be extracted from analyser instead
if (fstub && fstub >= _module.segs[0].addr && fstub <= _module.segs[0].addr + _module.segs[0].size) if (fstub && fstub >= _module.segs[0].addr && fstub < _module.segs[0].addr + _module.segs[0].size)
{ {
nid_to_use_addr.emplace(fnid, fstub); nid_to_use_addr.emplace(fnid, fstub);
} }
@@ -1895,7 +1895,7 @@ shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, bool virtual_load, c
} }
else else
{ {
ppu_loader.error("Library %s: PRX library info not found"); ppu_loader.error("Library: PRX library info not found");
} }
prx->start.set(prx->specials[0xbc9a0086]); prx->start.set(prx->specials[0xbc9a0086]);
@@ -3192,7 +3192,7 @@ bool ppu_load_rel_exec(const ppu_rel_object& elf)
for (const auto& s : elf.shdrs) for (const auto& s : elf.shdrs)
{ {
if (s.sh_type != sec_type::sht_progbits) if (s.sh_type == sec_type::sht_progbits)
{ {
memsize = utils::align<u32>(memsize + vm::cast(s.sh_size), 128); memsize = utils::align<u32>(memsize + vm::cast(s.sh_size), 128);
} }
+2 -2
View File
@@ -3867,12 +3867,12 @@ extern void ppu_precompile(std::vector<std::string>& dir_queue, std::vector<ppu_
if (mself.read(hdr) && hdr.get_count(mself.size())) if (mself.read(hdr) && hdr.get_count(mself.size()))
{ {
std::set<u64> offs;
for (u32 j = 0; j < hdr.count; j++) for (u32 j = 0; j < hdr.count; j++)
{ {
mself_record rec{}; mself_record rec{};
std::set<u64> offs;
if (mself.read(rec) && rec.get_pos(mself.size())) if (mself.read(rec) && rec.get_pos(mself.size()))
{ {
if (rec.size <= 0x20) if (rec.size <= 0x20)
+2 -3
View File
@@ -550,11 +550,10 @@ void PPUTranslator::CallFunction(u64 target, Value* indirect)
else if (_target >= caddr && _target <= cend) else if (_target >= caddr && _target <= cend)
{ {
u32 target_last = static_cast<u32>(_target); u32 target_last = static_cast<u32>(_target);
std::unordered_set<u32> passed_targets{target_last}; std::unordered_set<u32> passed_targets{target_last};
// Try to follow unconditional branches as long as there is no infinite loop // Try to follow unconditional branches as long as there is no infinite loop
while (target_last != _target) while (true)
{ {
const ppu_opcode_t op{*ensure(m_info.get_ptr<u32>(target_last))}; const ppu_opcode_t op{*ensure(m_info.get_ptr<u32>(target_last))};
const ppu_itype::type itype = g_ppu_itype.decode(op.opcode); const ppu_itype::type itype = g_ppu_itype.decode(op.opcode);
@@ -1304,7 +1303,7 @@ void PPUTranslator::VMADDFP(ppu_opcode_t op)
if (!m_use_fma && data == v128{}) if (!m_use_fma && data == v128{})
{ {
set_vr(op.vd, vec_handle_result(a * c + fsplat<f32[4]>(0.f))); set_vr(op.vd, vec_handle_result(a * c + fsplat<f32[4]>(0.f)));
ppu_log.notice("LLVM: VMADDFP with -0 addend at [0x%08x]", m_addr + (m_reloc ? m_reloc->addr : 0)); ppu_log.notice("LLVM: VMADDFP with +0 addend at [0x%08x]", m_addr + (m_reloc ? m_reloc->addr : 0));
return; return;
} }
} }