mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-31 20:41:45 +01:00
Implement fallback for PPU LLVM
This matches with interpreter implementation, fixing unregistered functions in lost cases
This commit is contained in:
parent
a9014a8cac
commit
f028737db8
@ -1,4 +1,4 @@
|
||||
#include "stdafx.h"
|
||||
#include "stdafx.h"
|
||||
#include "Utilities/VirtualMemory.h"
|
||||
#include "Utilities/sysinfo.h"
|
||||
#include "Utilities/JIT.h"
|
||||
@ -188,21 +188,52 @@ static u32 ppu_cache(u32 addr)
|
||||
|
||||
static bool ppu_fallback(ppu_thread& ppu, ppu_opcode_t op)
|
||||
{
|
||||
if (g_cfg.core.ppu_decoder == ppu_decoder_type::llvm)
|
||||
{
|
||||
fmt::throw_exception("Unregistered PPU function");
|
||||
}
|
||||
|
||||
ppu_ref(ppu.cia) = ppu_cache(ppu.cia);
|
||||
|
||||
if (g_cfg.core.ppu_debug)
|
||||
{
|
||||
LOG_ERROR(PPU, "Unregistered instruction: 0x%08x", op.opcode);
|
||||
}
|
||||
|
||||
ppu_ref(ppu.cia) = ppu_cache(ppu.cia);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: Make this a dispatch call
|
||||
void ppu_recompiler_fallback(ppu_thread& ppu)
|
||||
{
|
||||
if (g_cfg.core.ppu_debug)
|
||||
{
|
||||
LOG_ERROR(PPU, "Unregistered PPU Function (LR=0x%llx)", ppu.lr);
|
||||
}
|
||||
|
||||
const auto& table = g_ppu_interpreter_fast.get_table();
|
||||
const auto base = vm::g_base_addr;
|
||||
const auto cache = vm::g_exec_addr;
|
||||
|
||||
while (true)
|
||||
{
|
||||
// Run instructions in interpreter
|
||||
if (const u32 op = *reinterpret_cast<be_t<u32>*>(base + ppu.cia);
|
||||
LIKELY(table[ppu_decode(op)](ppu, { op })))
|
||||
{
|
||||
ppu.cia += 4;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (uptr func = *reinterpret_cast<u32*>(cache + ppu.cia);
|
||||
func != reinterpret_cast<uptr>(ppu_recompiler_fallback))
|
||||
{
|
||||
// We found a recompiler function at cia, return
|
||||
return;
|
||||
}
|
||||
|
||||
if (ppu.test_stopped())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static std::unordered_map<u32, u32>* s_ppu_toc;
|
||||
|
||||
static bool ppu_check_toc(ppu_thread& ppu, ppu_opcode_t op)
|
||||
@ -240,7 +271,8 @@ extern void ppu_register_range(u32 addr, u32 size)
|
||||
// Register executable range at
|
||||
utils::memory_commit(&ppu_ref(addr), size, utils::protection::rw);
|
||||
|
||||
const u32 fallback = ::narrow<u32>(reinterpret_cast<std::uintptr_t>(ppu_fallback));
|
||||
const u32 fallback = ::narrow<u32>(g_cfg.core.ppu_decoder == ppu_decoder_type::llvm ?
|
||||
reinterpret_cast<uptr>(ppu_recompiler_fallback) : reinterpret_cast<uptr>(ppu_fallback));
|
||||
|
||||
size &= ~3; // Loop assumes `size = n * 4`, enforce that by rounding down
|
||||
while (size)
|
||||
@ -1521,7 +1553,7 @@ extern void ppu_initialize(const ppu_module& info)
|
||||
#endif
|
||||
|
||||
// Write version, hash, CPU, settings
|
||||
fmt::append(obj_name, "v1-tane-%s-%s-%s.obj", fmt::base57(output, 16), fmt::base57(settings), jit_compiler::cpu(g_cfg.core.llvm_cpu));
|
||||
fmt::append(obj_name, "v2-tane-%s-%s-%s.obj", fmt::base57(output, 16), fmt::base57(settings), jit_compiler::cpu(g_cfg.core.llvm_cpu));
|
||||
}
|
||||
|
||||
if (Emu.IsStopped())
|
||||
|
@ -1,4 +1,4 @@
|
||||
#ifdef LLVM_AVAILABLE
|
||||
#ifdef LLVM_AVAILABLE
|
||||
|
||||
#include "PPUTranslator.h"
|
||||
#include "PPUThread.h"
|
||||
@ -271,6 +271,8 @@ void PPUTranslator::CallFunction(u64 target, Value* indirect)
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ir->CreateStore(Trunc(indirect, GetType<u32>()), m_ir->CreateStructGEP(nullptr, m_thread, &m_cia - m_locals), true);
|
||||
|
||||
// Try to optimize
|
||||
if (auto inst = dyn_cast_or_null<Instruction>(indirect))
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user