mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-10 16:19:28 +01:00
JitInterface: Refactor to class, move to System.
This commit is contained in:
parent
db40348c86
commit
9217a9eba4
@ -397,8 +397,9 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetProfiling
|
|||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> guard(s_host_identity_lock);
|
std::lock_guard<std::mutex> guard(s_host_identity_lock);
|
||||||
Core::SetState(Core::State::Paused);
|
Core::SetState(Core::State::Paused);
|
||||||
JitInterface::ClearCache();
|
auto& jit_interface = Core::System::GetInstance().GetJitInterface();
|
||||||
JitInterface::SetProfilingState(enable ? JitInterface::ProfilingState::Enabled :
|
jit_interface.ClearCache();
|
||||||
|
jit_interface.SetProfilingState(enable ? JitInterface::ProfilingState::Enabled :
|
||||||
JitInterface::ProfilingState::Disabled);
|
JitInterface::ProfilingState::Disabled);
|
||||||
Core::SetState(Core::State::Running);
|
Core::SetState(Core::State::Running);
|
||||||
}
|
}
|
||||||
@ -409,7 +410,8 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_WriteProfile
|
|||||||
std::lock_guard<std::mutex> guard(s_host_identity_lock);
|
std::lock_guard<std::mutex> guard(s_host_identity_lock);
|
||||||
std::string filename = File::GetUserPath(D_DUMP_IDX) + "Debug/profiler.txt";
|
std::string filename = File::GetUserPath(D_DUMP_IDX) + "Debug/profiler.txt";
|
||||||
File::CreateFullPath(filename);
|
File::CreateFullPath(filename);
|
||||||
JitInterface::WriteProfileResults(filename);
|
auto& jit_interface = Core::System::GetInstance().GetJitInterface();
|
||||||
|
jit_interface.WriteProfileResults(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Surface Handling
|
// Surface Handling
|
||||||
|
@ -986,7 +986,7 @@ void UpdateWantDeterminism(bool initial)
|
|||||||
|
|
||||||
// We need to clear the cache because some parts of the JIT depend on want_determinism,
|
// We need to clear the cache because some parts of the JIT depend on want_determinism,
|
||||||
// e.g. use of FMA.
|
// e.g. use of FMA.
|
||||||
JitInterface::ClearCache();
|
system.GetJitInterface().ClearCache();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,7 +132,7 @@ void GPFifoManager::CheckGatherPipe()
|
|||||||
UpdateGatherPipe();
|
UpdateGatherPipe();
|
||||||
|
|
||||||
// Profile where slow FIFO writes are occurring.
|
// Profile where slow FIFO writes are occurring.
|
||||||
JitInterface::CompileExceptionCheck(JitInterface::ExceptionType::FIFOWrite);
|
m_system.GetJitInterface().CompileExceptionCheck(JitInterface::ExceptionType::FIFOWrite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "Core/MachineContext.h"
|
#include "Core/MachineContext.h"
|
||||||
#include "Core/PowerPC/JitInterface.h"
|
#include "Core/PowerPC/JitInterface.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
#if defined(__FreeBSD__) || defined(__NetBSD__)
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -60,7 +61,7 @@ static LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
|
|||||||
uintptr_t fault_address = (uintptr_t)pPtrs->ExceptionRecord->ExceptionInformation[1];
|
uintptr_t fault_address = (uintptr_t)pPtrs->ExceptionRecord->ExceptionInformation[1];
|
||||||
SContext* ctx = pPtrs->ContextRecord;
|
SContext* ctx = pPtrs->ContextRecord;
|
||||||
|
|
||||||
if (JitInterface::HandleFault(fault_address, ctx))
|
if (Core::System::GetInstance().GetJitInterface().HandleFault(fault_address, ctx))
|
||||||
{
|
{
|
||||||
return EXCEPTION_CONTINUE_EXECUTION;
|
return EXCEPTION_CONTINUE_EXECUTION;
|
||||||
}
|
}
|
||||||
@ -72,7 +73,7 @@ static LONG NTAPI Handler(PEXCEPTION_POINTERS pPtrs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case EXCEPTION_STACK_OVERFLOW:
|
case EXCEPTION_STACK_OVERFLOW:
|
||||||
if (JitInterface::HandleStackFault())
|
if (Core::System::GetInstance().GetJitInterface().HandleStackFault())
|
||||||
return EXCEPTION_CONTINUE_EXECUTION;
|
return EXCEPTION_CONTINUE_EXECUTION;
|
||||||
else
|
else
|
||||||
return EXCEPTION_CONTINUE_SEARCH;
|
return EXCEPTION_CONTINUE_SEARCH;
|
||||||
@ -190,7 +191,8 @@ static void ExceptionThread(mach_port_t port)
|
|||||||
|
|
||||||
thread_state64_t* state = (thread_state64_t*)msg_in.old_state;
|
thread_state64_t* state = (thread_state64_t*)msg_in.old_state;
|
||||||
|
|
||||||
bool ok = JitInterface::HandleFault((uintptr_t)msg_in.code[1], state);
|
bool ok =
|
||||||
|
Core::System::GetInstance().GetJitInterface().HandleFault((uintptr_t)msg_in.code[1], state);
|
||||||
|
|
||||||
// Set up the reply.
|
// Set up the reply.
|
||||||
msg_out.Head.msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(msg_in.Head.msgh_bits), 0);
|
msg_out.Head.msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REMOTE(msg_in.Head.msgh_bits), 0);
|
||||||
@ -281,7 +283,7 @@ static void sigsegv_handler(int sig, siginfo_t* info, void* raw_context)
|
|||||||
mcontext_t* ctx = &context->uc_mcontext;
|
mcontext_t* ctx = &context->uc_mcontext;
|
||||||
#endif
|
#endif
|
||||||
// assume it's not a write
|
// assume it's not a write
|
||||||
if (!JitInterface::HandleFault(bad_address,
|
if (!Core::System::GetInstance().GetJitInterface().HandleFault(bad_address,
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
*ctx
|
*ctx
|
||||||
#else
|
#else
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "Core/PowerPC/Expression.h"
|
#include "Core/PowerPC/Expression.h"
|
||||||
#include "Core/PowerPC/JitInterface.h"
|
#include "Core/PowerPC/JitInterface.h"
|
||||||
#include "Core/PowerPC/MMU.h"
|
#include "Core/PowerPC/MMU.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
bool BreakPoints::IsAddressBreakPoint(u32 address) const
|
bool BreakPoints::IsAddressBreakPoint(u32 address) const
|
||||||
{
|
{
|
||||||
@ -105,7 +106,7 @@ void BreakPoints::Add(TBreakPoint bp)
|
|||||||
if (IsAddressBreakPoint(bp.address))
|
if (IsAddressBreakPoint(bp.address))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
JitInterface::InvalidateICache(bp.address, 4, true);
|
Core::System::GetInstance().GetJitInterface().InvalidateICache(bp.address, 4, true);
|
||||||
|
|
||||||
m_breakpoints.emplace_back(std::move(bp));
|
m_breakpoints.emplace_back(std::move(bp));
|
||||||
}
|
}
|
||||||
@ -141,7 +142,7 @@ void BreakPoints::Add(u32 address, bool temp, bool break_on_hit, bool log_on_hit
|
|||||||
m_breakpoints.emplace_back(std::move(bp));
|
m_breakpoints.emplace_back(std::move(bp));
|
||||||
}
|
}
|
||||||
|
|
||||||
JitInterface::InvalidateICache(address, 4, true);
|
Core::System::GetInstance().GetJitInterface().InvalidateICache(address, 4, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BreakPoints::ToggleBreakPoint(u32 address)
|
bool BreakPoints::ToggleBreakPoint(u32 address)
|
||||||
@ -165,14 +166,14 @@ void BreakPoints::Remove(u32 address)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
m_breakpoints.erase(iter);
|
m_breakpoints.erase(iter);
|
||||||
JitInterface::InvalidateICache(address, 4, true);
|
Core::System::GetInstance().GetJitInterface().InvalidateICache(address, 4, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BreakPoints::Clear()
|
void BreakPoints::Clear()
|
||||||
{
|
{
|
||||||
for (const TBreakPoint& bp : m_breakpoints)
|
for (const TBreakPoint& bp : m_breakpoints)
|
||||||
{
|
{
|
||||||
JitInterface::InvalidateICache(bp.address, 4, true);
|
Core::System::GetInstance().GetJitInterface().InvalidateICache(bp.address, 4, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_breakpoints.clear();
|
m_breakpoints.clear();
|
||||||
@ -185,7 +186,7 @@ void BreakPoints::ClearAllTemporary()
|
|||||||
{
|
{
|
||||||
if (bp->is_temporary)
|
if (bp->is_temporary)
|
||||||
{
|
{
|
||||||
JitInterface::InvalidateICache(bp->address, 4, true);
|
Core::System::GetInstance().GetJitInterface().InvalidateICache(bp->address, 4, true);
|
||||||
bp = m_breakpoints.erase(bp);
|
bp = m_breakpoints.erase(bp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -278,7 +279,7 @@ void MemChecks::Add(TMemCheck memory_check)
|
|||||||
// If this is the first one, clear the JIT cache so it can switch to
|
// If this is the first one, clear the JIT cache so it can switch to
|
||||||
// watchpoint-compatible code.
|
// watchpoint-compatible code.
|
||||||
if (!had_any)
|
if (!had_any)
|
||||||
JitInterface::ClearCache();
|
Core::System::GetInstance().GetJitInterface().ClearCache();
|
||||||
PowerPC::DBATUpdated();
|
PowerPC::DBATUpdated();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -307,7 +308,7 @@ void MemChecks::Remove(u32 address)
|
|||||||
Core::RunAsCPUThread([&] {
|
Core::RunAsCPUThread([&] {
|
||||||
m_mem_checks.erase(iter);
|
m_mem_checks.erase(iter);
|
||||||
if (!HasAny())
|
if (!HasAny())
|
||||||
JitInterface::ClearCache();
|
Core::System::GetInstance().GetJitInterface().ClearCache();
|
||||||
PowerPC::DBATUpdated();
|
PowerPC::DBATUpdated();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -316,7 +317,7 @@ void MemChecks::Clear()
|
|||||||
{
|
{
|
||||||
Core::RunAsCPUThread([&] {
|
Core::RunAsCPUThread([&] {
|
||||||
m_mem_checks.clear();
|
m_mem_checks.clear();
|
||||||
JitInterface::ClearCache();
|
Core::System::GetInstance().GetJitInterface().ClearCache();
|
||||||
PowerPC::DBATUpdated();
|
PowerPC::DBATUpdated();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "Core/PowerPC/JitInterface.h"
|
#include "Core/PowerPC/JitInterface.h"
|
||||||
#include "Core/PowerPC/MMU.h"
|
#include "Core/PowerPC/MMU.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
static u32 Helper_Get_EA(const PowerPC::PowerPCState& ppcs, const UGeckoInstruction inst)
|
static u32 Helper_Get_EA(const PowerPC::PowerPCState& ppcs, const UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
@ -473,7 +474,7 @@ void Interpreter::dcbf(Interpreter& interpreter, UGeckoInstruction inst)
|
|||||||
// Invalidate the JIT cache here as a heuristic to compensate for
|
// Invalidate the JIT cache here as a heuristic to compensate for
|
||||||
// the lack of precise L1 icache emulation in the JIT. (Portable software
|
// the lack of precise L1 icache emulation in the JIT. (Portable software
|
||||||
// should use icbi consistently, but games aren't portable.)
|
// should use icbi consistently, but games aren't portable.)
|
||||||
JitInterface::InvalidateICacheLine(address);
|
interpreter.m_system.GetJitInterface().InvalidateICacheLine(address);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -495,7 +496,7 @@ void Interpreter::dcbi(Interpreter& interpreter, UGeckoInstruction inst)
|
|||||||
// Invalidate the JIT cache here as a heuristic to compensate for
|
// Invalidate the JIT cache here as a heuristic to compensate for
|
||||||
// the lack of precise L1 icache emulation in the JIT. (Portable software
|
// the lack of precise L1 icache emulation in the JIT. (Portable software
|
||||||
// should use icbi consistently, but games aren't portable.)
|
// should use icbi consistently, but games aren't portable.)
|
||||||
JitInterface::InvalidateICacheLine(address);
|
interpreter.m_system.GetJitInterface().InvalidateICacheLine(address);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -511,7 +512,7 @@ void Interpreter::dcbst(Interpreter& interpreter, UGeckoInstruction inst)
|
|||||||
// Invalidate the JIT cache here as a heuristic to compensate for
|
// Invalidate the JIT cache here as a heuristic to compensate for
|
||||||
// the lack of precise L1 icache emulation in the JIT. (Portable software
|
// the lack of precise L1 icache emulation in the JIT. (Portable software
|
||||||
// should use icbi consistently, but games aren't portable.)
|
// should use icbi consistently, but games aren't portable.)
|
||||||
JitInterface::InvalidateICacheLine(address);
|
interpreter.m_system.GetJitInterface().InvalidateICacheLine(address);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -877,7 +877,7 @@ bool Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
|||||||
const u8* target = GetCodePtr();
|
const u8* target = GetCodePtr();
|
||||||
MOV(32, PPCSTATE(pc), Imm32(js.blockStart));
|
MOV(32, PPCSTATE(pc), Imm32(js.blockStart));
|
||||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||||
ABI_CallFunctionC(JitInterface::CompileExceptionCheck,
|
ABI_CallFunctionPC(JitInterface::CompileExceptionCheckFromJIT, &m_system.GetJitInterface(),
|
||||||
static_cast<u32>(JitInterface::ExceptionType::PairedQuantize));
|
static_cast<u32>(JitInterface::ExceptionType::PairedQuantize));
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
JMP(asm_routines.dispatcher_no_check, true);
|
JMP(asm_routines.dispatcher_no_check, true);
|
||||||
@ -1193,7 +1193,7 @@ void Jit64::IntializeSpeculativeConstants()
|
|||||||
target = GetCodePtr();
|
target = GetCodePtr();
|
||||||
MOV(32, PPCSTATE(pc), Imm32(js.blockStart));
|
MOV(32, PPCSTATE(pc), Imm32(js.blockStart));
|
||||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||||
ABI_CallFunctionC(JitInterface::CompileExceptionCheck,
|
ABI_CallFunctionPC(JitInterface::CompileExceptionCheckFromJIT, &m_system.GetJitInterface(),
|
||||||
static_cast<u32>(JitInterface::ExceptionType::SpeculativeConstants));
|
static_cast<u32>(JitInterface::ExceptionType::SpeculativeConstants));
|
||||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||||
JMP(asm_routines.dispatcher_no_check, true);
|
JMP(asm_routines.dispatcher_no_check, true);
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "Core/PowerPC/JitInterface.h"
|
#include "Core/PowerPC/JitInterface.h"
|
||||||
#include "Core/PowerPC/MMU.h"
|
#include "Core/PowerPC/MMU.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
using namespace Gen;
|
using namespace Gen;
|
||||||
|
|
||||||
@ -362,12 +363,14 @@ void Jit64::dcbx(UGeckoInstruction inst)
|
|||||||
{
|
{
|
||||||
MOV(32, R(ABI_PARAM1), R(effective_address));
|
MOV(32, R(ABI_PARAM1), R(effective_address));
|
||||||
MOV(32, R(ABI_PARAM2), R(loop_counter));
|
MOV(32, R(ABI_PARAM2), R(loop_counter));
|
||||||
ABI_CallFunction(JitInterface::InvalidateICacheLines);
|
MOV(64, R(ABI_PARAM3), Imm64(reinterpret_cast<u64>(&m_system.GetJitInterface())));
|
||||||
|
ABI_CallFunction(JitInterface::InvalidateICacheLinesFromJIT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MOV(32, R(ABI_PARAM1), R(effective_address));
|
MOV(32, R(ABI_PARAM1), R(effective_address));
|
||||||
ABI_CallFunction(JitInterface::InvalidateICacheLine);
|
MOV(64, R(ABI_PARAM3), Imm64(reinterpret_cast<u64>(&m_system.GetJitInterface())));
|
||||||
|
ABI_CallFunction(JitInterface::InvalidateICacheLineFromJIT);
|
||||||
}
|
}
|
||||||
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
|
ABI_PopRegistersAndAdjustStack(registersInUse, 0);
|
||||||
asm_routines.ResetStack(*this);
|
asm_routines.ResetStack(*this);
|
||||||
|
@ -327,8 +327,9 @@ void JitArm64::IntializeSpeculativeConstants()
|
|||||||
fail = GetCodePtr();
|
fail = GetCodePtr();
|
||||||
MOVI2R(DISPATCHER_PC, js.blockStart);
|
MOVI2R(DISPATCHER_PC, js.blockStart);
|
||||||
STR(IndexType::Unsigned, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc));
|
STR(IndexType::Unsigned, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc));
|
||||||
MOVP2R(ARM64Reg::X8, &JitInterface::CompileExceptionCheck);
|
MOVP2R(ARM64Reg::X8, &JitInterface::CompileExceptionCheckFromJIT);
|
||||||
MOVI2R(ARM64Reg::W0, static_cast<u32>(JitInterface::ExceptionType::SpeculativeConstants));
|
MOVP2R(ARM64Reg::X0, &m_system.GetJitInterface());
|
||||||
|
MOVI2R(ARM64Reg::W1, static_cast<u32>(JitInterface::ExceptionType::SpeculativeConstants));
|
||||||
BLR(ARM64Reg::X8);
|
BLR(ARM64Reg::X8);
|
||||||
B(dispatcher_no_check);
|
B(dispatcher_no_check);
|
||||||
SwitchToNearCode();
|
SwitchToNearCode();
|
||||||
@ -866,9 +867,10 @@ bool JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC)
|
|||||||
SetJumpTarget(fail);
|
SetJumpTarget(fail);
|
||||||
MOVI2R(DISPATCHER_PC, js.blockStart);
|
MOVI2R(DISPATCHER_PC, js.blockStart);
|
||||||
STR(IndexType::Unsigned, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc));
|
STR(IndexType::Unsigned, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc));
|
||||||
MOVI2R(ARM64Reg::W0, static_cast<u32>(JitInterface::ExceptionType::PairedQuantize));
|
MOVP2R(ARM64Reg::X0, &m_system.GetJitInterface());
|
||||||
MOVP2R(ARM64Reg::X1, &JitInterface::CompileExceptionCheck);
|
MOVI2R(ARM64Reg::W1, static_cast<u32>(JitInterface::ExceptionType::PairedQuantize));
|
||||||
BLR(ARM64Reg::X1);
|
MOVP2R(ARM64Reg::X2, &JitInterface::CompileExceptionCheckFromJIT);
|
||||||
|
BLR(ARM64Reg::X2);
|
||||||
B(dispatcher_no_check);
|
B(dispatcher_no_check);
|
||||||
SwitchToNearCode();
|
SwitchToNearCode();
|
||||||
SetJumpTarget(no_fail);
|
SetJumpTarget(no_fail);
|
||||||
|
@ -770,11 +770,12 @@ void JitArm64::dcbx(UGeckoInstruction inst)
|
|||||||
ABI_PushRegisters(gprs_to_push);
|
ABI_PushRegisters(gprs_to_push);
|
||||||
m_float_emit.ABI_PushRegisters(fprs_to_push, WA);
|
m_float_emit.ABI_PushRegisters(fprs_to_push, WA);
|
||||||
|
|
||||||
// The function call arguments are already in the correct registers
|
// The first two function call arguments are already in the correct registers
|
||||||
|
MOVP2R(ARM64Reg::X2, &m_system.GetJitInterface());
|
||||||
if (make_loop)
|
if (make_loop)
|
||||||
MOVP2R(ARM64Reg::X8, &JitInterface::InvalidateICacheLines);
|
MOVP2R(ARM64Reg::X8, &JitInterface::InvalidateICacheLinesFromJIT);
|
||||||
else
|
else
|
||||||
MOVP2R(ARM64Reg::X8, &JitInterface::InvalidateICacheLine);
|
MOVP2R(ARM64Reg::X8, &JitInterface::InvalidateICacheLineFromJIT);
|
||||||
BLR(ARM64Reg::X8);
|
BLR(ARM64Reg::X8);
|
||||||
|
|
||||||
m_float_emit.ABI_PopRegisters(fprs_to_push, WA);
|
m_float_emit.ABI_PopRegisters(fprs_to_push, WA);
|
||||||
|
@ -40,19 +40,24 @@
|
|||||||
#include "Core/PowerPC/JitArm64/Jit.h"
|
#include "Core/PowerPC/JitArm64/Jit.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace JitInterface
|
JitInterface::JitInterface(Core::System& system) : m_system(system)
|
||||||
{
|
{
|
||||||
static JitBase* g_jit = nullptr;
|
|
||||||
void SetJit(JitBase* jit)
|
|
||||||
{
|
|
||||||
g_jit = jit;
|
|
||||||
}
|
}
|
||||||
void DoState(PointerWrap& p)
|
|
||||||
|
JitInterface::~JitInterface() = default;
|
||||||
|
|
||||||
|
void JitInterface::SetJit(JitBase* jit)
|
||||||
{
|
{
|
||||||
if (g_jit && p.IsReadMode())
|
m_jit = jit;
|
||||||
g_jit->ClearCache();
|
|
||||||
}
|
}
|
||||||
CPUCoreBase* InitJitCore(PowerPC::CPUCore core)
|
|
||||||
|
void JitInterface::DoState(PointerWrap& p)
|
||||||
|
{
|
||||||
|
if (m_jit && p.IsReadMode())
|
||||||
|
m_jit->ClearCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
CPUCoreBase* JitInterface::InitJitCore(PowerPC::CPUCore core)
|
||||||
{
|
{
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
|
|
||||||
@ -60,42 +65,42 @@ CPUCoreBase* InitJitCore(PowerPC::CPUCore core)
|
|||||||
{
|
{
|
||||||
#if _M_X86
|
#if _M_X86
|
||||||
case PowerPC::CPUCore::JIT64:
|
case PowerPC::CPUCore::JIT64:
|
||||||
g_jit = new Jit64(system);
|
m_jit = new Jit64(system);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if _M_ARM_64
|
#if _M_ARM_64
|
||||||
case PowerPC::CPUCore::JITARM64:
|
case PowerPC::CPUCore::JITARM64:
|
||||||
g_jit = new JitArm64(system);
|
m_jit = new JitArm64(system);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case PowerPC::CPUCore::CachedInterpreter:
|
case PowerPC::CPUCore::CachedInterpreter:
|
||||||
g_jit = new CachedInterpreter(system);
|
m_jit = new CachedInterpreter(system);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Under this case the caller overrides the CPU core to the default and logs that
|
// Under this case the caller overrides the CPU core to the default and logs that
|
||||||
// it performed the override.
|
// it performed the override.
|
||||||
g_jit = nullptr;
|
m_jit = nullptr;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
g_jit->Init();
|
m_jit->Init();
|
||||||
return g_jit;
|
return m_jit;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPUCoreBase* GetCore()
|
CPUCoreBase* JitInterface::GetCore() const
|
||||||
{
|
{
|
||||||
return g_jit;
|
return m_jit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetProfilingState(ProfilingState state)
|
void JitInterface::SetProfilingState(ProfilingState state)
|
||||||
{
|
{
|
||||||
if (!g_jit)
|
if (!m_jit)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_jit->jo.profile_blocks = state == ProfilingState::Enabled;
|
m_jit->jo.profile_blocks = state == ProfilingState::Enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteProfileResults(const std::string& filename)
|
void JitInterface::WriteProfileResults(const std::string& filename) const
|
||||||
{
|
{
|
||||||
Profiler::ProfileStats prof_stats;
|
Profiler::ProfileStats prof_stats;
|
||||||
GetProfileResults(&prof_stats);
|
GetProfileResults(&prof_stats);
|
||||||
@ -122,19 +127,19 @@ void WriteProfileResults(const std::string& filename)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetProfileResults(Profiler::ProfileStats* prof_stats)
|
void JitInterface::GetProfileResults(Profiler::ProfileStats* prof_stats) const
|
||||||
{
|
{
|
||||||
// Can't really do this with no g_jit core available
|
// Can't really do this with no m_jit core available
|
||||||
if (!g_jit)
|
if (!m_jit)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
prof_stats->cost_sum = 0;
|
prof_stats->cost_sum = 0;
|
||||||
prof_stats->timecost_sum = 0;
|
prof_stats->timecost_sum = 0;
|
||||||
prof_stats->block_stats.clear();
|
prof_stats->block_stats.clear();
|
||||||
|
|
||||||
Core::RunAsCPUThread([&prof_stats] {
|
Core::RunAsCPUThread([this, &prof_stats] {
|
||||||
QueryPerformanceFrequency((LARGE_INTEGER*)&prof_stats->countsPerSec);
|
QueryPerformanceFrequency((LARGE_INTEGER*)&prof_stats->countsPerSec);
|
||||||
g_jit->GetBlockCache()->RunOnBlocks([&prof_stats](const JitBlock& block) {
|
m_jit->GetBlockCache()->RunOnBlocks([&prof_stats](const JitBlock& block) {
|
||||||
const auto& data = block.profile_data;
|
const auto& data = block.profile_data;
|
||||||
u64 cost = data.downcountCounter;
|
u64 cost = data.downcountCounter;
|
||||||
u64 timecost = data.ticCounter;
|
u64 timecost = data.ticCounter;
|
||||||
@ -150,20 +155,21 @@ void GetProfileResults(Profiler::ProfileStats* prof_stats)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::variant<GetHostCodeError, GetHostCodeResult> GetHostCode(u32 address)
|
std::variant<JitInterface::GetHostCodeError, JitInterface::GetHostCodeResult>
|
||||||
|
JitInterface::GetHostCode(u32 address) const
|
||||||
{
|
{
|
||||||
if (!g_jit)
|
if (!m_jit)
|
||||||
{
|
{
|
||||||
return GetHostCodeError::NoJitActive;
|
return GetHostCodeError::NoJitActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
JitBlock* block =
|
JitBlock* block =
|
||||||
g_jit->GetBlockCache()->GetBlockFromStartAddress(address, PowerPC::ppcState.msr.Hex);
|
m_jit->GetBlockCache()->GetBlockFromStartAddress(address, PowerPC::ppcState.msr.Hex);
|
||||||
if (!block)
|
if (!block)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 500; i++)
|
for (int i = 0; i < 500; i++)
|
||||||
{
|
{
|
||||||
block = g_jit->GetBlockCache()->GetBlockFromStartAddress(address - 4 * i,
|
block = m_jit->GetBlockCache()->GetBlockFromStartAddress(address - 4 * i,
|
||||||
PowerPC::ppcState.msr.Hex);
|
PowerPC::ppcState.msr.Hex);
|
||||||
if (block)
|
if (block)
|
||||||
break;
|
break;
|
||||||
@ -190,51 +196,52 @@ std::variant<GetHostCodeError, GetHostCodeResult> GetHostCode(u32 address)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HandleFault(uintptr_t access_address, SContext* ctx)
|
bool JitInterface::HandleFault(uintptr_t access_address, SContext* ctx)
|
||||||
{
|
{
|
||||||
// Prevent nullptr dereference on a crash with no JIT present
|
// Prevent nullptr dereference on a crash with no JIT present
|
||||||
if (!g_jit)
|
if (!m_jit)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return g_jit->HandleFault(access_address, ctx);
|
return m_jit->HandleFault(access_address, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HandleStackFault()
|
bool JitInterface::HandleStackFault()
|
||||||
{
|
{
|
||||||
if (!g_jit)
|
if (!m_jit)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return g_jit->HandleStackFault();
|
return m_jit->HandleStackFault();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClearCache()
|
void JitInterface::ClearCache()
|
||||||
{
|
{
|
||||||
if (g_jit)
|
if (m_jit)
|
||||||
g_jit->ClearCache();
|
m_jit->ClearCache();
|
||||||
}
|
|
||||||
void ClearSafe()
|
|
||||||
{
|
|
||||||
if (g_jit)
|
|
||||||
g_jit->GetBlockCache()->Clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InvalidateICache(u32 address, u32 size, bool forced)
|
void JitInterface::ClearSafe()
|
||||||
{
|
{
|
||||||
if (g_jit)
|
if (m_jit)
|
||||||
g_jit->GetBlockCache()->InvalidateICache(address, size, forced);
|
m_jit->GetBlockCache()->Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InvalidateICacheLine(u32 address)
|
void JitInterface::InvalidateICache(u32 address, u32 size, bool forced)
|
||||||
{
|
{
|
||||||
if (g_jit)
|
if (m_jit)
|
||||||
g_jit->GetBlockCache()->InvalidateICacheLine(address);
|
m_jit->GetBlockCache()->InvalidateICache(address, size, forced);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InvalidateICacheLines(u32 address, u32 count)
|
void JitInterface::InvalidateICacheLine(u32 address)
|
||||||
|
{
|
||||||
|
if (m_jit)
|
||||||
|
m_jit->GetBlockCache()->InvalidateICacheLine(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JitInterface::InvalidateICacheLines(u32 address, u32 count)
|
||||||
{
|
{
|
||||||
// This corresponds to a PPC code loop that:
|
// This corresponds to a PPC code loop that:
|
||||||
// - calls some form of dcb* instruction on 'address'
|
// - calls some form of dcb* instruction on 'address'
|
||||||
@ -250,9 +257,19 @@ void InvalidateICacheLines(u32 address, u32 count)
|
|||||||
InvalidateICache(address & ~0x1f, 32 * count, false);
|
InvalidateICache(address & ~0x1f, 32 * count, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompileExceptionCheck(ExceptionType type)
|
void JitInterface::InvalidateICacheLineFromJIT(u32 address, u32 dummy, JitInterface& jit_interface)
|
||||||
{
|
{
|
||||||
if (!g_jit)
|
jit_interface.InvalidateICacheLine(address);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JitInterface::InvalidateICacheLinesFromJIT(u32 address, u32 count, JitInterface& jit_interface)
|
||||||
|
{
|
||||||
|
jit_interface.InvalidateICacheLines(address, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JitInterface::CompileExceptionCheck(ExceptionType type)
|
||||||
|
{
|
||||||
|
if (!m_jit)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::unordered_set<u32>* exception_addresses = nullptr;
|
std::unordered_set<u32>* exception_addresses = nullptr;
|
||||||
@ -260,13 +277,13 @@ void CompileExceptionCheck(ExceptionType type)
|
|||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case ExceptionType::FIFOWrite:
|
case ExceptionType::FIFOWrite:
|
||||||
exception_addresses = &g_jit->js.fifoWriteAddresses;
|
exception_addresses = &m_jit->js.fifoWriteAddresses;
|
||||||
break;
|
break;
|
||||||
case ExceptionType::PairedQuantize:
|
case ExceptionType::PairedQuantize:
|
||||||
exception_addresses = &g_jit->js.pairedQuantizeAddresses;
|
exception_addresses = &m_jit->js.pairedQuantizeAddresses;
|
||||||
break;
|
break;
|
||||||
case ExceptionType::SpeculativeConstants:
|
case ExceptionType::SpeculativeConstants:
|
||||||
exception_addresses = &g_jit->js.noSpeculativeConstantsAddresses;
|
exception_addresses = &m_jit->js.noSpeculativeConstantsAddresses;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,17 +305,21 @@ void CompileExceptionCheck(ExceptionType type)
|
|||||||
|
|
||||||
// Invalidate the JIT block so that it gets recompiled with the external exception check
|
// Invalidate the JIT block so that it gets recompiled with the external exception check
|
||||||
// included.
|
// included.
|
||||||
g_jit->GetBlockCache()->InvalidateICache(PowerPC::ppcState.pc, 4, true);
|
m_jit->GetBlockCache()->InvalidateICache(PowerPC::ppcState.pc, 4, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shutdown()
|
void JitInterface::CompileExceptionCheckFromJIT(JitInterface& jit_interface, ExceptionType type)
|
||||||
{
|
{
|
||||||
if (g_jit)
|
jit_interface.CompileExceptionCheck(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
void JitInterface::Shutdown()
|
||||||
{
|
{
|
||||||
g_jit->Shutdown();
|
if (m_jit)
|
||||||
delete g_jit;
|
{
|
||||||
g_jit = nullptr;
|
m_jit->Shutdown();
|
||||||
|
delete m_jit;
|
||||||
|
m_jit = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace JitInterface
|
|
||||||
|
@ -13,6 +13,10 @@ class CPUCoreBase;
|
|||||||
class PointerWrap;
|
class PointerWrap;
|
||||||
class JitBase;
|
class JitBase;
|
||||||
|
|
||||||
|
namespace Core
|
||||||
|
{
|
||||||
|
class System;
|
||||||
|
}
|
||||||
namespace PowerPC
|
namespace PowerPC
|
||||||
{
|
{
|
||||||
enum class CPUCore;
|
enum class CPUCore;
|
||||||
@ -23,19 +27,20 @@ namespace Profiler
|
|||||||
struct ProfileStats;
|
struct ProfileStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace JitInterface
|
class JitInterface
|
||||||
{
|
{
|
||||||
enum class ExceptionType
|
public:
|
||||||
{
|
explicit JitInterface(Core::System& system);
|
||||||
FIFOWrite,
|
JitInterface(const JitInterface&) = delete;
|
||||||
PairedQuantize,
|
JitInterface(JitInterface&&) = delete;
|
||||||
SpeculativeConstants
|
JitInterface& operator=(const JitInterface&) = delete;
|
||||||
};
|
JitInterface& operator=(JitInterface&&) = delete;
|
||||||
|
~JitInterface();
|
||||||
|
|
||||||
void DoState(PointerWrap& p);
|
void DoState(PointerWrap& p);
|
||||||
|
|
||||||
CPUCoreBase* InitJitCore(PowerPC::CPUCore core);
|
CPUCoreBase* InitJitCore(PowerPC::CPUCore core);
|
||||||
CPUCoreBase* GetCore();
|
CPUCoreBase* GetCore() const;
|
||||||
|
|
||||||
// Debugging
|
// Debugging
|
||||||
enum class ProfilingState
|
enum class ProfilingState
|
||||||
@ -43,7 +48,6 @@ enum class ProfilingState
|
|||||||
Enabled,
|
Enabled,
|
||||||
Disabled
|
Disabled
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class GetHostCodeError
|
enum class GetHostCodeError
|
||||||
{
|
{
|
||||||
NoJitActive,
|
NoJitActive,
|
||||||
@ -57,9 +61,9 @@ struct GetHostCodeResult
|
|||||||
};
|
};
|
||||||
|
|
||||||
void SetProfilingState(ProfilingState state);
|
void SetProfilingState(ProfilingState state);
|
||||||
void WriteProfileResults(const std::string& filename);
|
void WriteProfileResults(const std::string& filename) const;
|
||||||
void GetProfileResults(Profiler::ProfileStats* prof_stats);
|
void GetProfileResults(Profiler::ProfileStats* prof_stats) const;
|
||||||
std::variant<GetHostCodeError, GetHostCodeResult> GetHostCode(u32 address);
|
std::variant<GetHostCodeError, GetHostCodeResult> GetHostCode(u32 address) const;
|
||||||
|
|
||||||
// Memory Utilities
|
// Memory Utilities
|
||||||
bool HandleFault(uintptr_t access_address, SContext* ctx);
|
bool HandleFault(uintptr_t access_address, SContext* ctx);
|
||||||
@ -77,11 +81,24 @@ void ClearSafe();
|
|||||||
void InvalidateICache(u32 address, u32 size, bool forced);
|
void InvalidateICache(u32 address, u32 size, bool forced);
|
||||||
void InvalidateICacheLine(u32 address);
|
void InvalidateICacheLine(u32 address);
|
||||||
void InvalidateICacheLines(u32 address, u32 count);
|
void InvalidateICacheLines(u32 address, u32 count);
|
||||||
|
static void InvalidateICacheLineFromJIT(u32 address, u32 dummy, JitInterface& jit_interface);
|
||||||
|
static void InvalidateICacheLinesFromJIT(u32 address, u32 count, JitInterface& jit_interface);
|
||||||
|
|
||||||
|
enum class ExceptionType
|
||||||
|
{
|
||||||
|
FIFOWrite,
|
||||||
|
PairedQuantize,
|
||||||
|
SpeculativeConstants
|
||||||
|
};
|
||||||
void CompileExceptionCheck(ExceptionType type);
|
void CompileExceptionCheck(ExceptionType type);
|
||||||
|
static void CompileExceptionCheckFromJIT(JitInterface& jit_interface, ExceptionType type);
|
||||||
|
|
||||||
/// used for the page fault unit test, don't use outside of tests!
|
/// used for the page fault unit test, don't use outside of tests!
|
||||||
void SetJit(JitBase* jit);
|
void SetJit(JitBase* jit);
|
||||||
|
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
} // namespace JitInterface
|
|
||||||
|
private:
|
||||||
|
JitBase* m_jit = nullptr;
|
||||||
|
Core::System& m_system;
|
||||||
|
};
|
||||||
|
@ -1770,7 +1770,7 @@ void DBATUpdated()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// IsOptimizable*Address and dcbz depends on the BAT mapping, so we need a flush here.
|
// IsOptimizable*Address and dcbz depends on the BAT mapping, so we need a flush here.
|
||||||
JitInterface::ClearSafe();
|
system.GetJitInterface().ClearSafe();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IBATUpdated()
|
void IBATUpdated()
|
||||||
@ -1789,7 +1789,7 @@ void IBATUpdated()
|
|||||||
UpdateFakeMMUBat(ibat_table, 0x40000000);
|
UpdateFakeMMUBat(ibat_table, 0x40000000);
|
||||||
UpdateFakeMMUBat(ibat_table, 0x70000000);
|
UpdateFakeMMUBat(ibat_table, 0x70000000);
|
||||||
}
|
}
|
||||||
JitInterface::ClearSafe();
|
system.GetJitInterface().ClearSafe();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translate effective address using BAT or PAT. Returns 0 if the address cannot be translated.
|
// Translate effective address using BAT or PAT. Returns 0 if the address cannot be translated.
|
||||||
|
@ -107,7 +107,7 @@ void Cache::Reset()
|
|||||||
void InstructionCache::Reset()
|
void InstructionCache::Reset()
|
||||||
{
|
{
|
||||||
Cache::Reset();
|
Cache::Reset();
|
||||||
JitInterface::ClearSafe();
|
Core::System::GetInstance().GetJitInterface().ClearSafe();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cache::Init()
|
void Cache::Init()
|
||||||
@ -424,7 +424,7 @@ void InstructionCache::Invalidate(u32 addr)
|
|||||||
valid[set] = 0;
|
valid[set] = 0;
|
||||||
modified[set] = 0;
|
modified[set] = 0;
|
||||||
|
|
||||||
JitInterface::InvalidateICacheLine(addr);
|
Core::System::GetInstance().GetJitInterface().InvalidateICacheLine(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstructionCache::RefreshConfig()
|
void InstructionCache::RefreshConfig()
|
||||||
|
@ -153,7 +153,7 @@ void DoState(PointerWrap& p)
|
|||||||
// SystemTimers::DecrementerSet();
|
// SystemTimers::DecrementerSet();
|
||||||
// SystemTimers::TimeBaseSet();
|
// SystemTimers::TimeBaseSet();
|
||||||
|
|
||||||
JitInterface::DoState(p);
|
Core::System::GetInstance().GetJitInterface().DoState(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ResetRegisters()
|
static void ResetRegisters()
|
||||||
@ -219,7 +219,8 @@ static void InitializeCPUCore(CPUCore cpu_core)
|
|||||||
{
|
{
|
||||||
// We initialize the interpreter because
|
// We initialize the interpreter because
|
||||||
// it is used on boot and code window independently.
|
// it is used on boot and code window independently.
|
||||||
auto& interpreter = Core::System::GetInstance().GetInterpreter();
|
auto& system = Core::System::GetInstance();
|
||||||
|
auto& interpreter = system.GetInterpreter();
|
||||||
interpreter.Init();
|
interpreter.Init();
|
||||||
|
|
||||||
switch (cpu_core)
|
switch (cpu_core)
|
||||||
@ -229,12 +230,12 @@ static void InitializeCPUCore(CPUCore cpu_core)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
s_cpu_core_base = JitInterface::InitJitCore(cpu_core);
|
s_cpu_core_base = system.GetJitInterface().InitJitCore(cpu_core);
|
||||||
if (!s_cpu_core_base) // Handle Situations where JIT core isn't available
|
if (!s_cpu_core_base) // Handle Situations where JIT core isn't available
|
||||||
{
|
{
|
||||||
WARN_LOG_FMT(POWERPC, "CPU core {} not available. Falling back to default.",
|
WARN_LOG_FMT(POWERPC, "CPU core {} not available. Falling back to default.",
|
||||||
static_cast<int>(cpu_core));
|
static_cast<int>(cpu_core));
|
||||||
s_cpu_core_base = JitInterface::InitJitCore(DefaultCPUCore());
|
s_cpu_core_base = system.GetJitInterface().InitJitCore(DefaultCPUCore());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -315,8 +316,9 @@ void ScheduleInvalidateCacheThreadSafe(u32 address)
|
|||||||
void Shutdown()
|
void Shutdown()
|
||||||
{
|
{
|
||||||
InjectExternalCPUCore(nullptr);
|
InjectExternalCPUCore(nullptr);
|
||||||
JitInterface::Shutdown();
|
auto& system = Core::System::GetInstance();
|
||||||
auto& interpreter = Core::System::GetInstance().GetInterpreter();
|
system.GetJitInterface().Shutdown();
|
||||||
|
auto& interpreter = system.GetInterpreter();
|
||||||
interpreter.Shutdown();
|
interpreter.Shutdown();
|
||||||
s_cpu_core_base = nullptr;
|
s_cpu_core_base = nullptr;
|
||||||
}
|
}
|
||||||
@ -328,7 +330,8 @@ CoreMode GetMode()
|
|||||||
|
|
||||||
static void ApplyMode()
|
static void ApplyMode()
|
||||||
{
|
{
|
||||||
auto& interpreter = Core::System::GetInstance().GetInterpreter();
|
auto& system = Core::System::GetInstance();
|
||||||
|
auto& interpreter = system.GetInterpreter();
|
||||||
|
|
||||||
switch (s_mode)
|
switch (s_mode)
|
||||||
{
|
{
|
||||||
@ -338,7 +341,7 @@ static void ApplyMode()
|
|||||||
|
|
||||||
case CoreMode::JIT: // Switching from interpreter to JIT.
|
case CoreMode::JIT: // Switching from interpreter to JIT.
|
||||||
// Don't really need to do much. It'll work, the cache will refill itself.
|
// Don't really need to do much. It'll work, the cache will refill itself.
|
||||||
s_cpu_core_base = JitInterface::GetCore();
|
s_cpu_core_base = system.GetJitInterface().GetCore();
|
||||||
if (!s_cpu_core_base) // Has a chance to not get a working JIT core if one isn't active on host
|
if (!s_cpu_core_base) // Has a chance to not get a working JIT core if one isn't active on host
|
||||||
s_cpu_core_base = &interpreter;
|
s_cpu_core_base = &interpreter;
|
||||||
break;
|
break;
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "Core/HW/Sram.h"
|
#include "Core/HW/Sram.h"
|
||||||
#include "Core/HW/VideoInterface.h"
|
#include "Core/HW/VideoInterface.h"
|
||||||
#include "Core/PowerPC/Interpreter/Interpreter.h"
|
#include "Core/PowerPC/Interpreter/Interpreter.h"
|
||||||
|
#include "Core/PowerPC/JitInterface.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
#include "IOS/USB/Emulated/Skylander.h"
|
#include "IOS/USB/Emulated/Skylander.h"
|
||||||
#include "VideoCommon/CommandProcessor.h"
|
#include "VideoCommon/CommandProcessor.h"
|
||||||
@ -40,7 +41,7 @@ struct System::Impl
|
|||||||
: m_audio_interface(system), m_core_timing(system), m_dsp(system), m_dvd_interface(system),
|
: m_audio_interface(system), m_core_timing(system), m_dsp(system), m_dvd_interface(system),
|
||||||
m_dvd_thread(system), m_expansion_interface(system), m_gp_fifo(system), m_memory(system),
|
m_dvd_thread(system), m_expansion_interface(system), m_gp_fifo(system), m_memory(system),
|
||||||
m_ppc_state(PowerPC::ppcState), m_processor_interface(system), m_serial_interface(system),
|
m_ppc_state(PowerPC::ppcState), m_processor_interface(system), m_serial_interface(system),
|
||||||
m_video_interface(system), m_interpreter(system, m_ppc_state)
|
m_video_interface(system), m_interpreter(system, m_ppc_state), m_jit_interface(system)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,6 +73,7 @@ struct System::Impl
|
|||||||
VertexShaderManager m_vertex_shader_manager;
|
VertexShaderManager m_vertex_shader_manager;
|
||||||
VideoInterface::VideoInterfaceManager m_video_interface;
|
VideoInterface::VideoInterfaceManager m_video_interface;
|
||||||
Interpreter m_interpreter;
|
Interpreter m_interpreter;
|
||||||
|
JitInterface m_jit_interface;
|
||||||
};
|
};
|
||||||
|
|
||||||
System::System() : m_impl{std::make_unique<Impl>(*this)}
|
System::System() : m_impl{std::make_unique<Impl>(*this)}
|
||||||
@ -182,6 +184,11 @@ Interpreter& System::GetInterpreter() const
|
|||||||
return m_impl->m_interpreter;
|
return m_impl->m_interpreter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JitInterface& System::GetJitInterface() const
|
||||||
|
{
|
||||||
|
return m_impl->m_jit_interface;
|
||||||
|
}
|
||||||
|
|
||||||
IOS::HLE::USB::SkylanderPortal& System::GetSkylanderPortal() const
|
IOS::HLE::USB::SkylanderPortal& System::GetSkylanderPortal() const
|
||||||
{
|
{
|
||||||
return m_impl->m_skylander_portal;
|
return m_impl->m_skylander_portal;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
class GeometryShaderManager;
|
class GeometryShaderManager;
|
||||||
class Interpreter;
|
class Interpreter;
|
||||||
|
class JitInterface;
|
||||||
class PixelShaderManager;
|
class PixelShaderManager;
|
||||||
class SoundStream;
|
class SoundStream;
|
||||||
struct Sram;
|
struct Sram;
|
||||||
@ -133,6 +134,7 @@ public:
|
|||||||
GPFifo::GPFifoManager& GetGPFifo() const;
|
GPFifo::GPFifoManager& GetGPFifo() const;
|
||||||
HSP::HSPManager& GetHSP() const;
|
HSP::HSPManager& GetHSP() const;
|
||||||
Interpreter& GetInterpreter() const;
|
Interpreter& GetInterpreter() const;
|
||||||
|
JitInterface& GetJitInterface() const;
|
||||||
IOS::HLE::USB::SkylanderPortal& GetSkylanderPortal() const;
|
IOS::HLE::USB::SkylanderPortal& GetSkylanderPortal() const;
|
||||||
Memory::MemoryManager& GetMemory() const;
|
Memory::MemoryManager& GetMemory() const;
|
||||||
MemoryInterface::MemoryInterfaceManager& GetMemoryInterface() const;
|
MemoryInterface::MemoryInterfaceManager& GetMemoryInterface() const;
|
||||||
|
@ -140,7 +140,8 @@ void CodeDiffDialog::ClearData()
|
|||||||
// Swap is used instead of clear for efficiency in the case of huge m_include/m_exclude
|
// Swap is used instead of clear for efficiency in the case of huge m_include/m_exclude
|
||||||
std::vector<Diff>().swap(m_include);
|
std::vector<Diff>().swap(m_include);
|
||||||
std::vector<Diff>().swap(m_exclude);
|
std::vector<Diff>().swap(m_exclude);
|
||||||
JitInterface::SetProfilingState(JitInterface::ProfilingState::Disabled);
|
Core::System::GetInstance().GetJitInterface().SetProfilingState(
|
||||||
|
JitInterface::ProfilingState::Disabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeDiffDialog::ClearBlockCache()
|
void CodeDiffDialog::ClearBlockCache()
|
||||||
@ -150,7 +151,7 @@ void CodeDiffDialog::ClearBlockCache()
|
|||||||
if (old_state == Core::State::Running)
|
if (old_state == Core::State::Running)
|
||||||
Core::SetState(Core::State::Paused);
|
Core::SetState(Core::State::Paused);
|
||||||
|
|
||||||
JitInterface::ClearCache();
|
Core::System::GetInstance().GetJitInterface().ClearCache();
|
||||||
|
|
||||||
if (old_state == Core::State::Running)
|
if (old_state == Core::State::Running)
|
||||||
Core::SetState(Core::State::Running);
|
Core::SetState(Core::State::Running);
|
||||||
@ -205,7 +206,7 @@ void CodeDiffDialog::OnRecord(bool enabled)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_record_btn->update();
|
m_record_btn->update();
|
||||||
JitInterface::SetProfilingState(state);
|
Core::System::GetInstance().GetJitInterface().SetProfilingState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeDiffDialog::OnInclude()
|
void CodeDiffDialog::OnInclude()
|
||||||
@ -271,7 +272,7 @@ std::vector<Diff> CodeDiffDialog::CalculateSymbolsFromProfile()
|
|||||||
{
|
{
|
||||||
Profiler::ProfileStats prof_stats;
|
Profiler::ProfileStats prof_stats;
|
||||||
auto& blockstats = prof_stats.block_stats;
|
auto& blockstats = prof_stats.block_stats;
|
||||||
JitInterface::GetProfileResults(&prof_stats);
|
Core::System::GetInstance().GetJitInterface().GetProfileResults(&prof_stats);
|
||||||
std::vector<Diff> current;
|
std::vector<Diff> current;
|
||||||
current.reserve(20000);
|
current.reserve(20000);
|
||||||
|
|
||||||
@ -391,7 +392,7 @@ void CodeDiffDialog::Update(bool include)
|
|||||||
m_exclude_size_label->setText(tr("Excluded: %1").arg(m_exclude.size()));
|
m_exclude_size_label->setText(tr("Excluded: %1").arg(m_exclude.size()));
|
||||||
m_include_size_label->setText(tr("Included: %1").arg(m_include.size()));
|
m_include_size_label->setText(tr("Included: %1").arg(m_include.size()));
|
||||||
|
|
||||||
JitInterface::ClearCache();
|
Core::System::GetInstance().GetJitInterface().ClearCache();
|
||||||
if (old_state == Core::State::Running)
|
if (old_state == Core::State::Running)
|
||||||
Core::SetState(Core::State::Running);
|
Core::SetState(Core::State::Running);
|
||||||
}
|
}
|
||||||
|
@ -1671,7 +1671,7 @@ void MenuBar::PatchHLEFunctions()
|
|||||||
|
|
||||||
void MenuBar::ClearCache()
|
void MenuBar::ClearCache()
|
||||||
{
|
{
|
||||||
Core::RunAsCPUThread(JitInterface::ClearCache);
|
Core::RunAsCPUThread([] { Core::System::GetInstance().GetJitInterface().ClearCache(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuBar::LogInstructions()
|
void MenuBar::LogInstructions()
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "Common/Assert.h"
|
#include "Common/Assert.h"
|
||||||
#include "Common/VariantUtil.h"
|
#include "Common/VariantUtil.h"
|
||||||
#include "Core/PowerPC/JitInterface.h"
|
#include "Core/PowerPC/JitInterface.h"
|
||||||
|
#include "Core/System.h"
|
||||||
|
|
||||||
#if defined(HAVE_LLVM)
|
#if defined(HAVE_LLVM)
|
||||||
class HostDisassemblerLLVM : public HostDisassembler
|
class HostDisassemblerLLVM : public HostDisassembler
|
||||||
@ -170,7 +171,7 @@ std::unique_ptr<HostDisassembler> GetNewDisassembler(const std::string& arch)
|
|||||||
|
|
||||||
DisassembleResult DisassembleBlock(HostDisassembler* disasm, u32 address)
|
DisassembleResult DisassembleBlock(HostDisassembler* disasm, u32 address)
|
||||||
{
|
{
|
||||||
auto res = JitInterface::GetHostCode(address);
|
auto res = Core::System::GetInstance().GetJitInterface().GetHostCode(address);
|
||||||
|
|
||||||
return std::visit(overloaded{[&](JitInterface::GetHostCodeError error) {
|
return std::visit(overloaded{[&](JitInterface::GetHostCodeError error) {
|
||||||
DisassembleResult result;
|
DisassembleResult result;
|
||||||
|
@ -76,7 +76,7 @@ TEST(PageFault, PageFault)
|
|||||||
Common::WriteProtectMemory(data, PAGE_GRAN, false);
|
Common::WriteProtectMemory(data, PAGE_GRAN, false);
|
||||||
|
|
||||||
PageFaultFakeJit pfjit(Core::System::GetInstance());
|
PageFaultFakeJit pfjit(Core::System::GetInstance());
|
||||||
JitInterface::SetJit(&pfjit);
|
Core::System::GetInstance().GetJitInterface().SetJit(&pfjit);
|
||||||
pfjit.m_data = data;
|
pfjit.m_data = data;
|
||||||
|
|
||||||
auto start = std::chrono::high_resolution_clock::now();
|
auto start = std::chrono::high_resolution_clock::now();
|
||||||
@ -88,7 +88,7 @@ TEST(PageFault, PageFault)
|
|||||||
};
|
};
|
||||||
|
|
||||||
EMM::UninstallExceptionHandler();
|
EMM::UninstallExceptionHandler();
|
||||||
JitInterface::SetJit(nullptr);
|
Core::System::GetInstance().GetJitInterface().SetJit(nullptr);
|
||||||
|
|
||||||
fmt::print("page fault timing:\n");
|
fmt::print("page fault timing:\n");
|
||||||
fmt::print("start->HandleFault {} ns\n",
|
fmt::print("start->HandleFault {} ns\n",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user