PPU LLVM: Filter out functions with patches
Some checks failed
Generate Translation Template / Generate Translation Template (push) Has been cancelled
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (/rpcs3/.ci/build-linux-aarch64.sh, gcc, rpcs3/rpcs3-ci-jammy-aarch64:1.6, ubuntu-24.04-arm) (push) Has been cancelled
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (/rpcs3/.ci/build-linux.sh, gcc, rpcs3/rpcs3-ci-jammy:1.6, ubuntu-24.04) (push) Has been cancelled
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (a1d35836e8d45bfc6f63c26f0a3e5d46ef622fe1, rpcs3/rpcs3-binaries-linux-arm64, /rpcs3/.ci/build-linux-aarch64.sh, clang, rpcs3/rpcs3-ci-jammy-aarch64:1.6, ubuntu-24.04-arm) (push) Has been cancelled
Build RPCS3 / RPCS3 Linux ${{ matrix.os }} ${{ matrix.compiler }} (d812f1254a1157c80fd402f94446310560f54e5f, rpcs3/rpcs3-binaries-linux, /rpcs3/.ci/build-linux.sh, clang, rpcs3/rpcs3-ci-jammy:1.6, ubuntu-24.04) (push) Has been cancelled
Build RPCS3 / RPCS3 Mac ${{ matrix.name }} (51ae32f468089a8169aaf1567de355ff4a3e0842, rpcs3/rpcs3-binaries-mac, arch -X86_64 .ci/build-mac.sh, Intel) (push) Has been cancelled
Build RPCS3 / RPCS3 Mac ${{ matrix.name }} (8e21bdbc40711a3fccd18fbf17b742348b0f4281, rpcs3/rpcs3-binaries-mac-arm64, .ci/build-mac-arm64.sh, Apple Silicon) (push) Has been cancelled
Build RPCS3 / RPCS3 Windows (push) Has been cancelled
Build RPCS3 / RPCS3 Windows Clang (win64, clang, clang64) (push) Has been cancelled
Build RPCS3 / RPCS3 FreeBSD (push) Has been cancelled

This commit is contained in:
Elad 2025-09-21 23:48:26 +03:00
parent 6bc690491f
commit 29108e1cb4
3 changed files with 69 additions and 2 deletions

View File

@ -145,6 +145,7 @@ struct ppu_module : public Type
std::shared_ptr<std::pair<u32, u32>> jit_bounds; // JIT instance modules addresses range
std::unordered_map<u32, void*> imports; // Imports information for release upon unload (TODO: OVL implementation!)
std::map<u32, std::vector<std::pair<ppua_reg_mask_t, u64>>> stub_addr_to_constant_state_of_registers; // Tells possible constant states of registers of functions
std::vector<u32> excluded_funcs; // Function code not be overwritten
bool is_relocatable = false; // Is code relocatable(?)
template <typename T>

View File

@ -934,13 +934,40 @@ struct ppu_far_jumps_t
ppu_far_jumps_t(int) noexcept {}
std::map<u32, all_info_t> vals;
std::pair<u32, u32> vals_range{0, 0};
::jit_runtime rt;
mutable shared_mutex mutex;
void add_value(u32 addr, all_info_t info)
{
vals.insert_or_assign(addr, std::move(info));
if (vals.size() == 1)
{
vals_range.first = addr;
vals_range.second = addr;
}
else
{
vals_range.first = std::min<u32>(vals_range.first, addr);
vals_range.second = std::max<u32>(vals_range.second, addr);
}
}
// Get target address, 'ppu' is used in ppu_far_jump in order to modify registers
u32 get_target(u32 pc, ppu_thread* ppu = nullptr)
{
if (vals_range.first > pc)
{
return 0;
}
if (vals_range.second < pc)
{
return 0;
}
reader_lock lock(mutex);
if (auto it = vals.find(pc); it != vals.end())
@ -949,7 +976,7 @@ struct ppu_far_jumps_t
return all_info.get_target(pc, ppu);
}
return {};
return 0;
}
// Get function patches in range (entry -> target)
@ -957,6 +984,16 @@ struct ppu_far_jumps_t
{
std::vector<std::pair<u32, u32>> targets;
if (vals_range.first >= pc + size)
{
return targets;
}
if (vals_range.second < pc)
{
return targets;
}
reader_lock lock(mutex);
auto it = vals.lower_bound(pc);
@ -1110,7 +1147,7 @@ bool ppu_form_branch_to_code(u32 entry, u32 target, bool link, bool with_toc, st
auto& jumps = g_fxo->get<ppu_far_jumps_t>();
std::lock_guard lock(jumps.mutex);
jumps.vals.insert_or_assign(entry, ppu_far_jumps_t::all_info_t{target, link, with_toc, std::move(module_name)});
jumps.add_value(entry, ppu_far_jumps_t::all_info_t{target, link, with_toc, std::move(module_name)});
ppu_register_function_at(entry, 4, g_cfg.core.ppu_decoder == ppu_decoder_type::_static ? &ppu_far_jump : ensure(g_fxo->get<ppu_far_jumps_t>().gen_jump<false>(entry)));
return true;
@ -5214,6 +5251,7 @@ bool ppu_initialize(const ppu_module<lv2_obj>& info, bool check_only, u64 file_s
{
// Replace the function with ppu_far_jump
fpos++;
part.excluded_funcs.emplace_back(func.addr);
continue;
}
}
@ -5246,6 +5284,11 @@ bool ppu_initialize(const ppu_module<lv2_obj>& info, bool check_only, u64 file_s
continue;
}
if (std::count(part.excluded_funcs.begin(), part.excluded_funcs.end(), func.addr))
{
continue;
}
const be_t<u32> addr = func.addr - reloc;
const be_t<u32> size = func.size;
sha1_update(&ctx, reinterpret_cast<const u8*>(&addr), sizeof(addr));
@ -5343,6 +5386,13 @@ bool ppu_initialize(const ppu_module<lv2_obj>& info, bool check_only, u64 file_s
continue;
}
if (g_fxo->is_init<ppu_far_jumps_t>() && !g_fxo->get<ppu_far_jumps_t>().get_targets(func.addr, func.size).empty())
{
// Filter out functions with patches
part.excluded_funcs.emplace_back(func.addr);
continue;
}
addrs.emplace_back(func.addr - reloc);
}
@ -5779,6 +5829,11 @@ static void ppu_initialize2(jit_compiler& jit, const ppu_module<lv2_obj>& module
{
if (func.size)
{
if (std::count(module_part.excluded_funcs.begin(), module_part.excluded_funcs.end(), func.addr))
{
continue;
}
const auto f = cast<Function>(_module->getOrInsertFunction(fmt::format("__0x%x", func.addr - reloc), _func).getCallee());
f->setCallingConv(CallingConv::GHC);
f->addParamAttr(1, llvm::Attribute::NoAlias);
@ -5834,6 +5889,11 @@ static void ppu_initialize2(jit_compiler& jit, const ppu_module<lv2_obj>& module
if (mod_func.size)
{
if (std::count(module_part.excluded_funcs.begin(), module_part.excluded_funcs.end(), mod_func.addr))
{
continue;
}
num_func++;
guest_code_size += mod_func.size;
max_addr = std::max<u32>(max_addr, mod_func.addr + mod_func.size);

View File

@ -364,6 +364,12 @@ Function* PPUTranslator::GetSymbolResolver(const ppu_module<lv2_obj>& info)
continue;
}
if (std::count(info.excluded_funcs.begin(), info.excluded_funcs.end(), f.addr))
{
// Excluded function (possibly patched)
continue;
}
vec_addrs.push_back(static_cast<u32>(f.addr - base));
functions.push_back(cast<Function>(m_module->getOrInsertFunction(fmt::format("__0x%x", f.addr - base), ftype).getCallee()));
}