1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 10:42:36 +01:00

PPU LLVM: Remove one external symbol resolve for BLR

This commit is contained in:
Elad.Ash 2024-03-21 15:56:31 +02:00 committed by GitHub
parent 2f822abb47
commit e32ed90d21
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -413,14 +413,14 @@ const auto ppu_recompiler_fallback_ghc = &ppu_recompiler_fallback;
#endif #endif
// Get pointer to executable cache // Get pointer to executable cache
static ppu_intrp_func_t* ppu_ptr(u32 addr) static inline u8* ppu_ptr(u32 addr)
{ {
return reinterpret_cast<ppu_intrp_func_t*>(vm::g_exec_addr + u64{addr} * 2); return vm::g_exec_addr + u64{addr} * 2;
} }
static ppu_intrp_func_t& ppu_ref(u32 addr) static inline ppu_intrp_func_t ppu_read(u32 addr)
{ {
return *ppu_ptr(addr); return read_from_ptr<ppu_intrp_func_t>(ppu_ptr(addr));
} }
// Get interpreter cache value // Get interpreter cache value
@ -445,7 +445,7 @@ static void ppu_fallback(ppu_thread& ppu, ppu_opcode_t op, be_t<u32>* this_op, p
{ {
const auto _pc = vm::get_addr(this_op); const auto _pc = vm::get_addr(this_op);
const auto _fn = ppu_cache(_pc); const auto _fn = ppu_cache(_pc);
ppu_ref(_pc) = _fn; write_to_ptr<ppu_intrp_func_t>(ppu_ptr(_pc), _fn);
return _fn(ppu, op, this_op, next_fn); return _fn(ppu, op, this_op, next_fn);
} }
@ -463,7 +463,7 @@ void ppu_recompiler_fallback(ppu_thread& ppu)
while (true) while (true)
{ {
if (uptr func = uptr(ppu_ref(ppu.cia)); (func << 16 >> 16) != reinterpret_cast<uptr>(ppu_recompiler_fallback_ghc)) if (uptr func = uptr(ppu_read(ppu.cia)); (func << 16 >> 16) != reinterpret_cast<uptr>(ppu_recompiler_fallback_ghc))
{ {
// We found a recompiler function at cia, return // We found a recompiler function at cia, return
break; break;
@ -730,11 +730,12 @@ extern void ppu_register_range(u32 addr, u32 size)
if (g_cfg.core.ppu_decoder == ppu_decoder_type::llvm) if (g_cfg.core.ppu_decoder == ppu_decoder_type::llvm)
{ {
// Assume addr is the start of first segment of PRX // Assume addr is the start of first segment of PRX
ppu_ref(addr) = reinterpret_cast<ppu_intrp_func_t>(reinterpret_cast<uptr>(ppu_recompiler_fallback_ghc) | (seg_base << (32 + 3))); const uptr entry_value = reinterpret_cast<uptr>(ppu_recompiler_fallback_ghc) | (seg_base << (32 + 3));
write_to_ptr<uptr>(ppu_ptr(addr), entry_value);
} }
else else
{ {
ppu_ref(addr) = ppu_fallback; write_to_ptr<ppu_intrp_func_t>(ppu_ptr(addr), ppu_fallback);
} }
addr += 4; addr += 4;
@ -749,7 +750,7 @@ extern void ppu_register_function_at(u32 addr, u32 size, ppu_intrp_func_t ptr =
// Initialize specific function // Initialize specific function
if (ptr) if (ptr)
{ {
ppu_ref(addr) = reinterpret_cast<ppu_intrp_func_t>((reinterpret_cast<uptr>(ptr) & 0xffff'ffff'ffffu) | (uptr(ppu_ref(addr)) & ~0xffff'ffff'ffffu)); write_to_ptr<uptr>(ppu_ptr(addr), (reinterpret_cast<uptr>(ptr) & 0xffff'ffff'ffffu) | (uptr(ppu_read(addr)) & ~0xffff'ffff'ffffu));
return; return;
} }
@ -771,9 +772,9 @@ extern void ppu_register_function_at(u32 addr, u32 size, ppu_intrp_func_t ptr =
// Initialize interpreter cache // Initialize interpreter cache
while (size) while (size)
{ {
if (ppu_ref(addr) != ppu_break && ppu_ref(addr) != ppu_far_jump) if (auto old = ppu_read(addr); old != ppu_break && old != ppu_far_jump)
{ {
ppu_ref(addr) = ppu_cache(addr); write_to_ptr<ppu_intrp_func_t>(ppu_ptr(addr), ppu_cache(addr));
} }
addr += 4; addr += 4;
@ -1132,8 +1133,8 @@ extern bool ppu_breakpoint(u32 addr, bool is_adding)
} }
// Remove breakpoint parameters // Remove breakpoint parameters
ppu_intrp_func_t to_set = 0; ppu_intrp_func_t func_original = 0;
ppu_intrp_func_t expected = &ppu_break; ppu_intrp_func_t breakpoint = &ppu_break;
if (u32 hle_addr{}; g_fxo->is_init<ppu_function_manager>() && (hle_addr = g_fxo->get<ppu_function_manager>().addr)) if (u32 hle_addr{}; g_fxo->is_init<ppu_function_manager>() && (hle_addr = g_fxo->get<ppu_function_manager>().addr))
{ {
@ -1143,31 +1144,40 @@ extern bool ppu_breakpoint(u32 addr, bool is_adding)
if (addr % 8 == 4 && index < ppu_function_manager::get().size()) if (addr % 8 == 4 && index < ppu_function_manager::get().size())
{ {
// HLE function placement // HLE function placement
to_set = ppu_function_manager::get()[index]; func_original = ppu_function_manager::get()[index];
} }
} }
if (!to_set) if (!func_original)
{ {
// If not an HLE function use regular instruction function // If not an HLE function use regular instruction function
to_set = ppu_cache(addr); func_original = ppu_cache(addr);
} }
ppu_intrp_func_t& _ref = ppu_ref(addr);
if (is_adding) if (is_adding)
{ {
// Swap if adding if (ppu_read(addr) == ppu_fallback)
std::swap(to_set, expected);
if (_ref == &ppu_fallback)
{ {
ppu_log.error("Unregistered instruction replaced with a breakpoint at 0x%08x", addr); ppu_log.error("Unregistered instruction replaced with a breakpoint at 0x%08x", addr);
expected = ppu_fallback; func_original = ppu_fallback;
} }
if (ppu_read(addr) != func_original)
{
return false;
}
write_to_ptr<ppu_intrp_func_t>(ppu_ptr(addr), breakpoint);
return true;
} }
return atomic_storage<ppu_intrp_func_t>::compare_exchange(_ref, expected, to_set); if (ppu_read(addr) != breakpoint)
{
return false;
}
write_to_ptr<ppu_intrp_func_t>(ppu_ptr(addr), func_original);
return true;
} }
extern bool ppu_patch(u32 addr, u32 value) extern bool ppu_patch(u32 addr, u32 value)
@ -1199,9 +1209,9 @@ extern bool ppu_patch(u32 addr, u32 value)
if (is_exec) if (is_exec)
{ {
if (ppu_ref(addr) != ppu_break && ppu_ref(addr) != ppu_fallback) if (auto old = ppu_read(addr); old != ppu_break && old != ppu_fallback)
{ {
ppu_ref(addr) = ppu_cache(addr); write_to_ptr<ppu_intrp_func_t>(ppu_ptr(addr), ppu_cache(addr));
} }
} }
@ -4249,8 +4259,18 @@ bool ppu_initialize(const ppu_module& info, bool check_only, u64 file_size)
for (const auto& func : info.funcs) for (const auto& func : info.funcs)
{ {
if (func.size && func.blocks.empty())
{
ppu_register_function_at(func.addr, func.size);
}
for (auto& block : func.blocks) for (auto& block : func.blocks)
{ {
if (!block.second)
{
continue;
}
if (g_fxo->is_init<ppu_far_jumps_t>() && !g_fxo->get<ppu_far_jumps_t>().get_targets(block.first, block.second).empty()) if (g_fxo->is_init<ppu_far_jumps_t>() && !g_fxo->get<ppu_far_jumps_t>().get_targets(block.first, block.second).empty())
{ {
// Replace the block with ppu_far_jump // Replace the block with ppu_far_jump
@ -4263,7 +4283,7 @@ bool ppu_initialize(const ppu_module& info, bool check_only, u64 file_size)
if (g_cfg.core.ppu_debug && func.size && func.toc != umax && !ppu_get_far_jump(func.addr)) if (g_cfg.core.ppu_debug && func.size && func.toc != umax && !ppu_get_far_jump(func.addr))
{ {
ppu_toc[func.addr] = func.toc; ppu_toc[func.addr] = func.toc;
ppu_ref(func.addr) = &ppu_check_toc; write_to_ptr<ppu_intrp_func_t>(ppu_ptr(func.addr), &ppu_check_toc);
} }
} }
@ -4856,7 +4876,7 @@ bool ppu_initialize(const ppu_module& info, bool check_only, u64 file_size)
const bool showing_only_apply_stage = !g_progr.load() && !g_progr_ptotal && !g_progr_ftotal && g_progr_ptotal.compare_and_swap_test(0, 1); const bool showing_only_apply_stage = !g_progr.load() && !g_progr_ptotal && !g_progr_ftotal && g_progr_ptotal.compare_and_swap_test(0, 1);
progr.emplace("Applying PPU Code..."); progr = "Applying PPU Code...";
if (is_first) if (is_first)
{ {
@ -4879,9 +4899,7 @@ bool ppu_initialize(const ppu_module& info, bool check_only, u64 file_size)
{ {
if (func.size == 4 && *info.get_ptr<u32>(func.addr) == ppu_instructions::BLR()) if (func.size == 4 && *info.get_ptr<u32>(func.addr) == ppu_instructions::BLR())
{ {
const auto name = fmt::format("__0x%x", func.addr - reloc); BLR_func = ppu_read(func.addr);
BLR_func = reinterpret_cast<ppu_intrp_func_t>(jit->get(name));
break; break;
} }
} }
@ -4897,9 +4915,9 @@ bool ppu_initialize(const ppu_module& info, bool check_only, u64 file_size)
for (u32 addr = info.segs[0].addr; addr < info.segs[0].addr + info.segs[0].size; addr += 4, inst_ptr++) for (u32 addr = info.segs[0].addr; addr < info.segs[0].addr + info.segs[0].size; addr += 4, inst_ptr++)
{ {
if (*inst_ptr == ppu_instructions::BLR() && (reinterpret_cast<uptr>(ppu_ref(addr)) << 16 >> 16) == reinterpret_cast<uptr>(ppu_recompiler_fallback_ghc)) if (*inst_ptr == ppu_instructions::BLR() && (reinterpret_cast<uptr>(ppu_read(addr)) << 16 >> 16) == reinterpret_cast<uptr>(ppu_recompiler_fallback_ghc))
{ {
ppu_register_function_at(addr, 4, BLR_func); write_to_ptr<ppu_intrp_func_t>(ppu_ptr(addr), BLR_func);
} }
} }
} }