From 5a9cbf007c883a9a2ceb656a00bbfc383d00392d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 20 Oct 2026 09:47:48 +0200 Subject: [PATCH] CPU: Pass the MIPSState explicitly where it was already at hand The JIT backends' calls out of generated code (the MIPS and IR interpreter fallbacks, and the bad address report) now take the state the backend was built for instead of reading currentMIPS. Likewise the interpreter's tick check, the IR dispatcher's Advance, and a couple of debugger helpers. MIPSState::InitRegisters() no longer sets currentMIPS; the boot paths set it. Co-Authored-By: Claude Opus 5.5 (1M context) --- Common/ABI.cpp | 73 ++++++++++++++++++++++++ Common/x64Emitter.h | 3 + Core/MIPS/ARM/ArmIRCompSystem.cpp | 1 + Core/MIPS/ARM/ArmIRJit.cpp | 2 + Core/MIPS/ARM64/Arm64IRCompSystem.cpp | 1 + Core/MIPS/ARM64/Arm64IRJit.cpp | 4 +- Core/MIPS/IR/IRJit.cpp | 2 +- Core/MIPS/IR/IRNativeCommon.cpp | 13 +++-- Core/MIPS/IR/IRNativeCommon.h | 11 +++- Core/MIPS/LoongArch64/LoongArch64Jit.cpp | 2 + Core/MIPS/MIPS.cpp | 1 - Core/MIPS/MIPSAnalyst.cpp | 4 +- Core/MIPS/MIPSTables.cpp | 6 +- Core/MIPS/MIPSTables.h | 10 +--- Core/MIPS/MIPSVFPUUtils.cpp | 2 +- Core/MIPS/RiscV/RiscVJit.cpp | 7 ++- Core/MIPS/x86/X64IRCompSystem.cpp | 2 +- Core/MIPS/x86/X64IRJit.cpp | 6 +- Core/System.cpp | 1 + headless/ReverseEngineer.cpp | 1 + 20 files changed, 121 insertions(+), 31 deletions(-) diff --git a/Common/ABI.cpp b/Common/ABI.cpp index 583a357128..bc048f8823 100644 --- a/Common/ABI.cpp +++ b/Common/ABI.cpp @@ -107,6 +107,14 @@ void XEmitter::ABI_CallFunctionCCC(const void *func, u32 param1, u32 param2, u32 ABI_RestoreStack(3 * 4); } +void XEmitter::ABI_CallFunctionCP(const void *func, u32 param1, void *param2) { + ABI_AlignStack(2 * 4); + PUSH(32, ImmPtr(param2)); + PUSH(32, Imm32(param1)); + CALL(func); + ABI_RestoreStack(2 * 4); +} + void XEmitter::ABI_CallFunctionCCP(const void *func, u32 param1, u32 param2, void *param3) { ABI_AlignStack(3 * 4); PUSH(32, ImmPtr(param3)); @@ -150,6 +158,14 @@ void XEmitter::ABI_CallFunctionPAA(const void *func, void *param1, const Gen::Op ABI_RestoreStack(3 * 4); } +void XEmitter::ABI_CallFunctionPP(const void *func, void *param1, void *param2) { + ABI_AlignStack(2 * 4); + PUSH(32, ImmPtr(param2)); + PUSH(32, ImmPtr(param1)); + CALL(func); + ABI_RestoreStack(2 * 4); +} + void XEmitter::ABI_CallFunctionPPC(const void *func, void *param1, void *param2, u32 param3) { ABI_AlignStack(3 * 4); PUSH(32, Imm32(param3)); @@ -196,6 +212,17 @@ void XEmitter::ABI_CallFunctionACC(const void *func, const Gen::OpArg &arg1, u32 ABI_RestoreStack(3 * 4); } +void XEmitter::ABI_CallFunctionACCP(const void *func, const Gen::OpArg &arg1, u32 param2, u32 param3, void *param4) +{ + ABI_AlignStack(4 * 4); + PUSH(32, ImmPtr(param4)); + PUSH(32, Imm32(param3)); + PUSH(32, Imm32(param2)); + PUSH(32, arg1); + CALL(func); + ABI_RestoreStack(4 * 4); +} + void XEmitter::ABI_CallFunctionA(const void *func, const Gen::OpArg &arg1) { ABI_AlignStack(1 * 4); @@ -348,6 +375,20 @@ void XEmitter::ABI_CallFunctionCCC(const void *func, u32 param1, u32 param2, u32 } } +void XEmitter::ABI_CallFunctionCP(const void *func, u32 param1, void *param2) { + MOV(32, R(ABI_PARAM1), Imm32(param1)); + MOV(64, R(ABI_PARAM2), ImmPtr(param2)); + u64 distance = u64(func) - (u64(code) + 5); + if (distance >= 0x0000000080000000ULL + && distance < 0xFFFFFFFF80000000ULL) { + // Far call + MOV(64, R(RAX), ImmPtr(func)); + CALLptr(R(RAX)); + } else { + CALL(func); + } +} + void XEmitter::ABI_CallFunctionCCP(const void *func, u32 param1, u32 param2, void *param3) { MOV(32, R(ABI_PARAM1), Imm32(param1)); MOV(32, R(ABI_PARAM2), Imm32(param2)); @@ -424,6 +465,20 @@ void XEmitter::ABI_CallFunctionPAA(const void *func, void *param1, const Gen::Op } } +void XEmitter::ABI_CallFunctionPP(const void *func, void *param1, void *param2) { + MOV(64, R(ABI_PARAM1), ImmPtr(param1)); + MOV(64, R(ABI_PARAM2), ImmPtr(param2)); + u64 distance = u64(func) - (u64(code) + 5); + if (distance >= 0x0000000080000000ULL + && distance < 0xFFFFFFFF80000000ULL) { + // Far call + MOV(64, R(RAX), ImmPtr(func)); + CALLptr(R(RAX)); + } else { + CALL(func); + } +} + void XEmitter::ABI_CallFunctionPPC(const void *func, void *param1, void *param2, u32 param3) { MOV(64, R(ABI_PARAM1), ImmPtr(param1)); MOV(64, R(ABI_PARAM2), ImmPtr(param2)); @@ -511,6 +566,24 @@ void XEmitter::ABI_CallFunctionACC(const void *func, const Gen::OpArg &arg1, u32 } } +void XEmitter::ABI_CallFunctionACCP(const void *func, const Gen::OpArg &arg1, u32 param2, u32 param3, void *param4) +{ + if (!arg1.IsSimpleReg(ABI_PARAM1)) + MOV(32, R(ABI_PARAM1), arg1); + MOV(32, R(ABI_PARAM2), Imm32(param2)); + MOV(32, R(ABI_PARAM3), Imm32(param3)); + MOV(64, R(ABI_PARAM4), ImmPtr(param4)); + u64 distance = u64(func) - (u64(code) + 5); + if (distance >= 0x0000000080000000ULL + && distance < 0xFFFFFFFF80000000ULL) { + // Far call + MOV(64, R(RAX), ImmPtr(func)); + CALLptr(R(RAX)); + } else { + CALL(func); + } +} + void XEmitter::ABI_CallFunctionA(const void *func, const Gen::OpArg &arg1) { if (!arg1.IsSimpleReg(ABI_PARAM1)) diff --git a/Common/x64Emitter.h b/Common/x64Emitter.h index 871de99fa2..9bc4d60da6 100644 --- a/Common/x64Emitter.h +++ b/Common/x64Emitter.h @@ -1412,14 +1412,17 @@ public: void ABI_CallFunctionC(const void *func, u32 param1); void ABI_CallFunctionCC(const void *func, u32 param1, u32 param2); void ABI_CallFunctionCCC(const void *func, u32 param1, u32 param2, u32 param3); + void ABI_CallFunctionCP(const void *func, u32 param1, void *param2); void ABI_CallFunctionCCP(const void *func, u32 param1, u32 param2, void *param3); void ABI_CallFunctionCCCP(const void *func, u32 param1, u32 param2, u32 param3, void *param4); void ABI_CallFunctionP(const void *func, void *param1); void ABI_CallFunctionPA(const void *func, void *param1, const Gen::OpArg &arg2); void ABI_CallFunctionPAA(const void *func, void *param1, const Gen::OpArg &arg2, const Gen::OpArg &arg3); + void ABI_CallFunctionPP(const void *func, void *param1, void *param2); void ABI_CallFunctionPPC(const void *func, void *param1, void *param2, u32 param3); void ABI_CallFunctionAC(const void *func, const Gen::OpArg &arg1, u32 param2); void ABI_CallFunctionACC(const void *func, const Gen::OpArg &arg1, u32 param2, u32 param3); + void ABI_CallFunctionACCP(const void *func, const Gen::OpArg &arg1, u32 param2, u32 param3, void *param4); void ABI_CallFunctionA(const void *func, const Gen::OpArg &arg1); void ABI_CallFunctionAA(const void *func, const Gen::OpArg &arg1, const Gen::OpArg &arg2); diff --git a/Core/MIPS/ARM/ArmIRCompSystem.cpp b/Core/MIPS/ARM/ArmIRCompSystem.cpp index 129632f7d8..41296dd08e 100644 --- a/Core/MIPS/ARM/ArmIRCompSystem.cpp +++ b/Core/MIPS/ARM/ArmIRCompSystem.cpp @@ -415,6 +415,7 @@ void ArmJitBackend::CompIR_ValidateAddress(IRInst inst) { // Otherwise would need a thunk to restore regs. MOVI2R(R1, alignment); MOVI2R(R2, isWrite ? 1 : 0); + MOVP2R(R3, mips_); QuickCallFunction(R12, &ReportBadAddress); B(dispatcherCheckCoreState_); diff --git a/Core/MIPS/ARM/ArmIRJit.cpp b/Core/MIPS/ARM/ArmIRJit.cpp index 3679d90eba..f8c8339dff 100644 --- a/Core/MIPS/ARM/ArmIRJit.cpp +++ b/Core/MIPS/ARM/ArmIRJit.cpp @@ -237,6 +237,7 @@ void ArmJitBackend::CompIR_Generic(IRInst inst) { // The 64-bit argument goes in R0:R1. MOVI2R(R0, (u32)value); MOVI2R(R1, (u32)(value >> 32)); + MOVP2R(R2, mips_); QuickCallFunction(R12, &DoIRInst); WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT); LoadStaticRegisters(); @@ -261,6 +262,7 @@ void ArmJitBackend::CompIR_Interpret(IRInst inst) { QuickCallFunction(R12, &NotifyMIPSInterpret); } MOVI2R(R0, inst.constant); + MOVP2R(R1, mips_); QuickCallFunction(R12, &MIPSInterpretTrampoline); WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT); LoadStaticRegisters(); diff --git a/Core/MIPS/ARM64/Arm64IRCompSystem.cpp b/Core/MIPS/ARM64/Arm64IRCompSystem.cpp index 2426a08456..7847725d76 100644 --- a/Core/MIPS/ARM64/Arm64IRCompSystem.cpp +++ b/Core/MIPS/ARM64/Arm64IRCompSystem.cpp @@ -447,6 +447,7 @@ void Arm64JitBackend::CompIR_ValidateAddress(IRInst inst) { MOV(W0, SCRATCH2); MOVI2R(W1, alignment); MOVI2R(W2, isWrite ? 1 : 0); + MOVP2R(X3, mips_); QuickCallFunction(SCRATCH2, &ReportBadAddress); B(dispatcherCheckCoreState_); diff --git a/Core/MIPS/ARM64/Arm64IRJit.cpp b/Core/MIPS/ARM64/Arm64IRJit.cpp index 39764ff7da..52fb0d4cdb 100644 --- a/Core/MIPS/ARM64/Arm64IRJit.cpp +++ b/Core/MIPS/ARM64/Arm64IRJit.cpp @@ -272,6 +272,7 @@ void Arm64JitBackend::CompIR_Generic(IRInst inst) { SaveStaticRegisters(); WriteDebugProfilerStatus(IRProfilerStatus::IR_INTERPRET); MOVI2R(X0, value); + MOVP2R(X1, mips_); QuickCallFunction(SCRATCH2_64, &DoIRInst); WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT); LoadStaticRegisters(); @@ -304,7 +305,8 @@ void Arm64JitBackend::CompIR_Interpret(IRInst inst) { MOVP2R(X0, MIPSGetName(op)); QuickCallFunction(SCRATCH2_64, &NotifyMIPSInterpret); } - MOVI2R(X0, inst.constant); + MOVI2R(W0, inst.constant); + MOVP2R(X1, mips_); QuickCallFunction(SCRATCH2_64, &MIPSInterpretTrampoline); WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT); LoadStaticRegisters(); diff --git a/Core/MIPS/IR/IRJit.cpp b/Core/MIPS/IR/IRJit.cpp index 7944f9e357..ff55fab1e3 100644 --- a/Core/MIPS/IR/IRJit.cpp +++ b/Core/MIPS/IR/IRJit.cpp @@ -312,7 +312,7 @@ void IRJit::RunBlocks() { MIPSState *mips = mips_; while (true) { RestoreHostRoundingMode(); - CoreTiming::Advance(currentMIPS); + CoreTiming::Advance(mips); if (coreState != 0) { break; } diff --git a/Core/MIPS/IR/IRNativeCommon.cpp b/Core/MIPS/IR/IRNativeCommon.cpp index 4796ddd32c..f1a8f90c4a 100644 --- a/Core/MIPS/IR/IRNativeCommon.cpp +++ b/Core/MIPS/IR/IRNativeCommon.cpp @@ -147,31 +147,31 @@ void IRNativeBackend::NotifyMIPSInterpret(const char *name) { debugSeenNotCompiled[name]++; } -void IRNativeBackend::DoMIPSInst(uint32_t value) { +void IRNativeBackend::DoMIPSInst(uint32_t value, MIPSState *mips) { MIPSOpcode op; memcpy(&op, &value, sizeof(op)); if constexpr (enableDebugStats) debugSeenNotCompiled[MIPSGetName(op)]++; - MIPSInterpret(currentMIPS, op); + MIPSInterpret(mips, op); } // This is called from IR->JIT implementation to fall back to the IR interpreter for missing ops. // Not fast. -uint32_t IRNativeBackend::DoIRInst(uint64_t value) { +uint32_t IRNativeBackend::DoIRInst(uint64_t value, MIPSState *mips) { IRInst inst[2]{}; memcpy(&inst[0], &value, sizeof(value)); if constexpr (enableDebugStats) debugSeenNotCompiledIR[(uint8_t)inst[0].op]++; // Doesn't really matter what value it returns as PC. inst[1].op = IROp::ExitToPC; - return IRInterpret(currentMIPS, &inst[0]); + return IRInterpret(mips, &inst[0]); } -int IRNativeBackend::ReportBadAddress(uint32_t addr, uint32_t alignment, uint32_t isWrite) { +int IRNativeBackend::ReportBadAddress(uint32_t addr, uint32_t alignment, uint32_t isWrite, MIPSState *mips) { const auto toss = [&](MemoryExceptionType t) { - Core_MemoryException(addr, alignment, currentMIPS->pc, t); + Core_MemoryException(addr, alignment, mips->pc, t); return coreState != CORE_RUNNING_CPU ? 1 : 0; }; @@ -514,6 +514,7 @@ void IRNativeJit::Init(IRNativeBackend &backend) { backend_ = &backend; backend_->SetProfiling(profiling_); debugInterface_.Init(backend_); + backend_->SetMIPSState(mips_); backend_->GenerateFixedCode(mips_); // Wanted this to be a reference, but vtbls get in the way. Shouldn't change. diff --git a/Core/MIPS/IR/IRNativeCommon.h b/Core/MIPS/IR/IRNativeCommon.h index 269b796712..bbcab71348 100644 --- a/Core/MIPS/IR/IRNativeCommon.h +++ b/Core/MIPS/IR/IRNativeCommon.h @@ -89,6 +89,9 @@ public: bool CodeInRange(const u8 *ptr) const; int OffsetFromCodePtr(const u8 *ptr); + void SetMIPSState(MIPSState *mips) { + mips_ = mips; + } virtual void GenerateFixedCode(MIPSState *mipsState) = 0; virtual bool CompileBlock(IRBlockCache *irBlockCache, int block_num) = 0; virtual void ClearAllBlocks() = 0; @@ -171,12 +174,12 @@ protected: static void NotifyMIPSInterpret(const char *name); // Callback to log AND perform a base interpreter op. Alternative to NotifyMIPSInterpret(). - static void DoMIPSInst(uint32_t op); + static void DoMIPSInst(uint32_t op, MIPSState *mips); // Callback to log AND perform an IR interpreter inst. Returns 0 or a PC to jump to. - static uint32_t DoIRInst(uint64_t inst); + static uint32_t DoIRInst(uint64_t inst, MIPSState *mips); - static int ReportBadAddress(uint32_t addr, uint32_t alignment, uint32_t isWrite); + static int ReportBadAddress(uint32_t addr, uint32_t alignment, uint32_t isWrite, MIPSState *mips); void AddLinkableExit(int block_num, uint32_t pc, int exitStartOffset, int exitLen); void EraseAllLinks(int block_num); @@ -185,6 +188,8 @@ protected: IRNativeHooks hooks_; IRBlockCache &blocks_; + // The CPU the generated code runs, for the calls out of it. + MIPSState *mips_ = nullptr; std::vector nativeBlocks_; std::unordered_multimap linksTo_; bool profiling_ = false; diff --git a/Core/MIPS/LoongArch64/LoongArch64Jit.cpp b/Core/MIPS/LoongArch64/LoongArch64Jit.cpp index 764f93b455..0b66e762ab 100644 --- a/Core/MIPS/LoongArch64/LoongArch64Jit.cpp +++ b/Core/MIPS/LoongArch64/LoongArch64Jit.cpp @@ -249,6 +249,7 @@ void LoongArch64JitBackend::CompIR_Generic(IRInst inst) { LI(R4, value); SaveStaticRegisters(); WriteDebugProfilerStatus(IRProfilerStatus::IR_INTERPRET); + LI(R5, (uintptr_t)mips_); QuickCallFunction(&DoIRInst, SCRATCH2); WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT); LoadStaticRegisters(); @@ -279,6 +280,7 @@ void LoongArch64JitBackend::CompIR_Interpret(IRInst inst) { QuickCallFunction(&NotifyMIPSInterpret, SCRATCH2); } LI(R4, (int32_t)inst.constant); + LI(R5, (uintptr_t)mips_); QuickCallFunction((const u8 *)&MIPSInterpretTrampoline, SCRATCH2); WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT); LoadStaticRegisters(); diff --git a/Core/MIPS/MIPS.cpp b/Core/MIPS/MIPS.cpp index 609a0ab036..5bfd2c67bd 100644 --- a/Core/MIPS/MIPS.cpp +++ b/Core/MIPS/MIPS.cpp @@ -364,7 +364,6 @@ void MIPSState::InitRegisters() { fpcond = 0; fcr31 = 0; debugCount = 0; - currentMIPS = this; inDelaySlot = false; llBit = 0; nextPC = 0; diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index 362c061526..a602b5e7e5 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -1569,7 +1569,7 @@ namespace MIPSAnalyst { switch (opInfo & CONDTYPE_MASK) { case CONDTYPE_EQ: if (opInfo & IN_FPUFLAG) { // fpu branch - info.conditionMet = currentMIPS->fpcond == 0; + info.conditionMet = cpu->GetFPCond() == 0; } else { info.conditionMet = (rt == rs); if (MIPS_GET_RT(op) == MIPS_GET_RS(op)) { // always true @@ -1579,7 +1579,7 @@ namespace MIPSAnalyst { break; case CONDTYPE_NE: if (opInfo & IN_FPUFLAG) { // fpu branch - info.conditionMet = currentMIPS->fpcond != 0; + info.conditionMet = cpu->GetFPCond() != 0; } else { info.conditionMet = (rt != rs); if (MIPS_GET_RT(op) == MIPS_GET_RS(op)) { // always true diff --git a/Core/MIPS/MIPSTables.cpp b/Core/MIPS/MIPSTables.cpp index d9a5221f42..23204d0b53 100644 --- a/Core/MIPS/MIPSTables.cpp +++ b/Core/MIPS/MIPSTables.cpp @@ -1372,8 +1372,8 @@ void MIPSInterpret(MIPSState *mips, MIPSOpcode op) { } // See the declaration comment in MIPSTables.h. -void CDECL MIPSInterpretTrampoline(MIPSOpcode op) { - MIPSInterpret(currentMIPS, op); +void CDECL MIPSInterpretTrampoline(u32 op, MIPSState *mips) { + MIPSInterpret(mips, MIPSOpcode(op)); } // This is the slow, feature-rich runloop for the interpreter. @@ -1434,7 +1434,7 @@ static void RunUntilDowncountZeroWithChecks(MIPSState *mips, u64 globalTicks) { } } - if (CoreTiming::GetTicks(currentMIPS) > globalTicks) + if (CoreTiming::GetTicks(mips) > globalTicks) return; } } diff --git a/Core/MIPS/MIPSTables.h b/Core/MIPS/MIPSTables.h index 2e64ca58db..4e7383313a 100644 --- a/Core/MIPS/MIPSTables.h +++ b/Core/MIPS/MIPSTables.h @@ -135,13 +135,9 @@ void MIPSInterpret(MIPSState *mips, MIPSOpcode op); //only for those rare ones int MIPSInterpret_RunUntil(MIPSState *mips, u64 globalTicks); MIPSInterpretFunc MIPSGetInterpretFunc(MIPSOpcode op); -// 1-arg (MIPSOpcode only) trampoline around MIPSInterpret(currentMIPS, op), for JIT backends -// (x86/ARM/ARM64/RiscV/LoongArch64 Comp_Generic / CompIR_Interpret) that bake a raw function -// pointer directly into generated machine code as their interpreter fallback - that codegen -// only arranges a single MIPSOpcode argument before the call, so it can't target a real -// MIPSInterpretFunc (now 2-arg) without also being taught to pass an explicit MIPSState*. -// TODO: teach each JIT's codegen to pass mips explicitly, then delete this. -void CDECL MIPSInterpretTrampoline(MIPSOpcode op); +// MIPSInterpret for the JIT backends' interpreter fallback (CompIR_Interpret), which calls it from +// generated code, with the opcode as a plain u32. +void CDECL MIPSInterpretTrampoline(u32 op, MIPSState *mips); int MIPSGetInstructionCycleEstimate(MIPSOpcode op); int MIPSGetMemoryAccessSize(MIPSOpcode op); diff --git a/Core/MIPS/MIPSVFPUUtils.cpp b/Core/MIPS/MIPSVFPUUtils.cpp index 6183190706..849a89fbcf 100644 --- a/Core/MIPS/MIPSVFPUUtils.cpp +++ b/Core/MIPS/MIPSVFPUUtils.cpp @@ -324,7 +324,7 @@ void WriteMatrix(MIPSState *mips, const float *rd, MatrixSize size, int reg) { default: side = 0; } - if (currentMIPS->VfpuWriteMask() != 0) { + if (mips->VfpuWriteMask() != 0) { ERROR_LOG_REPORT(Log::CPU, "Write mask used with vfpu matrix instruction."); } diff --git a/Core/MIPS/RiscV/RiscVJit.cpp b/Core/MIPS/RiscV/RiscVJit.cpp index b61077a5b6..f739aec8e5 100644 --- a/Core/MIPS/RiscV/RiscVJit.cpp +++ b/Core/MIPS/RiscV/RiscVJit.cpp @@ -252,7 +252,9 @@ void RiscVJitBackend::CompIR_Generic(IRInst inst) { LI(X10, value, SCRATCH2); SaveStaticRegisters(); WriteDebugProfilerStatus(IRProfilerStatus::IR_INTERPRET); - QuickCallFunction(&DoIRInst, SCRATCH2); + // X11 is SCRATCH2, so the call takes RA as its temp. + LI(X11, (uintptr_t)mips_); + QuickCallFunction(&DoIRInst); WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT); LoadStaticRegisters(); @@ -282,7 +284,8 @@ void RiscVJitBackend::CompIR_Interpret(IRInst inst) { QuickCallFunction(&NotifyMIPSInterpret, SCRATCH2); } LI(X10, (int32_t)inst.constant); - QuickCallFunction((const u8 *)&MIPSInterpretTrampoline, SCRATCH2); + LI(X11, (uintptr_t)mips_); + QuickCallFunction((const u8 *)&MIPSInterpretTrampoline); WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT); LoadStaticRegisters(); } diff --git a/Core/MIPS/x86/X64IRCompSystem.cpp b/Core/MIPS/x86/X64IRCompSystem.cpp index 0fe7bcb262..ff0db60f3e 100644 --- a/Core/MIPS/x86/X64IRCompSystem.cpp +++ b/Core/MIPS/x86/X64IRCompSystem.cpp @@ -446,7 +446,7 @@ void X64JitBackend::CompIR_ValidateAddress(IRInst inst) { // Ignores the return value, always returns to the dispatcher. // Otherwise would need a thunk to restore regs. - ABI_CallFunctionACC((const void *)&ReportBadAddress, R(SCRATCH1), alignment, isWrite); + ABI_CallFunctionACCP((const void *)&ReportBadAddress, R(SCRATCH1), alignment, isWrite, mips_); JMP(dispatcherCheckCoreState_, true); for (FixupBranch &b : validJumps) diff --git a/Core/MIPS/x86/X64IRJit.cpp b/Core/MIPS/x86/X64IRJit.cpp index 0f631762db..facfd2eda4 100644 --- a/Core/MIPS/x86/X64IRJit.cpp +++ b/Core/MIPS/x86/X64IRJit.cpp @@ -233,9 +233,9 @@ void X64JitBackend::CompIR_Generic(IRInst inst) { SaveStaticRegisters(); WriteDebugProfilerStatus(IRProfilerStatus::IR_INTERPRET); #if PPSSPP_ARCH(AMD64) - ABI_CallFunctionP((const void *)&DoIRInst, (void *)value); + ABI_CallFunctionPP((const void *)&DoIRInst, (void *)value, mips_); #else - ABI_CallFunctionCC((const void *)&DoIRInst, (u32)(value & 0xFFFFFFFF), (u32)(value >> 32)); + ABI_CallFunctionCCP((const void *)&DoIRInst, (u32)(value & 0xFFFFFFFF), (u32)(value >> 32), mips_); #endif WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT); LoadStaticRegisters(); @@ -259,7 +259,7 @@ void X64JitBackend::CompIR_Interpret(IRInst inst) { if (DebugStatsEnabled()) { ABI_CallFunctionP((const void *)&NotifyMIPSInterpret, (void *)MIPSGetName(op)); } - ABI_CallFunctionC((const void *)&MIPSInterpretTrampoline, inst.constant); + ABI_CallFunctionCP((const void *)&MIPSInterpretTrampoline, inst.constant, mips_); WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT); LoadStaticRegisters(); } diff --git a/Core/System.cpp b/Core/System.cpp index e4d17996f7..c1f90a635b 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -548,6 +548,7 @@ static bool CPU_Init(FileLoader *fileLoader, IdentifiedFileType type, std::strin LoadSymbolsIfSupported(); LoadGameSymbolsIfEnabled(); + currentMIPS = &mipsr4k; mipsr4k.Reset(); CoreTiming::Init(&mipsr4k); diff --git a/headless/ReverseEngineer.cpp b/headless/ReverseEngineer.cpp index 832572b4d1..67485bda51 100644 --- a/headless/ReverseEngineer.cpp +++ b/headless/ReverseEngineer.cpp @@ -240,6 +240,7 @@ bool InitMinimalPSP() { return false; } + currentMIPS = &mipsr4k; mipsr4k.Reset(); CoreTiming::Init(&mipsr4k); HLEInit();