CPU: Let each MIPSState own its JIT

The global MIPSComp::jit becomes MIPSState::jit, created and deleted by the
state it runs. JitAt() compiles with the JIT of the state it's handed, so
the dispatchers no longer go through a global. Code that is about the main
CPU by nature (the UI, the crash handler, the disassembler's symbol lookup,
the JIT harness) uses mipsr4k.jit.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-20 09:52:17 +02:00
1 parent 5a9cbf007c
commit a3c4ef8e06
15 files changed
+103 -102

No files matched your search

+2 -2
View File
@@ -1453,9 +1453,9 @@ void __KernelLoadContext(const PSPThreadContext *ctx, bool vfpuEnabled) {
memcpy(currentMIPS->other, ctx->other, sizeof(ctx->other));
// Not locking here, we assume the jit isn't switched during execution.
if (MIPSComp::jit) {
if (currentMIPS->jit) {
// When thread switching, we must update the rounding mode if cached in the jit.
MIPSComp::jit->UpdateFCR31();
currentMIPS->jit->UpdateFCR31();
}
// Reset the llBit, the other thread may have touched memory.
+3 -3
View File
@@ -198,7 +198,7 @@ namespace MIPSInt {
int size = 0x40 + (addr & 0x3F);
// Through MIPSState, which also drops replacement hooks in functions the game changed.
mips->InvalidateICacheRangeImmediate(alignedAddr, size);
if (MIPSComp::jit) {
if (mips->jit) {
// Using a bool to avoid locking/etc. in case it's slow.
if (!loggedAlignment && (addr & 0x3F) != 0) {
// These are seen exclusively in Lego games, and are really no big deal. Reporting removed.
@@ -745,9 +745,9 @@ namespace MIPSInt {
mips->fcr31 = value & 0x0181FFFF;
mips->fpcond = (value >> 23) & 1;
// Don't bother locking, assuming the CPU can't be reset now anyway.
if (MIPSComp::jit) {
if (mips->jit) {
// In case of DISABLE, we need to tell jit we updated FCR31.
MIPSComp::jit->UpdateFCR31();
mips->jit->UpdateFCR31();
} else {
// The interpreter emulates the rounding mode by putting the host FPU in it,
// so it has to switch right here rather than at the next block boundary.
+6 -8
View File
@@ -51,15 +51,13 @@
#endif
namespace MIPSComp {
JitInterface *jit;
void JitAt(MIPSState *mips) {
// TODO: We could probably check for a bad pc here, and fire an exception. Could spare us from some crashes.
// Although, we just tried to load from this address to check for a JIT block, and if we're here, that succeeded..
jit->Compile(mips->pc);
mips->jit->Compile(mips->pc);
}
void DoDummyJitState(PointerWrap &p) {
void DoDummyJitState(PointerWrap &p, const MIPSState *mips) {
// This is here so the savestate matches between jit and non-jit.
auto s = p.Section("Jit", 1, 2);
if (!s)
@@ -67,7 +65,7 @@ namespace MIPSComp {
// This is startDefaultPrefix. Writing false made a JIT loading the state assume an uneaten
// prefix for the rest of the session.
bool dummy = currentMIPS->HasDefaultPrefix();
bool dummy = mips->HasDefaultPrefix();
Do(p, dummy);
if (s >= 2) {
dummy = true;
@@ -176,9 +174,9 @@ std::string AddAddress(const std::string &buf, uint64_t addr) {
#if PPSSPP_ARCH(ARM64) || defined(DISASM_ALL)
static bool Arm64SymbolCallback(char *buffer, int bufsize, uint8_t *address) {
if (MIPSComp::jit) {
if (mipsr4k.jit) {
std::string name;
if (MIPSComp::jit->DescribeCodePtr(address, name)) {
if (mipsr4k.jit->DescribeCodePtr(address, name)) {
truncate_cpy(buffer, bufsize, name);
return true;
}
@@ -269,7 +267,7 @@ const char *ppsspp_resolver(struct ud*,
static char buf[128];
std::string str;
if (MIPSComp::jit && MIPSComp::jit->DescribeCodePtr((u8 *)(uintptr_t)addr, str)) {
if (mipsr4k.jit && mipsr4k.jit->DescribeCodePtr((u8 *)(uintptr_t)addr, str)) {
*offset = 0;
truncate_cpy(buf, sizeof(buf), str);
return buf;
+1 -3
View File
@@ -182,9 +182,7 @@ namespace MIPSComp {
// This seems to be the same for all branch types.
u32 ResolveNotTakenTarget(const BranchInfo &branchInfo);
extern JitInterface *jit;
void DoDummyJitState(PointerWrap &p);
void DoDummyJitState(PointerWrap &p, const MIPSState *mips);
JitInterface *CreateNativeJit(MIPSState *mipsState);
}
+30 -32
View File
@@ -232,8 +232,6 @@ const float cst_constants[32] = {
};
MIPSState::MIPSState() {
MIPSComp::jit = nullptr;
// Initialize vorder
// This reordering of the VFPU registers in RAM means that instead of being like this:
@@ -304,18 +302,18 @@ MIPSState::~MIPSState() {
}
// The block shadow's replacement hook entries have to match the JIT's dispatcher.
static void UpdateBlockShadowHook() {
Replacement_SetBlockShadowHook(MIPSComp::jit ? MIPSComp::jit->GetBlockShadowHookValue() : Memory::BLOCK_SHADOW_HOOK_NO_JIT);
static void UpdateBlockShadowHook(const MIPSComp::JitInterface *jit) {
Replacement_SetBlockShadowHook(jit ? jit->GetBlockShadowHookValue() : Memory::BLOCK_SHADOW_HOOK_NO_JIT);
}
void MIPSState::Shutdown() {
MIPSComp::JitInterface *oldjit = MIPSComp::jit;
MIPSComp::JitInterface *oldjit = jit;
if (oldjit) {
oldjit->FlushProfile();
MIPSComp::jit = nullptr;
jit = nullptr;
delete oldjit;
}
UpdateBlockShadowHook();
UpdateBlockShadowHook(jit);
pendingInvalidates_.clear();
invalidateAll_ = false;
}
@@ -328,13 +326,13 @@ void MIPSState::Reset() {
void MIPSState::Init() {
InitRegisters();
if (PSP_CoreParameter().cpuCore == CPUCore::JIT || PSP_CoreParameter().cpuCore == CPUCore::JIT_IR) {
MIPSComp::jit = MIPSComp::CreateNativeJit(this);
jit = MIPSComp::CreateNativeJit(this);
} else if (PSP_CoreParameter().cpuCore == CPUCore::IR_INTERPRETER) {
MIPSComp::jit = new MIPSComp::IRJit(this, false);
jit = new MIPSComp::IRJit(this, false);
} else {
MIPSComp::jit = nullptr;
jit = nullptr;
}
UpdateBlockShadowHook();
UpdateBlockShadowHook(jit);
}
void MIPSState::InitRegisters() {
@@ -386,9 +384,9 @@ void MIPSState::UpdateCore(CPUCore desired) {
IncrementDebugCounter(DebugCounter::CPUCORE_SWITCHES);
// Get rid of the old JIT first, before switching.
if (MIPSComp::jit) {
delete MIPSComp::jit;
MIPSComp::jit = nullptr;
if (jit) {
delete jit;
jit = nullptr;
}
PSP_CoreParameter().cpuCore = desired;
@@ -416,12 +414,12 @@ void MIPSState::UpdateCore(CPUCore desired) {
break;
}
MIPSComp::jit = newjit;
jit = newjit;
if (newjit) {
// The game may already have set a rounding mode on the previous core.
newjit->UpdateFCR31();
}
UpdateBlockShadowHook();
UpdateBlockShadowHook(jit);
}
void MIPSState::DoState(PointerWrap &p) {
@@ -430,10 +428,10 @@ void MIPSState::DoState(PointerWrap &p) {
return;
if (p.mode == p.MODE_READ) {
if (MIPSComp::jit && !keepJitBlocks_.empty()) {
if (jit && !keepJitBlocks_.empty()) {
// Blocks in code the load didn't change can stay. Queued invalidations stay too.
InitRegisters();
MIPSComp::jit->InvalidateCacheExcept(keepJitBlocks_);
jit->InvalidateCacheExcept(keepJitBlocks_);
} else {
// Start the JIT over.
Reset();
@@ -441,10 +439,10 @@ void MIPSState::DoState(PointerWrap &p) {
keepJitBlocks_.clear();
}
// Assume we're not saving state during a CPU core reset, so no lock.
if (MIPSComp::jit)
MIPSComp::jit->DoState(p);
if (jit)
jit->DoState(p);
else
MIPSComp::DoDummyJitState(p);
MIPSComp::DoDummyJitState(p, this);
DoArray(p, r, sizeof(r) / sizeof(r[0]));
DoArray(p, f, sizeof(f) / sizeof(f[0]));
@@ -480,9 +478,9 @@ void MIPSState::DoState(PointerWrap &p) {
Do(p, llBit);
Do(p, debugCount);
if (p.mode == p.MODE_READ && MIPSComp::jit) {
if (p.mode == p.MODE_READ && jit) {
// Now that we've loaded fcr31, update any jit state associated.
MIPSComp::jit->UpdateFCR31();
jit->UpdateFCR31();
}
}
@@ -505,7 +503,7 @@ int MIPSState::RunLoopUntil(u64 globalTicks) {
downcount -= cycles;
}
ProcessPendingInvalidates();
MIPSComp::jit->RunLoopUntil(globalTicks);
jit->RunLoopUntil(globalTicks);
break;
case CPUCore::INTERPRETER:
@@ -517,12 +515,12 @@ int MIPSState::RunLoopUntil(u64 globalTicks) {
void MIPSState::InvalidateICacheRangeImmediate(u32 address, u32 length) {
Replacement_CheckRange(address, length);
if (!MIPSComp::jit) {
if (!jit) {
// Nothing to do.
return;
}
if (length != 0) {
MIPSComp::jit->InvalidateCacheAt(address, length);
jit->InvalidateCacheAt(address, length);
}
}
@@ -536,12 +534,12 @@ void MIPSState::ProcessPendingInvalidates() {
pending.swap(pendingInvalidates_);
for (const auto &p : pending) {
Replacement_CheckRange(p.addr, p.size);
if (MIPSComp::jit && !all) {
MIPSComp::jit->InvalidateCacheAt(p.addr, p.size);
if (jit && !all) {
jit->InvalidateCacheAt(p.addr, p.size);
}
}
if (MIPSComp::jit && all) {
MIPSComp::jit->ClearCache();
if (jit && all) {
jit->ClearCache();
}
}
}
@@ -549,14 +547,14 @@ void MIPSState::ProcessPendingInvalidates() {
void MIPSState::InvalidateICacheRangeDeferred(u32 address, u32 length) {
// TODO: We can try to merge the invalidate with the previous one.
pendingInvalidates_.push_back(PendingCacheOperation{address, length});
if (MIPSComp::jit) {
if (jit) {
Core_ReenterDispatcher();
}
}
// Queued ranges still get their replacement hook checks.
void MIPSState::ClearJitCacheDeferred() {
if (!MIPSComp::jit) {
if (!jit) {
return;
}
+7
View File
@@ -30,6 +30,10 @@
class PointerWrap;
namespace MIPSComp {
class JitInterface;
}
typedef Memory::Opcode MIPSOpcode;
// A fake opcode the CPU cores fetch in place of an instruction with a replacement function (see
@@ -304,6 +308,9 @@ public:
std::vector<PendingCacheOperation> pendingInvalidates_;
bool invalidateAll_ = false;
std::vector<std::pair<u32, u32>> keepJitBlocks_;
// Owned. Null on the interpreter.
MIPSComp::JitInterface *jit = nullptr;
};
// Access control ('private') break standard layout. Let's not allow it, to avoid excessive
+7 -7
View File
@@ -125,7 +125,7 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) {
g_lastCrashAddress = nullptr;
// TODO: Check that codePtr is within the current JIT space.
bool inJitSpace = MIPSComp::jit && MIPSComp::jit->CodeInRange(codePtr);
bool inJitSpace = mipsr4k.jit && mipsr4k.jit->CodeInRange(codePtr);
if (!inJitSpace) {
// This is a crash in non-jitted code. Not something we want to handle here, ignore.
// Actually, we could handle crashes from the IR interpreter here, although recovering the call stack
@@ -210,7 +210,7 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) {
success = false;
#endif
if (MIPSComp::jit && (shadowFault || MIPSComp::jit->IsAtDispatchFetch(codePtr))) {
if (mipsr4k.jit && (shadowFault || mipsr4k.jit->IsAtDispatchFetch(codePtr))) {
// The shadow entry's offset is the target, masked.
u32 targetAddr = shadowFault ? guestAddress : currentMIPS->pc;
// TODO: Do the other archs and platforms.
@@ -220,7 +220,7 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) {
#endif
Core_ExecException(targetAddr, currentMIPS->pc, ExecExceptionType::JUMP);
// Redirect execution to a crash handler that will switch to CoreState::CORE_RUNTIME_ERROR immediately.
uintptr_t crashHandler = (uintptr_t)MIPSComp::jit->GetCrashHandler();
uintptr_t crashHandler = (uintptr_t)mipsr4k.jit->GetCrashHandler();
if (crashHandler != 0) {
context->CTX_PC = crashHandler;
ERROR_LOG(Log::MemMap, "Bad execution access detected, halting: %08x (last known pc %08x, host: %p)", targetAddr, currentMIPS->pc, (void *)hostAddress);
@@ -252,7 +252,7 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) {
g_numReportedBadAccesses++;
if (g_numReportedBadAccesses < 100) {
std::string temp;
if (MIPSComp::jit && MIPSComp::jit->DescribeCodePtr(codePtr, temp)) {
if (mipsr4k.jit && mipsr4k.jit->DescribeCodePtr(codePtr, temp)) {
ERROR_LOG(Log::MemMap, "Bad memory access detected and ignored: %08x (%p) at %s", guestAddress, (void *)hostAddress, temp.c_str());
} else {
ERROR_LOG(Log::MemMap, "Bad memory access detected and ignored: %08x (%p)", guestAddress, (void *)hostAddress);
@@ -261,7 +261,7 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) {
} else {
std::string infoString = "";
std::string temp;
if (MIPSComp::jit && MIPSComp::jit->DescribeCodePtr(codePtr, temp)) {
if (mipsr4k.jit && mipsr4k.jit->DescribeCodePtr(codePtr, temp)) {
infoString += temp + " ";
}
temp.clear();
@@ -281,8 +281,8 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) {
// Redirect execution to a crash handler that will switch to CoreState::CORE_RUNTIME_ERROR immediately.
uintptr_t crashHandler = 0;
if (MIPSComp::jit)
crashHandler = (uintptr_t)MIPSComp::jit->GetCrashHandler();
if (mipsr4k.jit)
crashHandler = (uintptr_t)mipsr4k.jit->GetCrashHandler();
if (crashHandler != 0)
context->CTX_PC = crashHandler;
else
+4 -4
View File
@@ -376,8 +376,8 @@ void CwCheatScreen::onFinish(DialogResult result) {
if (result != DR_BACK) // This only works for BACK here.
return;
if (MIPSComp::jit) {
MIPSComp::jit->ClearCache();
if (mipsr4k.jit) {
mipsr4k.jit->ClearCache();
}
}
@@ -401,8 +401,8 @@ void CwCheatScreen::OnAddCheat(UI::EventParams &params) {
void CwCheatScreen::OnEditCheatFile(UI::EventParams &params) {
g_Config.bReloadCheats = true;
if (MIPSComp::jit) {
MIPSComp::jit->ClearCache();
if (mipsr4k.jit) {
mipsr4k.jit->ClearCache();
}
if (engine_) {
File::OpenFileInEditor(engine_->CheatFilename());
+2 -2
View File
@@ -72,9 +72,9 @@ static void DrawJitStats(UIContext *ctx, const Bounds &bounds) {
char statbuf[1024];
StringWriter w(statbuf, sizeof(statbuf));
if (MIPSComp::jit) {
if (mipsr4k.jit) {
MIPSComp::JitStats stats;
MIPSComp::jit->GetStats(&stats);
mipsr4k.jit->GetStats(&stats);
const double irPercent = stats.irArenaSize ? 100.0 * stats.irArenaUsed / stats.irArenaSize : 0.0;
w.F("Blocks: %d (%d valid)\n", stats.numBlocks, stats.numValidBlocks);
if (stats.codeSize) {
+2 -2
View File
@@ -922,8 +922,8 @@ static void DrawInternals(ImConfig &cfg) {
if (ImGui::CollapsingHeader("Memory")) {
ImGui::Text("Base pointer: %p", Memory::base);
ImGui::Text("Main memory size: %08x", Memory::g_MemorySize);
if (MIPSComp::jit) {
ImGui::Text("JIT code cache: %p", MIPSComp::jit->GetCodeBase());
if (mipsr4k.jit) {
ImGui::Text("JIT code cache: %p", mipsr4k.jit->GetCodeBase());
ImGui::Text("MIPS state: %p", currentMIPS);
}
if (ImGui::Button("Copy to clipboard")) {
+1 -1
View File
@@ -63,7 +63,7 @@ void ImJitViewerWindow::Draw(ImConfig &cfg, ImControl &control) {
numColumns = 4;
}
JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface();
JitBlockCacheDebugInterface *blockCacheDebug = mipsr4k.jit->GetBlockCacheDebugInterface();
if (core_ != (int)core) {
// Core changed, need to refresh.
+14 -14
View File
@@ -13,10 +13,10 @@
#include "UI/PopupScreens.h"
JitCompareScreen::JitCompareScreen() : UITabbedBaseDialogScreen(Path()) {
if (!MIPSComp::jit) {
if (!mipsr4k.jit) {
return;
}
JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface();
JitBlockCacheDebugInterface *blockCacheDebug = mipsr4k.jit->GetBlockCacheDebugInterface();
// The only defaults that make sense.
if (blockCacheDebug->SupportsProfiling()) {
listSort_ = ListSort::TIME_SPENT;
@@ -43,8 +43,8 @@ void JitCompareScreen::CreateTabs() {
{ "Executions", "I_ARROW_DOWN" },
};
int sortCount = ARRAY_SIZE(sortMenu);
if (MIPSComp::jit) {
JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface();
if (mipsr4k.jit) {
JitBlockCacheDebugInterface *blockCacheDebug = mipsr4k.jit->GetBlockCacheDebugInterface();
if (!blockCacheDebug->SupportsProfiling()) {
sortCount -= 2;
}
@@ -133,7 +133,7 @@ void JitCompareScreen::CreateTabs() {
}
void JitCompareScreen::FillBlockList() {
JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface();
JitBlockCacheDebugInterface *blockCacheDebug = mipsr4k.jit->GetBlockCacheDebugInterface();
blockList_.clear();
int64_t sumTotalNanos = 0;
int64_t sumExecutions = 0;
@@ -226,11 +226,11 @@ void JitCompareScreen::UpdateDisasm() {
using namespace UI;
if (!MIPSComp::jit) {
if (!mipsr4k.jit) {
return;
}
JitBlockCacheDebugInterface *blockCacheDebug = MIPSComp::jit->GetBlockCacheDebugInterface();
JitBlockCacheDebugInterface *blockCacheDebug = mipsr4k.jit->GetBlockCacheDebugInterface();
FillBlockList();
@@ -337,10 +337,10 @@ void JitCompareScreen::OnBlockClick(UI::EventParams &e) {
}
void JitCompareScreen::OnAddressChange(UI::EventParams &e) {
if (!MIPSComp::jit) {
if (!mipsr4k.jit) {
return;
}
JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface();
JitBlockCacheDebugInterface *blockCache = mipsr4k.jit->GetBlockCacheDebugInterface();
if (!blockCache)
return;
u32 addr;
@@ -363,11 +363,11 @@ void JitCompareScreen::OnSelectBlock(UI::EventParams &e) {
}
void JitCompareScreen::OnBlockAddress(UI::EventParams &e) {
if (!MIPSComp::jit) {
if (!mipsr4k.jit) {
return;
}
JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface();
JitBlockCacheDebugInterface *blockCache = mipsr4k.jit->GetBlockCacheDebugInterface();
if (!blockCache)
return;
@@ -381,11 +381,11 @@ void JitCompareScreen::OnBlockAddress(UI::EventParams &e) {
/*
void JitCompareScreen::OnRandomBlock(int flag) {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (!MIPSComp::jit) {
std::lock_guard<std::recursive_mutex> guard(mipsr4k.jitLock);
if (!mipsr4k.jit) {
return;
}
JitBlockCacheDebugInterface *blockCache = MIPSComp::jit->GetBlockCacheDebugInterface();
JitBlockCacheDebugInterface *blockCache = mipsr4k.jit->GetBlockCacheDebugInterface();
if (!blockCache)
return;
+3 -3
View File
@@ -66,9 +66,9 @@ void HandleCommonMessages(UIMessage message, const char *value, ScreenManager *m
if (message == UIMessage::REQUEST_CLEAR_JIT && PSP_IsInited()) {
// TODO: This seems to clearly be the wrong place to handle this.
if (MIPSComp::jit) {
if (MIPSComp::jit)
MIPSComp::jit->ClearCache();
if (mipsr4k.jit) {
if (mipsr4k.jit)
mipsr4k.jit->ClearCache();
}
currentMIPS->UpdateCore((CPUCore)g_Config.iCpuCore);
} else if (message == UIMessage::SHOW_CONTROL_MAPPING && isActiveScreen && std::string(activeScreen->tag()) != "ControlMapping") {
+1 -1
View File
@@ -1027,7 +1027,7 @@ namespace MainWindow {
const u8 *ptr = (const u8 *)info->addr;
std::string name;
if (MIPSComp::jit && MIPSComp::jit->DescribeCodePtr(ptr, name)) {
if (mipsr4k.jit && mipsr4k.jit->DescribeCodePtr(ptr, name)) {
swprintf_s(info->name, L"Jit::%S", name.c_str());
return;
}
+20 -20
View File
@@ -87,7 +87,7 @@ HLEFunction UnitTestFakeSyscalls[] = {
double ExecCPUTest(bool clearCache = true) {
int blockTicks = 1000000;
if (MIPSComp::jit) {
if (mipsr4k.jit) {
currentMIPS->pc = PSP_GetUserMemoryBase();
MIPSComp::JitAt(currentMIPS);
}
@@ -101,15 +101,15 @@ double ExecCPUTest(bool clearCache = true) {
}
}, 0.5, 1000);
if (MIPSComp::jit) {
JitBlockCacheDebugInterface *cache = MIPSComp::jit->GetBlockCacheDebugInterface();
if (mipsr4k.jit) {
JitBlockCacheDebugInterface *cache = mipsr4k.jit->GetBlockCacheDebugInterface();
if (cache) {
JitBlockDebugInfo block = cache->GetBlockDebugInfo(0);
WARN_LOG(Log::JIT, "Executed %d target instrs, %d IR, for %d orig", (int)block.targetDisasm.size(), (int)block.irDisasm.size(), (int)block.origDisasm.size());
}
if (clearCache)
MIPSComp::jit->ClearCache();
mipsr4k.jit->ClearCache();
}
return callsPerSecond;
@@ -200,7 +200,7 @@ bool TestJit() {
printf("%s modified the code in PSP memory\n", core);
memoryClean = false;
}
if (MIPSComp::jit && Memory::ReadBlockShadow(PSP_GetUserMemoryBase()) == 0) {
if (mipsr4k.jit && Memory::ReadBlockShadow(PSP_GetUserMemoryBase()) == 0) {
printf("%s didn't enter its block in the block shadow\n", core);
memoryClean = false;
}
@@ -224,13 +224,13 @@ bool TestJit() {
mipsr4k.UpdateCore(CPUCore::IR_INTERPRETER);
ir_speed = ExecCPUTest(false);
checkMemoryClean("IR interpreter");
MIPSComp::jit->ClearCache();
mipsr4k.jit->ClearCache();
mipsr4k.UpdateCore(CPUCore::JIT);
jit_speed = ExecCPUTest(false); // not clearing, so the below can do things.
checkMemoryClean("JIT");
// Disassemble
JitBlockCacheDebugInterface *cache = MIPSComp::jit->GetBlockCacheDebugInterface();
JitBlockCacheDebugInterface *cache = mipsr4k.jit->GetBlockCacheDebugInterface();
if (cache) {
JitBlockDebugInfo block = cache->GetBlockDebugInfo(0); // Should only be one block.
std::vector<std::string> &lines = block.targetDisasm;
@@ -297,11 +297,11 @@ bool TestJitDotBench() {
mipsr4k.UpdateCore(CPUCore::JIT);
const double callsPerSecond = ExecCPUTest(false);
if (getenv("PPSSPP_JITBENCH_DISASM")) {
JitBlockDebugInfo block = MIPSComp::jit->GetBlockCacheDebugInterface()->GetBlockDebugInfo(0);
JitBlockDebugInfo block = mipsr4k.jit->GetBlockCacheDebugInterface()->GetBlockDebugInfo(0);
for (size_t i = 0; i < block.targetDisasm.size() && i < 80; i++)
printf(" %s\n", block.targetDisasm[i].c_str());
}
MIPSComp::jit->ClearCache();
mipsr4k.jit->ClearCache();
printf("%-14s %6.2f ns per dot\n", seq.name, 1e9 / (callsPerSecond * groups * seq.dots));
}
@@ -337,7 +337,7 @@ static bool CheckReplacementHooks(u32 func, u32 size, const std::vector<u8> &cod
};
for (CPUCore core : cores) {
mipsr4k.UpdateCore(core);
const u32 hook = MIPSComp::jit->GetBlockShadowHookValue();
const u32 hook = mipsr4k.jit->GetBlockShadowHookValue();
EXPECT_EQ_HEX(Memory::ReadBlockShadow(func), hook);
// Compiling replaces the hook value with the block's entry.
@@ -346,11 +346,11 @@ static bool CheckReplacementHooks(u32 func, u32 size, const std::vector<u8> &cod
EXPECT_TRUE(block != 0 && block != hook);
// Destroying the block puts it back, whichever way it goes.
MIPSComp::jit->InvalidateCacheAt(func, 4);
mipsr4k.jit->InvalidateCacheAt(func, 4);
EXPECT_EQ_HEX(Memory::ReadBlockShadow(func), hook);
compile();
MIPSComp::jit->ClearCache();
EXPECT_EQ_HEX(Memory::ReadBlockShadow(func), MIPSComp::jit->GetBlockShadowHookValue());
mipsr4k.jit->ClearCache();
EXPECT_EQ_HEX(Memory::ReadBlockShadow(func), mipsr4k.jit->GetBlockShadowHookValue());
// Leave a block for the core switch to destroy.
compile();
@@ -398,7 +398,7 @@ static bool CheckReplacementHooks(u32 func, u32 size, const std::vector<u8> &cod
// The game overwriting the hooked instruction drops the hook.
MIPSAnalyst::ReplaceFunctions();
EXPECT_EQ_HEX(Memory::ReadBlockShadow(func), MIPSComp::jit->GetBlockShadowHookValue());
EXPECT_EQ_HEX(Memory::ReadBlockShadow(func), mipsr4k.jit->GetBlockShadowHookValue());
Memory::WriteUnchecked_U32(MIPS_MAKE_NOP(), func);
EXPECT_EQ_HEX(ReadExecutedOp(func).encoding, MIPS_MAKE_NOP());
EXPECT_FALSE(Replacement_IsHooked(func));
@@ -836,8 +836,8 @@ static void RunFuzzCase(const std::vector<u32> &code, const FuzzState &init, Fuz
for (int i = 0; i < FUZZ_MAX_INSTRS; ++i) {
Memory::WriteUnchecked_U32(MIPS_MAKE_NOP(), addr + 12 + i * 4);
}
if (MIPSComp::jit && !keepCache) {
MIPSComp::jit->ClearCache();
if (mipsr4k.jit && !keepCache) {
mipsr4k.jit->ClearCache();
}
MIPSState *mips = currentMIPS;
@@ -850,8 +850,8 @@ static void RunFuzzCase(const std::vector<u32> &code, const FuzzState &init, Fuz
mips->lo = init.lo;
mips->fcr31 = init.fcr31;
// As a thread switch does, or a JIT keeps converting in the previous case's rounding mode.
if (MIPSComp::jit) {
MIPSComp::jit->UpdateFCR31();
if (mipsr4k.jit) {
mipsr4k.jit->UpdateFCR31();
}
mips->fpcond = init.fpcond;
mips->llBit = 0;
@@ -866,8 +866,8 @@ static void RunFuzzCase(const std::vector<u32> &code, const FuzzState &init, Fuz
}
out->cycles = (u32)(g_terminatorTicks - startTicks);
if (g_fuzzPrintBlocks && MIPSComp::jit) {
JitBlockCacheDebugInterface *blocks = MIPSComp::jit->GetBlockCacheDebugInterface();
if (g_fuzzPrintBlocks && mipsr4k.jit) {
JitBlockCacheDebugInterface *blocks = mipsr4k.jit->GetBlockCacheDebugInterface();
for (int i = 0; i < blocks->GetNumBlocks(); i++) {
if (!blocks->IsValidBlock(i))
continue;