mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
Plumb an explicit MIPSState *mips through the interpreter's Int_* handlers
All ~82 MIPSInt::Int_* functions (Interpreter.cpp/.h, InterpreterVFPU.cpp/.h) now take an explicit MIPSState *mips instead of reaching for the global currentMIPS internally, along with their file-local helpers (DelayBranchTo, SkipLikely, ApplySwizzleS/T, ApplyPrefixD/ST, RetainInvalidSwizzleST, EatPrefixes). MIPSInterpretFunc, Interpret(), ExecInstruction()/InterpreterDispatch.cpp (regenerated), and RunUntilFast() all thread mips through accordingly. Deliberately left on currentMIPS for now: MIPSVFPUUtils.cpp's ReadVector/WriteVector/ReadMatrix/WriteMatrix/VFPURewritePrefix - these are shared with every JIT backend's compile-time VFPU code, so parameterizing them would balloon this into a JIT-wide refactor. This is a partial refactor; that's the next boundary to push on. Several JIT backends (x86 Jit.cpp, ARM/ArmJit.cpp, ARM64/Arm64Jit.cpp, x86/X64IRJit.cpp, RiscV/RiscVJit.cpp, LoongArch64/LoongArch64Jit.cpp, ARM64/Arm64IRJit.cpp) bake the raw interpreter function pointer directly into JIT-generated machine code as their "fall back to the interpreter for this one op" mechanism, with only a single argument register set up for the call. Rather than hand-editing register allocation across four architectures that can't be build-tested here, added MIPSInterpretTrampoline(MIPSOpcode op) - a 1-arg wrapper around MIPSInterpret(currentMIPS, op) - and pointed all 7 such call sites at it instead, leaving that codegen untouched. Two other call sites (JitLogMiss, JitBranchLog) were plain C++ calls and just got the extra argument directly. Verified (Windows x64): PPSSPPWindows/PPSSPPHeadless/UnitTest all build clean, 49/49 unit tests pass. `test.py -g --graphics=software`: interpreter 312/314 (cpu/fpu/fpu is the pre-existing, unrelated interpreter-vs-JIT denormal difference; gpu/rendertarget/copy passes standalone, so was cross-test state bleed in the batch run, not a regression), default JIT 314/314, jit-ir 313/314 (gpu/vertices/morph is an expected difference from the vertex decoder taking a different mode with this core change, not a bug). Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_019SKhm9wKEQzRUsx9mTrrtQ
This commit is contained in:
1 parent
ba4c3d93f3
commit
ffad0acea1
17 files changed
+620
-608
No files matched your search
@@ -569,7 +569,7 @@ void ArmJit::Comp_Generic(MIPSOpcode op)
|
||||
gpr.SetRegImm(SCRATCHREG1, GetCompilerPC());
|
||||
MovToPC(SCRATCHREG1);
|
||||
gpr.SetRegImm(R0, op.encoding);
|
||||
QuickCallFunction(R1, (void *)func);
|
||||
QuickCallFunction(R1, (void *)&MIPSInterpretTrampoline);
|
||||
ApplyRoundingMode();
|
||||
RestoreDowncount();
|
||||
}
|
||||
|
||||
@@ -276,7 +276,7 @@ void Arm64JitBackend::CompIR_Interpret(IRInst inst) {
|
||||
QuickCallFunction(SCRATCH2_64, &NotifyMIPSInterpret);
|
||||
}
|
||||
MOVI2R(X0, inst.constant);
|
||||
QuickCallFunction(SCRATCH2_64, MIPSGetInterpretFunc(op));
|
||||
QuickCallFunction(SCRATCH2_64, &MIPSInterpretTrampoline);
|
||||
WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT);
|
||||
LoadStaticRegisters();
|
||||
}
|
||||
|
||||
@@ -581,7 +581,7 @@ void Arm64Jit::Comp_Generic(MIPSOpcode op) {
|
||||
MOVI2R(SCRATCH1, GetCompilerPC());
|
||||
MovToPC(SCRATCH1);
|
||||
MOVI2R(W0, op.encoding);
|
||||
QuickCallFunction(SCRATCH2_64, (void *)func);
|
||||
QuickCallFunction(SCRATCH2_64, (void *)&MIPSInterpretTrampoline);
|
||||
ApplyRoundingMode();
|
||||
LoadStaticRegisters();
|
||||
}
|
||||
|
||||
+94
-94
@@ -35,11 +35,11 @@
|
||||
#include "Core/HLE/HLETables.h"
|
||||
#include "Core/HLE/ReplaceTables.h"
|
||||
|
||||
#define R(i) (currentMIPS->r[i])
|
||||
#define F(i) (currentMIPS->f[i])
|
||||
#define FI(i) (currentMIPS->fi[i])
|
||||
#define FsI(i) (currentMIPS->fs[i])
|
||||
#define PC (currentMIPS->pc)
|
||||
#define R(i) (mips->r[i])
|
||||
#define F(i) (mips->f[i])
|
||||
#define FI(i) (mips->fi[i])
|
||||
#define FsI(i) (mips->fs[i])
|
||||
#define PC (mips->pc)
|
||||
|
||||
#define _SIMM16_SHL2 ((u32)(s32)(s16)(op & 0xFFFF) << 2)
|
||||
#define _RS ((op>>21) & 0x1F)
|
||||
@@ -51,27 +51,27 @@
|
||||
#define _POS ((op>>6 ) & 0x1F)
|
||||
#define _SIZE ((op>>11) & 0x1F)
|
||||
|
||||
#define HI currentMIPS->hi
|
||||
#define LO currentMIPS->lo
|
||||
#define HI mips->hi
|
||||
#define LO mips->lo
|
||||
|
||||
static inline void DelayBranchTo(u32 where)
|
||||
static inline void DelayBranchTo(MIPSState *mips, u32 where)
|
||||
{
|
||||
if (!Memory::IsValidAddress(where) || (where & 3) != 0) {
|
||||
Core_ExecException(where, PC, ExecExceptionType::JUMP);
|
||||
}
|
||||
PC += 4;
|
||||
mipsr4k.nextPC = where;
|
||||
mipsr4k.inDelaySlot = true;
|
||||
mips->nextPC = where;
|
||||
mips->inDelaySlot = true;
|
||||
}
|
||||
|
||||
static inline void SkipLikely() {
|
||||
static inline void SkipLikely(MIPSState *mips) {
|
||||
MIPSInfo delaySlot = MIPSGetInfo(Memory::Read_Instruction(PC + 4, true));
|
||||
// Don't actually skip if it is a jump (seen in Brooktown High.)
|
||||
if (delaySlot & IS_JUMP) {
|
||||
PC += 4;
|
||||
} else {
|
||||
PC += 8;
|
||||
--mipsr4k.downcount;
|
||||
--mips->downcount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ int MIPS_SingleStep(MIPSState *mips) {
|
||||
|
||||
namespace MIPSInt
|
||||
{
|
||||
void Int_Cache(MIPSOpcode op)
|
||||
void Int_Cache(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
int imm = SignExtend16ToS32(op);
|
||||
int rs = _RS;
|
||||
@@ -154,37 +154,37 @@ namespace MIPSInt
|
||||
PC += 4;
|
||||
}
|
||||
|
||||
void Int_Syscall(MIPSOpcode op)
|
||||
void Int_Syscall(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
// Need to pre-move PC, as CallSyscall may result in a rescheduling!
|
||||
// To do this neater, we'll need a little generated kernel loop that syscall can jump to and then RFI from
|
||||
// but I don't see a need to bother.
|
||||
if (mipsr4k.inDelaySlot)
|
||||
if (mips->inDelaySlot)
|
||||
{
|
||||
mipsr4k.pc = mipsr4k.nextPC;
|
||||
mips->pc = mips->nextPC;
|
||||
}
|
||||
else
|
||||
{
|
||||
mipsr4k.pc += 4;
|
||||
mips->pc += 4;
|
||||
}
|
||||
mipsr4k.inDelaySlot = false;
|
||||
mips->inDelaySlot = false;
|
||||
CallSyscall(op);
|
||||
}
|
||||
|
||||
void Int_Sync(MIPSOpcode op)
|
||||
void Int_Sync(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
//DEBUG_LOG(Log::CPU, "sync");
|
||||
PC += 4;
|
||||
}
|
||||
|
||||
void Int_Break(MIPSOpcode op)
|
||||
void Int_Break(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
Reporting::ReportMessage("BREAK instruction hit");
|
||||
Core_BreakException(PC);
|
||||
PC += 4;
|
||||
}
|
||||
|
||||
void Int_RelBranch(MIPSOpcode op)
|
||||
void Int_RelBranch(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
int imm = _SIMM16_SHL2;
|
||||
int rs = _RS;
|
||||
@@ -193,15 +193,15 @@ namespace MIPSInt
|
||||
|
||||
switch (op >> 26)
|
||||
{
|
||||
case 4: if (R(rt) == R(rs)) DelayBranchTo(addr); else PC += 4; break; //beq
|
||||
case 5: if (R(rt) != R(rs)) DelayBranchTo(addr); else PC += 4; break; //bne
|
||||
case 6: if ((s32)R(rs) <= 0) DelayBranchTo(addr); else PC += 4; break; //blez
|
||||
case 7: if ((s32)R(rs) > 0) DelayBranchTo(addr); else PC += 4; break; //bgtz
|
||||
case 4: if (R(rt) == R(rs)) DelayBranchTo(mips, addr); else PC += 4; break; //beq
|
||||
case 5: if (R(rt) != R(rs)) DelayBranchTo(mips, addr); else PC += 4; break; //bne
|
||||
case 6: if ((s32)R(rs) <= 0) DelayBranchTo(mips, addr); else PC += 4; break; //blez
|
||||
case 7: if ((s32)R(rs) > 0) DelayBranchTo(mips, addr); else PC += 4; break; //bgtz
|
||||
|
||||
case 20: if (R(rt) == R(rs)) DelayBranchTo(addr); else SkipLikely(); break; //beql
|
||||
case 21: if (R(rt) != R(rs)) DelayBranchTo(addr); else SkipLikely(); break; //bnel
|
||||
case 22: if ((s32)R(rs) <= 0) DelayBranchTo(addr); else SkipLikely(); break; //blezl
|
||||
case 23: if ((s32)R(rs) > 0) DelayBranchTo(addr); else SkipLikely(); break; //bgtzl
|
||||
case 20: if (R(rt) == R(rs)) DelayBranchTo(mips, addr); else SkipLikely(mips); break; //beql
|
||||
case 21: if (R(rt) != R(rs)) DelayBranchTo(mips, addr); else SkipLikely(mips); break; //bnel
|
||||
case 22: if ((s32)R(rs) <= 0) DelayBranchTo(mips, addr); else SkipLikely(mips); break; //blezl
|
||||
case 23: if ((s32)R(rs) > 0) DelayBranchTo(mips, addr); else SkipLikely(mips); break; //bgtzl
|
||||
|
||||
default:
|
||||
_dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted");
|
||||
@@ -209,7 +209,7 @@ namespace MIPSInt
|
||||
}
|
||||
}
|
||||
|
||||
void Int_RelBranchRI(MIPSOpcode op)
|
||||
void Int_RelBranchRI(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
int imm = _SIMM16_SHL2;
|
||||
int rs = _RS;
|
||||
@@ -217,14 +217,14 @@ namespace MIPSInt
|
||||
|
||||
switch ((op>>16) & 0x1F)
|
||||
{
|
||||
case 0: if ((s32)R(rs) < 0) DelayBranchTo(addr); else PC += 4; break;//bltz
|
||||
case 1: if ((s32)R(rs) >= 0) DelayBranchTo(addr); else PC += 4; break;//bgez
|
||||
case 2: if ((s32)R(rs) < 0) DelayBranchTo(addr); else SkipLikely(); break;//bltzl
|
||||
case 3: if ((s32)R(rs) >= 0) DelayBranchTo(addr); else SkipLikely(); break;//bgezl
|
||||
case 16: R(MIPS_REG_RA) = PC + 8; if ((s32)R(rs) < 0) DelayBranchTo(addr); else PC += 4; break;//bltzal
|
||||
case 17: R(MIPS_REG_RA) = PC + 8; if ((s32)R(rs) >= 0) DelayBranchTo(addr); else PC += 4; break;//bgezal
|
||||
case 18: R(MIPS_REG_RA) = PC + 8; if ((s32)R(rs) < 0) DelayBranchTo(addr); else SkipLikely(); break;//bltzall
|
||||
case 19: R(MIPS_REG_RA) = PC + 8; if ((s32)R(rs) >= 0) DelayBranchTo(addr); else SkipLikely(); break;//bgezall
|
||||
case 0: if ((s32)R(rs) < 0) DelayBranchTo(mips, addr); else PC += 4; break;//bltz
|
||||
case 1: if ((s32)R(rs) >= 0) DelayBranchTo(mips, addr); else PC += 4; break;//bgez
|
||||
case 2: if ((s32)R(rs) < 0) DelayBranchTo(mips, addr); else SkipLikely(mips); break;//bltzl
|
||||
case 3: if ((s32)R(rs) >= 0) DelayBranchTo(mips, addr); else SkipLikely(mips); break;//bgezl
|
||||
case 16: R(MIPS_REG_RA) = PC + 8; if ((s32)R(rs) < 0) DelayBranchTo(mips, addr); else PC += 4; break;//bltzal
|
||||
case 17: R(MIPS_REG_RA) = PC + 8; if ((s32)R(rs) >= 0) DelayBranchTo(mips, addr); else PC += 4; break;//bgezal
|
||||
case 18: R(MIPS_REG_RA) = PC + 8; if ((s32)R(rs) < 0) DelayBranchTo(mips, addr); else SkipLikely(mips); break;//bltzall
|
||||
case 19: R(MIPS_REG_RA) = PC + 8; if ((s32)R(rs) >= 0) DelayBranchTo(mips, addr); else SkipLikely(mips); break;//bgezall
|
||||
default:
|
||||
_dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted");
|
||||
break;
|
||||
@@ -232,58 +232,58 @@ namespace MIPSInt
|
||||
}
|
||||
|
||||
|
||||
void Int_VBranch(MIPSOpcode op)
|
||||
void Int_VBranch(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
int imm = _SIMM16_SHL2;
|
||||
u32 addr = PC + imm + 4;
|
||||
|
||||
// x, y, z, w, any, all, (invalid), (invalid)
|
||||
int imm3 = (op>>18)&7;
|
||||
int val = (currentMIPS->vfpuCtrl[VFPU_CTRL_CC] >> imm3) & 1;
|
||||
int val = (mips->vfpuCtrl[VFPU_CTRL_CC] >> imm3) & 1;
|
||||
|
||||
switch ((op >> 16) & 3)
|
||||
{
|
||||
case 0: if (!val) DelayBranchTo(addr); else PC += 4; break; //bvf
|
||||
case 1: if ( val) DelayBranchTo(addr); else PC += 4; break; //bvt
|
||||
case 2: if (!val) DelayBranchTo(addr); else SkipLikely(); break; //bvfl
|
||||
case 3: if ( val) DelayBranchTo(addr); else SkipLikely(); break; //bvtl
|
||||
case 0: if (!val) DelayBranchTo(mips, addr); else PC += 4; break; //bvf
|
||||
case 1: if ( val) DelayBranchTo(mips, addr); else PC += 4; break; //bvt
|
||||
case 2: if (!val) DelayBranchTo(mips, addr); else SkipLikely(mips); break; //bvfl
|
||||
case 3: if ( val) DelayBranchTo(mips, addr); else SkipLikely(mips); break; //bvtl
|
||||
}
|
||||
}
|
||||
|
||||
void Int_FPUBranch(MIPSOpcode op)
|
||||
void Int_FPUBranch(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
int imm = _SIMM16_SHL2;
|
||||
u32 addr = PC + imm + 4;
|
||||
switch((op>>16)&0x1f)
|
||||
{
|
||||
case 0: if (!currentMIPS->fpcond) DelayBranchTo(addr); else PC += 4; break;//bc1f
|
||||
case 1: if ( currentMIPS->fpcond) DelayBranchTo(addr); else PC += 4; break;//bc1t
|
||||
case 2: if (!currentMIPS->fpcond) DelayBranchTo(addr); else SkipLikely(); break;//bc1fl
|
||||
case 3: if ( currentMIPS->fpcond) DelayBranchTo(addr); else SkipLikely(); break;//bc1tl
|
||||
case 0: if (!mips->fpcond) DelayBranchTo(mips, addr); else PC += 4; break;//bc1f
|
||||
case 1: if ( mips->fpcond) DelayBranchTo(mips, addr); else PC += 4; break;//bc1t
|
||||
case 2: if (!mips->fpcond) DelayBranchTo(mips, addr); else SkipLikely(mips); break;//bc1fl
|
||||
case 3: if ( mips->fpcond) DelayBranchTo(mips, addr); else SkipLikely(mips); break;//bc1tl
|
||||
default:
|
||||
_dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Int_JumpType(MIPSOpcode op)
|
||||
void Int_JumpType(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
if (mipsr4k.inDelaySlot)
|
||||
if (mips->inDelaySlot)
|
||||
ERROR_LOG(Log::CPU, "Jump in delay slot :(");
|
||||
|
||||
u32 off = ((op & 0x03FFFFFF) << 2);
|
||||
u32 addr = (currentMIPS->pc & 0xF0000000) | off;
|
||||
u32 addr = (mips->pc & 0xF0000000) | off;
|
||||
|
||||
switch (op>>26)
|
||||
{
|
||||
case 2: //j
|
||||
if (!mipsr4k.inDelaySlot)
|
||||
DelayBranchTo(addr);
|
||||
if (!mips->inDelaySlot)
|
||||
DelayBranchTo(mips, addr);
|
||||
break;
|
||||
case 3: //jal
|
||||
R(MIPS_REG_RA) = PC + 8;
|
||||
if (!mipsr4k.inDelaySlot)
|
||||
DelayBranchTo(addr);
|
||||
if (!mips->inDelaySlot)
|
||||
DelayBranchTo(mips, addr);
|
||||
break;
|
||||
default:
|
||||
_dbg_assert_msg_(false,"Trying to interpret instruction that can't be interpreted");
|
||||
@@ -291,9 +291,9 @@ namespace MIPSInt
|
||||
}
|
||||
}
|
||||
|
||||
void Int_JumpRegType(MIPSOpcode op)
|
||||
void Int_JumpRegType(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
if (mipsr4k.inDelaySlot) {
|
||||
if (mips->inDelaySlot) {
|
||||
// There's one of these in Star Soldier at 0881808c, which seems benign.
|
||||
ERROR_LOG(Log::CPU, "Jump in delay slot :(");
|
||||
}
|
||||
@@ -304,20 +304,20 @@ namespace MIPSInt
|
||||
switch (op & 0x3f)
|
||||
{
|
||||
case 8: //jr
|
||||
if (!mipsr4k.inDelaySlot)
|
||||
DelayBranchTo(addr);
|
||||
if (!mips->inDelaySlot)
|
||||
DelayBranchTo(mips, addr);
|
||||
break;
|
||||
case 9: //jalr
|
||||
if (rd != 0)
|
||||
R(rd) = PC + 8;
|
||||
// Update rd, but otherwise do not take the branch if we're branching.
|
||||
if (!mipsr4k.inDelaySlot)
|
||||
DelayBranchTo(addr);
|
||||
if (!mips->inDelaySlot)
|
||||
DelayBranchTo(mips, addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Int_IType(MIPSOpcode op) {
|
||||
void Int_IType(MIPSState *mips, MIPSOpcode op) {
|
||||
u32 uimm = op & 0xFFFF;
|
||||
u32 suimm = SignExtend16ToU32(op);
|
||||
s32 simm = SignExtend16ToS32(op);
|
||||
@@ -347,7 +347,7 @@ namespace MIPSInt
|
||||
PC += 4;
|
||||
}
|
||||
|
||||
void Int_StoreSync(MIPSOpcode op) {
|
||||
void Int_StoreSync(MIPSState *mips, MIPSOpcode op) {
|
||||
int imm = (signed short)(op & 0xFFFF);
|
||||
int rt = _RT;
|
||||
int rs = _RS;
|
||||
@@ -363,10 +363,10 @@ namespace MIPSInt
|
||||
}
|
||||
R(rt) = Memory::ReadUnchecked_U32(addr);
|
||||
}
|
||||
currentMIPS->llBit = 1;
|
||||
mips->llBit = 1;
|
||||
break;
|
||||
case 56: // sc
|
||||
if (currentMIPS->llBit) {
|
||||
if (mips->llBit) {
|
||||
if (!Memory::IsValid4AlignedAddress(addr)) {
|
||||
Core_MemoryException(addr, 4, PC, MemoryExceptionType::WRITE_WORD, "sc");
|
||||
return;
|
||||
@@ -387,7 +387,7 @@ namespace MIPSInt
|
||||
}
|
||||
|
||||
|
||||
void Int_RType3(MIPSOpcode op) {
|
||||
void Int_RType3(MIPSState *mips, MIPSOpcode op) {
|
||||
int rt = _RT;
|
||||
int rs = _RS;
|
||||
int rd = _RD;
|
||||
@@ -421,7 +421,7 @@ namespace MIPSInt
|
||||
}
|
||||
|
||||
|
||||
void Int_ITypeMem(MIPSOpcode op) {
|
||||
void Int_ITypeMem(MIPSState *mips, MIPSOpcode op) {
|
||||
int imm = (signed short)(op&0xFFFF);
|
||||
int rt = _RT;
|
||||
int rs = _RS;
|
||||
@@ -557,7 +557,7 @@ namespace MIPSInt
|
||||
PC += 4;
|
||||
}
|
||||
|
||||
void Int_FPULS(MIPSOpcode op) {
|
||||
void Int_FPULS(MIPSState *mips, MIPSOpcode op) {
|
||||
s32 offset = (s16)(op & 0xFFFF);
|
||||
int ft = _FT;
|
||||
int rs = _RS;
|
||||
@@ -585,7 +585,7 @@ namespace MIPSInt
|
||||
PC += 4;
|
||||
}
|
||||
|
||||
void Int_mxc1(MIPSOpcode op)
|
||||
void Int_mxc1(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
int fs = _FS;
|
||||
int rt = _RT;
|
||||
@@ -599,8 +599,8 @@ namespace MIPSInt
|
||||
case 2: //cfc1
|
||||
if (rt != 0) {
|
||||
if (fs == 31) {
|
||||
currentMIPS->fcr31 = (currentMIPS->fcr31 & ~(1<<23)) | ((currentMIPS->fpcond & 1)<<23);
|
||||
R(rt) = currentMIPS->fcr31;
|
||||
mips->fcr31 = (mips->fcr31 & ~(1<<23)) | ((mips->fpcond & 1)<<23);
|
||||
R(rt) = mips->fcr31;
|
||||
} else if (fs == 0) {
|
||||
R(rt) = MIPSState::FCR0_VALUE;
|
||||
} else {
|
||||
@@ -619,8 +619,8 @@ namespace MIPSInt
|
||||
{
|
||||
u32 value = R(rt);
|
||||
if (fs == 31) {
|
||||
currentMIPS->fcr31 = value & 0x0181FFFF;
|
||||
currentMIPS->fpcond = (value >> 23) & 1;
|
||||
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) {
|
||||
// In case of DISABLE, we need to tell jit we updated FCR31.
|
||||
@@ -640,7 +640,7 @@ namespace MIPSInt
|
||||
PC += 4;
|
||||
}
|
||||
|
||||
void Int_RType2(MIPSOpcode op)
|
||||
void Int_RType2(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
int rs = _RS;
|
||||
int rd = _RD;
|
||||
@@ -667,7 +667,7 @@ namespace MIPSInt
|
||||
PC += 4;
|
||||
}
|
||||
|
||||
void Int_MulDivType(MIPSOpcode op)
|
||||
void Int_MulDivType(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
int rt = _RT;
|
||||
int rs = _RS;
|
||||
@@ -772,7 +772,7 @@ namespace MIPSInt
|
||||
}
|
||||
|
||||
|
||||
void Int_ShiftType(MIPSOpcode op)
|
||||
void Int_ShiftType(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
int rt = _RT;
|
||||
int rs = _RS;
|
||||
@@ -826,7 +826,7 @@ namespace MIPSInt
|
||||
PC += 4;
|
||||
}
|
||||
|
||||
void Int_Allegrex(MIPSOpcode op)
|
||||
void Int_Allegrex(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
int rt = _RT;
|
||||
int rd = _RD;
|
||||
@@ -859,7 +859,7 @@ namespace MIPSInt
|
||||
PC += 4;
|
||||
}
|
||||
|
||||
void Int_Allegrex2(MIPSOpcode op)
|
||||
void Int_Allegrex2(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
int rt = _RT;
|
||||
int rd = _RD;
|
||||
@@ -886,7 +886,7 @@ namespace MIPSInt
|
||||
PC += 4;
|
||||
}
|
||||
|
||||
void Int_Special2(MIPSOpcode op)
|
||||
void Int_Special2(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
static int reported = 0;
|
||||
switch (op & 0x3F)
|
||||
@@ -912,7 +912,7 @@ namespace MIPSInt
|
||||
PC += 4;
|
||||
}
|
||||
|
||||
void Int_Special3(MIPSOpcode op)
|
||||
void Int_Special3(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
int rs = _RS;
|
||||
int rt = _RT;
|
||||
@@ -945,7 +945,7 @@ namespace MIPSInt
|
||||
PC += 4;
|
||||
}
|
||||
|
||||
void Int_FPU2op(MIPSOpcode op)
|
||||
void Int_FPU2op(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
int fs = _FS;
|
||||
int fd = _FD;
|
||||
@@ -992,7 +992,7 @@ namespace MIPSInt
|
||||
FsI(fd) = my_isinf(F(fs)) && F(fs) < 0.0f ? -2147483648LL : 2147483647LL;
|
||||
break;
|
||||
}
|
||||
switch (currentMIPS->fcr31 & 3)
|
||||
switch (mips->fcr31 & 3)
|
||||
{
|
||||
case 0: FsI(fd) = (int)round_ieee_754(F(fs)); break; // RINT_0
|
||||
case 1: FsI(fd) = (int)F(fs); break; // CAST_1
|
||||
@@ -1007,7 +1007,7 @@ namespace MIPSInt
|
||||
PC += 4;
|
||||
}
|
||||
|
||||
void Int_FPUComp(MIPSOpcode op)
|
||||
void Int_FPUComp(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
int fs = _FS;
|
||||
int ft = _FT;
|
||||
@@ -1059,11 +1059,11 @@ namespace MIPSInt
|
||||
cond = false;
|
||||
break;
|
||||
}
|
||||
currentMIPS->fpcond = cond;
|
||||
mips->fpcond = cond;
|
||||
PC += 4;
|
||||
}
|
||||
|
||||
void Int_FPU3op(MIPSOpcode op)
|
||||
void Int_FPU3op(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
int ft = _FT;
|
||||
int fs = _FS;
|
||||
@@ -1089,7 +1089,7 @@ namespace MIPSInt
|
||||
PC += 4;
|
||||
}
|
||||
|
||||
void Int_Interrupt(MIPSOpcode op)
|
||||
void Int_Interrupt(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
static int reported = 0;
|
||||
switch (op & 1)
|
||||
@@ -1097,7 +1097,7 @@ namespace MIPSInt
|
||||
case 0:
|
||||
// unlikely to be legitimately used
|
||||
if (!reported) {
|
||||
Reporting::ReportMessage("INTERRUPT instruction hit (%08x) at %08x", op.encoding, currentMIPS->pc);
|
||||
Reporting::ReportMessage("INTERRUPT instruction hit (%08x) at %08x", op.encoding, mips->pc);
|
||||
WARN_LOG(Log::CPU, "Disable/Enable Interrupt CPU instruction");
|
||||
reported = 1;
|
||||
}
|
||||
@@ -1106,7 +1106,7 @@ namespace MIPSInt
|
||||
PC += 4;
|
||||
}
|
||||
|
||||
void Int_Emuhack(MIPSOpcode op)
|
||||
void Int_Emuhack(MIPSState *mips, MIPSOpcode op)
|
||||
{
|
||||
if (((op >> 24) & 3) != EMUOP_CALL_REPLACEMENT) {
|
||||
_dbg_assert_msg_(false, "Trying to interpret emuhack instruction that can't be interpreted");
|
||||
@@ -1122,20 +1122,20 @@ namespace MIPSInt
|
||||
|
||||
if (entry->flags & (REPFLAG_HOOKENTER | REPFLAG_HOOKEXIT)) {
|
||||
// Interpret the original instruction under the hook.
|
||||
MIPSInterpret(currentMIPS, Memory::Read_Instruction(PC, true));
|
||||
MIPSInterpret(mips, Memory::Read_Instruction(PC, true));
|
||||
} else if (cycles < 0) {
|
||||
// Leave PC unchanged, call the replacement again (assumes args are modified.)
|
||||
currentMIPS->downcount += cycles;
|
||||
mips->downcount += cycles;
|
||||
} else {
|
||||
PC = currentMIPS->r[MIPS_REG_RA];
|
||||
currentMIPS->downcount -= cycles;
|
||||
PC = mips->r[MIPS_REG_RA];
|
||||
mips->downcount -= cycles;
|
||||
}
|
||||
} else {
|
||||
if (!entry || !entry->replaceFunc) {
|
||||
ERROR_LOG(Log::CPU, "Bad replacement function index %i", index);
|
||||
}
|
||||
// Interpret the original instruction under it.
|
||||
MIPSInterpret(currentMIPS, Memory::Read_Instruction(PC, true));
|
||||
MIPSInterpret(mips, Memory::Read_Instruction(PC, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
+27
-27
@@ -24,32 +24,32 @@ int MIPS_SingleStep(MIPSState *mips);
|
||||
|
||||
namespace MIPSInt
|
||||
{
|
||||
void Int_Syscall(MIPSOpcode op);
|
||||
void Int_Syscall(MIPSState *mips, MIPSOpcode op);
|
||||
|
||||
void Int_mxc1(MIPSOpcode op);
|
||||
void Int_RelBranch(MIPSOpcode op);
|
||||
void Int_RelBranchRI(MIPSOpcode op);
|
||||
void Int_IType(MIPSOpcode op);
|
||||
void Int_ITypeMem(MIPSOpcode op);
|
||||
void Int_RType2(MIPSOpcode op);
|
||||
void Int_RType3(MIPSOpcode op);
|
||||
void Int_ShiftType(MIPSOpcode op);
|
||||
void Int_MulDivType(MIPSOpcode op);
|
||||
void Int_JumpType(MIPSOpcode op);
|
||||
void Int_JumpRegType(MIPSOpcode op);
|
||||
void Int_Allegrex2(MIPSOpcode op);
|
||||
void Int_FPULS(MIPSOpcode op);
|
||||
void Int_FPU3op(MIPSOpcode op);
|
||||
void Int_FPU2op(MIPSOpcode op);
|
||||
void Int_Allegrex(MIPSOpcode op);
|
||||
void Int_FPUComp(MIPSOpcode op);
|
||||
void Int_FPUBranch(MIPSOpcode op);
|
||||
void Int_Emuhack(MIPSOpcode op);
|
||||
void Int_Special2(MIPSOpcode op);
|
||||
void Int_Special3(MIPSOpcode op);
|
||||
void Int_Interrupt(MIPSOpcode op);
|
||||
void Int_Cache(MIPSOpcode op);
|
||||
void Int_Sync(MIPSOpcode op);
|
||||
void Int_Break(MIPSOpcode op);
|
||||
void Int_StoreSync(MIPSOpcode op);
|
||||
void Int_mxc1(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_RelBranch(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_RelBranchRI(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_IType(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_ITypeMem(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_RType2(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_RType3(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_ShiftType(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_MulDivType(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_JumpType(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_JumpRegType(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Allegrex2(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_FPULS(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_FPU3op(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_FPU2op(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Allegrex(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_FPUComp(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_FPUBranch(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Emuhack(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Special2(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Special3(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Interrupt(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Cache(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Sync(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Break(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_StoreSync(MIPSState *mips, MIPSOpcode op);
|
||||
}
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
// Returns the cycle count consumed, or -1 if op isn't a recognized instruction -
|
||||
// callers must fall back to MIPSInterpret() themselves in that case.
|
||||
int ExecInstruction(MIPSOpcode op) {
|
||||
int ExecInstruction(MIPSState *mips, MIPSOpcode op) {
|
||||
switch ((op.encoding >> 26) & 0x3f) {
|
||||
case 0:
|
||||
{
|
||||
@@ -36,12 +36,12 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
case 4:
|
||||
case 6:
|
||||
case 7:
|
||||
MIPSInt::Int_ShiftType(op);
|
||||
MIPSInt::Int_ShiftType(mips, op);
|
||||
return 1;
|
||||
// jr, jalr
|
||||
case 8:
|
||||
case 9:
|
||||
MIPSInt::Int_JumpRegType(op);
|
||||
MIPSInt::Int_JumpRegType(mips, op);
|
||||
return 1;
|
||||
// movz, movn, add, addu, sub, subu, and, or, xor, nor, slt, sltu, max, min
|
||||
case 10:
|
||||
@@ -58,19 +58,19 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
case 43:
|
||||
case 44:
|
||||
case 45:
|
||||
MIPSInt::Int_RType3(op);
|
||||
MIPSInt::Int_RType3(mips, op);
|
||||
return 1;
|
||||
// syscall
|
||||
case 12:
|
||||
MIPSInt::Int_Syscall(op);
|
||||
MIPSInt::Int_Syscall(mips, op);
|
||||
return 1;
|
||||
// break
|
||||
case 13:
|
||||
MIPSInt::Int_Break(op);
|
||||
MIPSInt::Int_Break(mips, op);
|
||||
return 1;
|
||||
// sync
|
||||
case 15:
|
||||
MIPSInt::Int_Sync(op);
|
||||
MIPSInt::Int_Sync(mips, op);
|
||||
return 1;
|
||||
// mfhi, mthi, mflo, mtlo, mult, multu, div, divu, madd, maddu, msub, msubu
|
||||
case 16:
|
||||
@@ -85,12 +85,12 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
case 29:
|
||||
case 46:
|
||||
case 47:
|
||||
MIPSInt::Int_MulDivType(op);
|
||||
MIPSInt::Int_MulDivType(mips, op);
|
||||
return 1;
|
||||
// clz, clo
|
||||
case 22:
|
||||
case 23:
|
||||
MIPSInt::Int_RType2(op);
|
||||
MIPSInt::Int_RType2(mips, op);
|
||||
return 1;
|
||||
default:
|
||||
return -1;
|
||||
@@ -108,7 +108,7 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
case 17:
|
||||
case 18:
|
||||
case 19:
|
||||
MIPSInt::Int_RelBranchRI(op);
|
||||
MIPSInt::Int_RelBranchRI(mips, op);
|
||||
return 1;
|
||||
default:
|
||||
return -1;
|
||||
@@ -117,7 +117,7 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
// j, jal
|
||||
case 2:
|
||||
case 3:
|
||||
MIPSInt::Int_JumpType(op);
|
||||
MIPSInt::Int_JumpType(mips, op);
|
||||
return 1;
|
||||
// beq, bne, blez, bgtz, beql, bnel, blezl, bgtzl
|
||||
case 4:
|
||||
@@ -128,7 +128,7 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
case 21:
|
||||
case 22:
|
||||
case 23:
|
||||
MIPSInt::Int_RelBranch(op);
|
||||
MIPSInt::Int_RelBranch(mips, op);
|
||||
return 1;
|
||||
// addi, addiu, slti, sltiu, andi, ori, xori, lui
|
||||
case 8:
|
||||
@@ -139,7 +139,7 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
MIPSInt::Int_IType(op);
|
||||
MIPSInt::Int_IType(mips, op);
|
||||
return 1;
|
||||
case 16:
|
||||
{
|
||||
@@ -175,7 +175,7 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
case 2:
|
||||
case 4:
|
||||
case 6:
|
||||
MIPSInt::Int_mxc1(op);
|
||||
MIPSInt::Int_mxc1(mips, op);
|
||||
return 1;
|
||||
case 8:
|
||||
{
|
||||
@@ -185,7 +185,7 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
MIPSInt::Int_FPUBranch(op);
|
||||
MIPSInt::Int_FPUBranch(mips, op);
|
||||
return 1;
|
||||
default:
|
||||
return -1;
|
||||
@@ -198,11 +198,11 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
MIPSInt::Int_FPU3op(op);
|
||||
MIPSInt::Int_FPU3op(mips, op);
|
||||
return 1;
|
||||
// div.s
|
||||
case 3:
|
||||
MIPSInt::Int_FPU3op(op);
|
||||
MIPSInt::Int_FPU3op(mips, op);
|
||||
return 29;
|
||||
// sqrt.s, abs.s, mov.s, neg.s, round.w.s, trunc.w.s, ceil.w.s, floor.w.s, cvt.w.s
|
||||
case 4:
|
||||
@@ -214,11 +214,11 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
case 14:
|
||||
case 15:
|
||||
case 36:
|
||||
MIPSInt::Int_FPU2op(op);
|
||||
MIPSInt::Int_FPU2op(mips, op);
|
||||
return 1;
|
||||
// dis.int
|
||||
case 38:
|
||||
MIPSInt::Int_Interrupt(op);
|
||||
MIPSInt::Int_Interrupt(mips, op);
|
||||
return 1;
|
||||
// c.f.s, c.un.s, c.eq.s, c.ueq.s, c.olt.s, c.ult.s, c.ole.s, c.ule.s, c.sf.s, c.ngle.s, c.seq.s, c.ngl.s, c.lt.s, c.nge.s, c.le.s, c.ngt.s
|
||||
case 48:
|
||||
@@ -237,7 +237,7 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
case 61:
|
||||
case 62:
|
||||
case 63:
|
||||
MIPSInt::Int_FPUComp(op);
|
||||
MIPSInt::Int_FPUComp(mips, op);
|
||||
return 1;
|
||||
default:
|
||||
return -1;
|
||||
@@ -248,7 +248,7 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
switch ((op.encoding >> 0) & 0x3f) {
|
||||
// cvt.s.w
|
||||
case 32:
|
||||
MIPSInt::Int_FPU2op(op);
|
||||
MIPSInt::Int_FPU2op(mips, op);
|
||||
return 1;
|
||||
default:
|
||||
return -1;
|
||||
@@ -264,7 +264,7 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
// mfv, mtv
|
||||
case 3:
|
||||
case 7:
|
||||
MIPSInt::Int_Mftv(op);
|
||||
MIPSInt::Int_Mftv(mips, op);
|
||||
return 2;
|
||||
case 8:
|
||||
{
|
||||
@@ -274,7 +274,7 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
MIPSInt::Int_VBranch(op);
|
||||
MIPSInt::Int_VBranch(mips, op);
|
||||
return 2;
|
||||
default:
|
||||
return -1;
|
||||
@@ -291,11 +291,11 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 7:
|
||||
MIPSInt::Int_VecDo3(op);
|
||||
MIPSInt::Int_VecDo3(mips, op);
|
||||
return 2;
|
||||
// vsbn
|
||||
case 2:
|
||||
MIPSInt::Int_Vsbn(op);
|
||||
MIPSInt::Int_Vsbn(mips, op);
|
||||
return 2;
|
||||
default:
|
||||
return -1;
|
||||
@@ -306,27 +306,27 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
switch ((op.encoding >> 23) & 0x7) {
|
||||
// vmul
|
||||
case 0:
|
||||
MIPSInt::Int_VecDo3(op);
|
||||
MIPSInt::Int_VecDo3(mips, op);
|
||||
return 2;
|
||||
// vdot
|
||||
case 1:
|
||||
MIPSInt::Int_VDot(op);
|
||||
MIPSInt::Int_VDot(mips, op);
|
||||
return 2;
|
||||
// vscl
|
||||
case 2:
|
||||
MIPSInt::Int_VScl(op);
|
||||
MIPSInt::Int_VScl(mips, op);
|
||||
return 2;
|
||||
// vhdp
|
||||
case 4:
|
||||
MIPSInt::Int_VHdp(op);
|
||||
MIPSInt::Int_VHdp(mips, op);
|
||||
return 2;
|
||||
// vcrs
|
||||
case 5:
|
||||
MIPSInt::Int_Vcrs(op);
|
||||
MIPSInt::Int_Vcrs(mips, op);
|
||||
return 2;
|
||||
// vdet
|
||||
case 6:
|
||||
MIPSInt::Int_Vdet(op);
|
||||
MIPSInt::Int_Vdet(mips, op);
|
||||
return 2;
|
||||
default:
|
||||
return -1;
|
||||
@@ -337,12 +337,12 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
switch ((op.encoding >> 24) & 0x3) {
|
||||
// RUNBLOCK
|
||||
case 0:
|
||||
MIPSInt::Int_Emuhack(op);
|
||||
MIPSInt::Int_Emuhack(mips, op);
|
||||
return 2;
|
||||
// RetKrnl, CallRepl
|
||||
case 1:
|
||||
case 2:
|
||||
MIPSInt::Int_Emuhack(op);
|
||||
MIPSInt::Int_Emuhack(mips, op);
|
||||
return 1;
|
||||
default:
|
||||
return -1;
|
||||
@@ -353,24 +353,24 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
switch ((op.encoding >> 23) & 0x7) {
|
||||
// vcmp
|
||||
case 0:
|
||||
MIPSInt::Int_Vcmp(op);
|
||||
MIPSInt::Int_Vcmp(mips, op);
|
||||
return 2;
|
||||
// vmin, vmax
|
||||
case 2:
|
||||
case 3:
|
||||
MIPSInt::Int_Vminmax(op);
|
||||
MIPSInt::Int_Vminmax(mips, op);
|
||||
return 2;
|
||||
// vscmp
|
||||
case 5:
|
||||
MIPSInt::Int_Vscmp(op);
|
||||
MIPSInt::Int_Vscmp(mips, op);
|
||||
return 2;
|
||||
// vsge
|
||||
case 6:
|
||||
MIPSInt::Int_Vsge(op);
|
||||
MIPSInt::Int_Vsge(mips, op);
|
||||
return 2;
|
||||
// vslt
|
||||
case 7:
|
||||
MIPSInt::Int_Vslt(op);
|
||||
MIPSInt::Int_Vslt(mips, op);
|
||||
return 2;
|
||||
default:
|
||||
return -1;
|
||||
@@ -382,7 +382,7 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
// mfic, mtic
|
||||
case 36:
|
||||
case 38:
|
||||
MIPSInt::Int_Special2(op);
|
||||
MIPSInt::Int_Special2(mips, op);
|
||||
return 1;
|
||||
default:
|
||||
return -1;
|
||||
@@ -394,7 +394,7 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
// ext, ins
|
||||
case 0:
|
||||
case 4:
|
||||
MIPSInt::Int_Special3(op);
|
||||
MIPSInt::Int_Special3(mips, op);
|
||||
return 1;
|
||||
case 24:
|
||||
case 32:
|
||||
@@ -403,13 +403,13 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
// wsbh, wsbw
|
||||
case 2:
|
||||
case 3:
|
||||
MIPSInt::Int_Allegrex2(op);
|
||||
MIPSInt::Int_Allegrex2(mips, op);
|
||||
return 1;
|
||||
// seb, bitrev, seh
|
||||
case 16:
|
||||
case 20:
|
||||
case 24:
|
||||
MIPSInt::Int_Allegrex(op);
|
||||
MIPSInt::Int_Allegrex(mips, op);
|
||||
return 1;
|
||||
default:
|
||||
return -1;
|
||||
@@ -432,26 +432,26 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
case 42:
|
||||
case 43:
|
||||
case 46:
|
||||
MIPSInt::Int_ITypeMem(op);
|
||||
MIPSInt::Int_ITypeMem(mips, op);
|
||||
return 1;
|
||||
// cache
|
||||
case 47:
|
||||
MIPSInt::Int_Cache(op);
|
||||
MIPSInt::Int_Cache(mips, op);
|
||||
return 1;
|
||||
// ll, sc
|
||||
case 48:
|
||||
case 56:
|
||||
MIPSInt::Int_StoreSync(op);
|
||||
MIPSInt::Int_StoreSync(mips, op);
|
||||
return 1;
|
||||
// lwc1, swc1
|
||||
case 49:
|
||||
case 57:
|
||||
MIPSInt::Int_FPULS(op);
|
||||
MIPSInt::Int_FPULS(mips, op);
|
||||
return 1;
|
||||
// lv.s, sv.s
|
||||
case 50:
|
||||
case 58:
|
||||
MIPSInt::Int_SV(op);
|
||||
MIPSInt::Int_SV(mips, op);
|
||||
return 2;
|
||||
case 52:
|
||||
{
|
||||
@@ -476,16 +476,16 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
case 24:
|
||||
case 26:
|
||||
case 28:
|
||||
MIPSInt::Int_VV2Op(op);
|
||||
MIPSInt::Int_VV2Op(mips, op);
|
||||
return 2;
|
||||
// vidt
|
||||
case 3:
|
||||
MIPSInt::Int_Vidt(op);
|
||||
MIPSInt::Int_Vidt(mips, op);
|
||||
return 2;
|
||||
// vzero, vone
|
||||
case 6:
|
||||
case 7:
|
||||
MIPSInt::Int_VVectorInit(op);
|
||||
MIPSInt::Int_VVectorInit(mips, op);
|
||||
return 2;
|
||||
default:
|
||||
return -1;
|
||||
@@ -496,43 +496,43 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
switch ((op.encoding >> 16) & 0x1f) {
|
||||
// vrnds
|
||||
case 0:
|
||||
MIPSInt::Int_Vrnds(op);
|
||||
MIPSInt::Int_Vrnds(mips, op);
|
||||
return 2;
|
||||
// vrndi, vrndf1, vrndf2
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
MIPSInt::Int_VrndX(op);
|
||||
MIPSInt::Int_VrndX(mips, op);
|
||||
return 2;
|
||||
// vf2h
|
||||
case 18:
|
||||
MIPSInt::Int_Vf2h(op);
|
||||
MIPSInt::Int_Vf2h(mips, op);
|
||||
return 2;
|
||||
// vh2f
|
||||
case 19:
|
||||
MIPSInt::Int_Vh2f(op);
|
||||
MIPSInt::Int_Vh2f(mips, op);
|
||||
return 2;
|
||||
// vsbz
|
||||
case 22:
|
||||
MIPSInt::Int_Vsbz(op);
|
||||
MIPSInt::Int_Vsbz(mips, op);
|
||||
return 2;
|
||||
// vlgb
|
||||
case 23:
|
||||
MIPSInt::Int_Vlgb(op);
|
||||
MIPSInt::Int_Vlgb(mips, op);
|
||||
return 2;
|
||||
// vuc2ifs, vc2i, vus2i, vs2i
|
||||
case 24:
|
||||
case 25:
|
||||
case 26:
|
||||
case 27:
|
||||
MIPSInt::Int_Vx2i(op);
|
||||
MIPSInt::Int_Vx2i(mips, op);
|
||||
return 2;
|
||||
// vi2uc, vi2c, vi2us, vi2s
|
||||
case 28:
|
||||
case 29:
|
||||
case 30:
|
||||
case 31:
|
||||
MIPSInt::Int_Vi2x(op);
|
||||
MIPSInt::Int_Vi2x(mips, op);
|
||||
return 2;
|
||||
default:
|
||||
return -1;
|
||||
@@ -543,58 +543,58 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
switch ((op.encoding >> 16) & 0x1f) {
|
||||
// vsrt1
|
||||
case 0:
|
||||
MIPSInt::Int_Vsrt1(op);
|
||||
MIPSInt::Int_Vsrt1(mips, op);
|
||||
return 2;
|
||||
// vsrt2
|
||||
case 1:
|
||||
MIPSInt::Int_Vsrt2(op);
|
||||
MIPSInt::Int_Vsrt2(mips, op);
|
||||
return 2;
|
||||
// vbfy1, vbfy2
|
||||
case 2:
|
||||
case 3:
|
||||
MIPSInt::Int_Vbfy(op);
|
||||
MIPSInt::Int_Vbfy(mips, op);
|
||||
return 2;
|
||||
// vocp
|
||||
case 4:
|
||||
MIPSInt::Int_Vocp(op);
|
||||
MIPSInt::Int_Vocp(mips, op);
|
||||
return 2;
|
||||
// vsocp
|
||||
case 5:
|
||||
MIPSInt::Int_Vsocp(op);
|
||||
MIPSInt::Int_Vsocp(mips, op);
|
||||
return 2;
|
||||
// vfad
|
||||
case 6:
|
||||
MIPSInt::Int_Vfad(op);
|
||||
MIPSInt::Int_Vfad(mips, op);
|
||||
return 2;
|
||||
// vavg
|
||||
case 7:
|
||||
MIPSInt::Int_Vavg(op);
|
||||
MIPSInt::Int_Vavg(mips, op);
|
||||
return 2;
|
||||
// vsrt3
|
||||
case 8:
|
||||
MIPSInt::Int_Vsrt3(op);
|
||||
MIPSInt::Int_Vsrt3(mips, op);
|
||||
return 2;
|
||||
// vsrt4
|
||||
case 9:
|
||||
MIPSInt::Int_Vsrt4(op);
|
||||
MIPSInt::Int_Vsrt4(mips, op);
|
||||
return 2;
|
||||
// vsgn
|
||||
case 10:
|
||||
MIPSInt::Int_Vsgn(op);
|
||||
MIPSInt::Int_Vsgn(mips, op);
|
||||
return 2;
|
||||
// vmfvc
|
||||
case 16:
|
||||
MIPSInt::Int_Vmfvc(op);
|
||||
MIPSInt::Int_Vmfvc(mips, op);
|
||||
return 2;
|
||||
// vmtvc
|
||||
case 17:
|
||||
MIPSInt::Int_Vmtvc(op);
|
||||
MIPSInt::Int_Vmtvc(mips, op);
|
||||
return 2;
|
||||
// vt4444, vt5551, vt5650
|
||||
case 25:
|
||||
case 26:
|
||||
case 27:
|
||||
MIPSInt::Int_ColorConv(op);
|
||||
MIPSInt::Int_ColorConv(mips, op);
|
||||
return 2;
|
||||
default:
|
||||
return -1;
|
||||
@@ -602,22 +602,22 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
}
|
||||
// vcst
|
||||
case 3:
|
||||
MIPSInt::Int_Vcst(op);
|
||||
MIPSInt::Int_Vcst(mips, op);
|
||||
return 2;
|
||||
// vf2in, vf2iz, vf2iu, vf2id
|
||||
case 16:
|
||||
case 17:
|
||||
case 18:
|
||||
case 19:
|
||||
MIPSInt::Int_Vf2i(op);
|
||||
MIPSInt::Int_Vf2i(mips, op);
|
||||
return 2;
|
||||
// vi2f
|
||||
case 20:
|
||||
MIPSInt::Int_Vi2f(op);
|
||||
MIPSInt::Int_Vi2f(mips, op);
|
||||
return 2;
|
||||
// vcmov
|
||||
case 21:
|
||||
MIPSInt::Int_Vcmov(op);
|
||||
MIPSInt::Int_Vcmov(mips, op);
|
||||
return 2;
|
||||
// vwbn, vwbn, vwbn, vwbn, vwbn, vwbn, vwbn, vwbn
|
||||
case 24:
|
||||
@@ -628,7 +628,7 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
case 29:
|
||||
case 30:
|
||||
case 31:
|
||||
MIPSInt::Int_Vwbn(op);
|
||||
MIPSInt::Int_Vwbn(mips, op);
|
||||
return 2;
|
||||
default:
|
||||
return -1;
|
||||
@@ -639,7 +639,7 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
case 54:
|
||||
case 61:
|
||||
case 62:
|
||||
MIPSInt::Int_SVQ(op);
|
||||
MIPSInt::Int_SVQ(mips, op);
|
||||
return 2;
|
||||
case 55:
|
||||
{
|
||||
@@ -651,12 +651,12 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
MIPSInt::Int_VPFX(op);
|
||||
MIPSInt::Int_VPFX(mips, op);
|
||||
return 2;
|
||||
// viim.s, vfim.s
|
||||
case 6:
|
||||
case 7:
|
||||
MIPSInt::Int_Viim(op);
|
||||
MIPSInt::Int_Viim(mips, op);
|
||||
return 2;
|
||||
default:
|
||||
return -1;
|
||||
@@ -670,7 +670,7 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
MIPSInt::Int_Vmmul(op);
|
||||
MIPSInt::Int_Vmmul(mips, op);
|
||||
return 2;
|
||||
// v(h)tfm2, v(h)tfm2, v(h)tfm2, v(h)tfm2, v(h)tfm3, v(h)tfm3, v(h)tfm3, v(h)tfm3, v(h)tfm4, v(h)tfm4, v(h)tfm4, v(h)tfm4
|
||||
case 4:
|
||||
@@ -685,34 +685,34 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
MIPSInt::Int_Vtfm(op);
|
||||
MIPSInt::Int_Vtfm(mips, op);
|
||||
return 2;
|
||||
// vmscl, vmscl, vmscl, vmscl
|
||||
case 16:
|
||||
case 17:
|
||||
case 18:
|
||||
case 19:
|
||||
MIPSInt::Int_Vmscl(op);
|
||||
MIPSInt::Int_Vmscl(mips, op);
|
||||
return 2;
|
||||
// vcrsp.t/vqmul.q, vcrsp.t/vqmul.q, vcrsp.t/vqmul.q, vcrsp.t/vqmul.q
|
||||
case 20:
|
||||
case 21:
|
||||
case 22:
|
||||
case 23:
|
||||
MIPSInt::Int_CrossQuat(op);
|
||||
MIPSInt::Int_CrossQuat(mips, op);
|
||||
return 2;
|
||||
case 28:
|
||||
{
|
||||
switch ((op.encoding >> 16) & 0xf) {
|
||||
// vmmov
|
||||
case 0:
|
||||
MIPSInt::Int_Vmmov(op);
|
||||
MIPSInt::Int_Vmmov(mips, op);
|
||||
return 2;
|
||||
// vmidt, vmzero, vmone
|
||||
case 3:
|
||||
case 6:
|
||||
case 7:
|
||||
MIPSInt::Int_VMatrixInit(op);
|
||||
MIPSInt::Int_VMatrixInit(mips, op);
|
||||
return 2;
|
||||
default:
|
||||
return -1;
|
||||
@@ -720,7 +720,7 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
}
|
||||
// vrot
|
||||
case 29:
|
||||
MIPSInt::Int_Vrot(op);
|
||||
MIPSInt::Int_Vrot(mips, op);
|
||||
return 2;
|
||||
default:
|
||||
return -1;
|
||||
@@ -728,7 +728,7 @@ int ExecInstruction(MIPSOpcode op) {
|
||||
}
|
||||
// vflush
|
||||
case 63:
|
||||
MIPSInt::Int_Vflush(op);
|
||||
MIPSInt::Int_Vflush(mips, op);
|
||||
return 2;
|
||||
default:
|
||||
return -1;
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
#include "Core/MIPS/MIPS.h"
|
||||
|
||||
// Fast switch-tree interpreter dispatcher, generated into InterpreterDispatch.cpp by
|
||||
// GenerateInterpreterDispatch() in MIPSTables.cpp. Executes op on the global currentMIPS
|
||||
// (same convention as the MIPSInt::Int_* handlers it calls into) and returns the number of
|
||||
// cycles it consumed - or -1 if op isn't a recognized instruction (an invalid encoding, or
|
||||
// one of the handful of real instructions with no interpreter implementation, e.g.
|
||||
// tge/tlt/teq/...). Not total by design: the caller must fall back to MIPSInterpret() on a
|
||||
// negative return, since deciding what "unhandled" means is a caller policy, not something
|
||||
// a mechanically generated dispatch tree should embed.
|
||||
int ExecInstruction(MIPSOpcode op);
|
||||
// GenerateInterpreterDispatch() in MIPSTables.cpp. Executes op on mips (same convention as
|
||||
// the MIPSInt::Int_* handlers it calls into) and returns the number of cycles it consumed -
|
||||
// or -1 if op isn't a recognized instruction (an invalid encoding, or one of the handful of
|
||||
// real instructions with no interpreter implementation, e.g. tge/tlt/teq/...). Not total by
|
||||
// design: the caller must fall back to MIPSInterpret() on a negative return, since deciding
|
||||
// what "unhandled" means is a caller policy, not something a mechanically generated dispatch
|
||||
// tree should embed.
|
||||
int ExecInstruction(MIPSState *mips, MIPSOpcode op);
|
||||
+309
-308
File diff suppressed because it is too large.
Load diff
+55
-57
@@ -20,63 +20,61 @@
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/MIPS/MIPS.h"
|
||||
|
||||
int MIPS_SingleStep();
|
||||
|
||||
namespace MIPSInt
|
||||
{
|
||||
void Int_SV(MIPSOpcode op);
|
||||
void Int_SVQ(MIPSOpcode op);
|
||||
void Int_Mftv(MIPSOpcode op);
|
||||
void Int_VecDo3(MIPSOpcode op);
|
||||
void Int_Vcst(MIPSOpcode op);
|
||||
void Int_VMatrixInit(MIPSOpcode op);
|
||||
void Int_VVectorInit(MIPSOpcode op);
|
||||
void Int_Vmmul(MIPSOpcode op);
|
||||
void Int_Vmscl(MIPSOpcode op);
|
||||
void Int_Vmmov(MIPSOpcode op);
|
||||
void Int_VV2Op(MIPSOpcode op);
|
||||
void Int_Vrot(MIPSOpcode op);
|
||||
void Int_VDot(MIPSOpcode op);
|
||||
void Int_VHdp(MIPSOpcode op);
|
||||
void Int_Vavg(MIPSOpcode op);
|
||||
void Int_Vfad(MIPSOpcode op);
|
||||
void Int_Vocp(MIPSOpcode op);
|
||||
void Int_Vsocp(MIPSOpcode op);
|
||||
void Int_Vsgn(MIPSOpcode op);
|
||||
void Int_Vtfm(MIPSOpcode op);
|
||||
void Int_Viim(MIPSOpcode op);
|
||||
void Int_VScl(MIPSOpcode op);
|
||||
void Int_Vidt(MIPSOpcode op);
|
||||
void Int_Vcmp(MIPSOpcode op);
|
||||
void Int_Vminmax(MIPSOpcode op);
|
||||
void Int_Vscmp(MIPSOpcode op);
|
||||
void Int_Vcrs(MIPSOpcode op);
|
||||
void Int_Vdet(MIPSOpcode op);
|
||||
void Int_Vcmov(MIPSOpcode op);
|
||||
void Int_CrossQuat(MIPSOpcode op);
|
||||
void Int_VPFX(MIPSOpcode op);
|
||||
void Int_Vflush(MIPSOpcode op);
|
||||
void Int_Vbfy(MIPSOpcode op);
|
||||
void Int_Vsrt1(MIPSOpcode op);
|
||||
void Int_Vsrt2(MIPSOpcode op);
|
||||
void Int_Vsrt3(MIPSOpcode op);
|
||||
void Int_Vsrt4(MIPSOpcode op);
|
||||
void Int_Vf2i(MIPSOpcode op);
|
||||
void Int_Vi2f(MIPSOpcode op);
|
||||
void Int_Vi2x(MIPSOpcode op);
|
||||
void Int_Vx2i(MIPSOpcode op);
|
||||
void Int_VBranch(MIPSOpcode op);
|
||||
void Int_Vrnds(MIPSOpcode op);
|
||||
void Int_VrndX(MIPSOpcode op);
|
||||
void Int_ColorConv(MIPSOpcode op);
|
||||
void Int_Vh2f(MIPSOpcode op);
|
||||
void Int_Vf2h(MIPSOpcode op);
|
||||
void Int_Vsge(MIPSOpcode op);
|
||||
void Int_Vslt(MIPSOpcode op);
|
||||
void Int_Vmfvc(MIPSOpcode op);
|
||||
void Int_Vmtvc(MIPSOpcode op);
|
||||
void Int_Vlgb(MIPSOpcode op);
|
||||
void Int_Vwbn(MIPSOpcode op);
|
||||
void Int_Vsbn(MIPSOpcode op);
|
||||
void Int_Vsbz(MIPSOpcode op);
|
||||
void Int_SV(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_SVQ(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Mftv(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_VecDo3(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vcst(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_VMatrixInit(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_VVectorInit(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vmmul(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vmscl(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vmmov(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_VV2Op(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vrot(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_VDot(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_VHdp(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vavg(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vfad(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vocp(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vsocp(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vsgn(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vtfm(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Viim(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_VScl(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vidt(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vcmp(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vminmax(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vscmp(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vcrs(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vdet(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vcmov(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_CrossQuat(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_VPFX(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vflush(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vbfy(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vsrt1(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vsrt2(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vsrt3(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vsrt4(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vf2i(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vi2f(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vi2x(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vx2i(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_VBranch(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vrnds(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_VrndX(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_ColorConv(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vh2f(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vf2h(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vsge(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vslt(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vmfvc(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vmtvc(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vlgb(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vwbn(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vsbn(MIPSState *mips, MIPSOpcode op);
|
||||
void Int_Vsbz(MIPSState *mips, MIPSOpcode op);
|
||||
}
|
||||
@@ -259,7 +259,7 @@ void LoongArch64JitBackend::CompIR_Interpret(IRInst inst) {
|
||||
QuickCallFunction(&NotifyMIPSInterpret, SCRATCH2);
|
||||
}
|
||||
LI(R4, (int32_t)inst.constant);
|
||||
QuickCallFunction((const u8 *)MIPSGetInterpretFunc(op), SCRATCH2);
|
||||
QuickCallFunction((const u8 *)&MIPSInterpretTrampoline, SCRATCH2);
|
||||
WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT);
|
||||
LoadStaticRegisters();
|
||||
}
|
||||
|
||||
+19
-14
@@ -976,7 +976,7 @@ static void EmitDispatchLevel(std::string &out, MipsEncoding encoding, int inden
|
||||
out += ind + StringFromFormat("// %s\n", names.c_str());
|
||||
for (u32 idx : group)
|
||||
out += ind + StringFromFormat("case %d:\n", idx);
|
||||
out += ind2 + StringFromFormat("MIPSInt::%s(op);\n", instr.interpretName);
|
||||
out += ind2 + StringFromFormat("MIPSInt::%s(mips, op);\n", instr.interpretName);
|
||||
out += ind2 + StringFromFormat("return %d;\n", (int)instr.flags.cycles);
|
||||
} else {
|
||||
for (u32 idx : group)
|
||||
@@ -985,7 +985,7 @@ static void EmitDispatchLevel(std::string &out, MipsEncoding encoding, int inden
|
||||
EmitDispatchLevel(out, instr.altEncoding, indent + 1);
|
||||
out += ind + "}\n";
|
||||
// No trailing return here - the nested switch above always either returns
|
||||
// a value directly from a case, or falls to its own default's "goto slow_path;".
|
||||
// a value directly from a case, or falls to its own default's "return -1;".
|
||||
}
|
||||
}
|
||||
|
||||
@@ -995,15 +995,15 @@ static void EmitDispatchLevel(std::string &out, MipsEncoding encoding, int inden
|
||||
}
|
||||
|
||||
// Generates a full, compilable Core/MIPS/InterpreterDispatch.cpp: a fast
|
||||
// int ExecInstruction(MIPSOpcode op) dispatcher, built by resolving the tables above into
|
||||
// a nested switch tree at generation time, so each real instruction is reached by a direct
|
||||
// call instead of MIPSGetInstruction()'s per-instruction table walk plus indirect call
|
||||
// through instr->interpret. Leaves call straight into the existing MIPSInt::Int_* handlers
|
||||
// - the tables only record which handler an opcode maps to, not the handler's behavior, so
|
||||
// that's the only thing there is to call - and return that instruction's fixed cycle count
|
||||
// (baked in at generation time, same value MIPSGetInstructionCycleEstimate() would have
|
||||
// returned) so the caller can still track downcount. Operates on the global currentMIPS,
|
||||
// same as the Int_* handlers do.
|
||||
// int ExecInstruction(MIPSState *mips, MIPSOpcode op) dispatcher, built by resolving the
|
||||
// tables above into a nested switch tree at generation time, so each real instruction is
|
||||
// reached by a direct call instead of MIPSGetInstruction()'s per-instruction table walk plus
|
||||
// indirect call through instr->interpret. Leaves call straight into the existing
|
||||
// MIPSInt::Int_* handlers - the tables only record which handler an opcode maps to, not the
|
||||
// handler's behavior, so that's the only thing there is to call - and return that
|
||||
// instruction's fixed cycle count (baked in at generation time, same value
|
||||
// MIPSGetInstructionCycleEstimate() would have returned) so the caller can still track
|
||||
// downcount.
|
||||
//
|
||||
// The generated function is deliberately not total: most of the 32-bit opcode space doesn't
|
||||
// decode to anything (either a genuinely invalid encoding, or a real-but-uninterpreted
|
||||
@@ -1036,7 +1036,7 @@ std::string GenerateInterpreterDispatch() {
|
||||
out += "#include \"Core/MIPS/InterpreterVFPU.h\"\n\n";
|
||||
out += "// Returns the cycle count consumed, or -1 if op isn't a recognized instruction -\n";
|
||||
out += "// callers must fall back to MIPSInterpret() themselves in that case.\n";
|
||||
out += "int ExecInstruction(MIPSOpcode op) {\n";
|
||||
out += "int ExecInstruction(MIPSState *mips, MIPSOpcode op) {\n";
|
||||
EmitDispatchLevel(out, Imme, 1);
|
||||
out += "}\n";
|
||||
return out;
|
||||
@@ -1097,7 +1097,7 @@ static void HandleUnknownInstruction(MIPSState *mips, MIPSOpcode op) {
|
||||
|
||||
static inline void Interpret(MIPSState *mips, const MIPSInstruction *instr, MIPSOpcode op) {
|
||||
if (instr && instr->interpret) {
|
||||
instr->interpret(op);
|
||||
instr->interpret(mips, op);
|
||||
} else {
|
||||
HandleUnknownInstruction(mips, op);
|
||||
}
|
||||
@@ -1114,6 +1114,11 @@ void MIPSInterpret(MIPSState *mips, MIPSOpcode op) {
|
||||
Interpret(mips, instr, op);
|
||||
}
|
||||
|
||||
// See the declaration comment in MIPSTables.h.
|
||||
void CDECL MIPSInterpretTrampoline(MIPSOpcode op) {
|
||||
MIPSInterpret(currentMIPS, op);
|
||||
}
|
||||
|
||||
static inline void RunUntilFast(MIPSState *curMips) {
|
||||
// NEVER stop in a delay slot!
|
||||
while (curMips->downcount >= 0 && coreState == CORE_RUNNING_CPU) {
|
||||
@@ -1125,7 +1130,7 @@ static inline void RunUntilFast(MIPSState *curMips) {
|
||||
MIPSOpcode op = MIPSOpcode(Memory::ReadUnchecked_U32(curMips->pc));
|
||||
|
||||
bool wasInDelaySlot = curMips->inDelaySlot;
|
||||
int cycles = ExecInstruction(op);
|
||||
int cycles = ExecInstruction(curMips, op);
|
||||
if (cycles < 0) {
|
||||
// Not a recognized instruction (invalid encoding, or a known instruction
|
||||
// with no interpreter implementation, e.g. tge/tlt/teq/...). No point
|
||||
|
||||
+11
-3
@@ -122,7 +122,7 @@ struct MIPSInfo {
|
||||
};
|
||||
|
||||
typedef void (CDECL *MIPSDisFunc)(MIPSOpcode opcode, uint32_t pc, char *out, size_t outSize);
|
||||
typedef void (CDECL *MIPSInterpretFunc)(MIPSOpcode opcode);
|
||||
typedef void (CDECL *MIPSInterpretFunc)(MIPSState *mips, MIPSOpcode opcode);
|
||||
|
||||
namespace MIPSComp {
|
||||
class MIPSFrontendInterface;
|
||||
@@ -135,12 +135,20 @@ 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);
|
||||
|
||||
int MIPSGetInstructionCycleEstimate(MIPSOpcode op);
|
||||
int MIPSGetMemoryAccessSize(MIPSOpcode op);
|
||||
const char *MIPSGetName(MIPSOpcode op);
|
||||
std::string MIPSDisasmAt(u32 compilerPC);
|
||||
|
||||
// Generates the full contents of Core/MIPS/InterpreterDispatch.cpp: a fast switch-tree
|
||||
// int ExecInstruction(MIPSOpcode op) dispatcher, derived from the tables in MIPSTables.cpp.
|
||||
// See GenerateInterpreterDispatch()'s comment (in the .cpp) for details.
|
||||
// int ExecInstruction(MIPSState *mips, MIPSOpcode op) dispatcher, derived from the tables in
|
||||
// MIPSTables.cpp. See GenerateInterpreterDispatch()'s comment (in the .cpp) for details.
|
||||
std::string GenerateInterpreterDispatch();
|
||||
@@ -260,7 +260,7 @@ void RiscVJitBackend::CompIR_Interpret(IRInst inst) {
|
||||
QuickCallFunction(&NotifyMIPSInterpret, SCRATCH2);
|
||||
}
|
||||
LI(X10, (int32_t)inst.constant);
|
||||
QuickCallFunction((const u8 *)MIPSGetInterpretFunc(op), SCRATCH2);
|
||||
QuickCallFunction((const u8 *)&MIPSInterpretTrampoline, SCRATCH2);
|
||||
WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT);
|
||||
LoadStaticRegisters();
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ static void JitBranchLog(MIPSOpcode op, u32 pc) {
|
||||
|
||||
MIPSInterpretFunc func = MIPSGetInterpretFunc(op);
|
||||
MIPSInfo info = MIPSGetInfo(op);
|
||||
func(op);
|
||||
func(currentMIPS, op);
|
||||
|
||||
// Branch taken, use nextPC.
|
||||
if (currentMIPS->inDelaySlot)
|
||||
|
||||
@@ -111,7 +111,7 @@ static void JitLogMiss(MIPSOpcode op)
|
||||
notJitOps[MIPSGetName(op)]++;
|
||||
|
||||
MIPSInterpretFunc func = MIPSGetInterpretFunc(op);
|
||||
func(op);
|
||||
func(currentMIPS, op);
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@@ -626,7 +626,7 @@ void Jit::Comp_Generic(MIPSOpcode op) {
|
||||
if (USE_JIT_MISSMAP)
|
||||
ABI_CallFunctionC(&JitLogMiss, op.encoding);
|
||||
else
|
||||
ABI_CallFunctionC(func, op.encoding);
|
||||
ABI_CallFunctionC(&MIPSInterpretTrampoline, op.encoding);
|
||||
ApplyRoundingMode();
|
||||
} else {
|
||||
// These are basically always due to some kind of crash or corruption now.
|
||||
|
||||
@@ -256,7 +256,7 @@ void X64JitBackend::CompIR_Interpret(IRInst inst) {
|
||||
if (DebugStatsEnabled()) {
|
||||
ABI_CallFunctionP((const void *)&NotifyMIPSInterpret, (void *)MIPSGetName(op));
|
||||
}
|
||||
ABI_CallFunctionC((const void *)MIPSGetInterpretFunc(op), inst.constant);
|
||||
ABI_CallFunctionC((const void *)&MIPSInterpretTrampoline, inst.constant);
|
||||
WriteDebugProfilerStatus(IRProfilerStatus::IN_JIT);
|
||||
LoadStaticRegisters();
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ def main():
|
||||
|
||||
# Sanity check before clobbering the tracked file - a stale/broken binary should
|
||||
# fail loudly here rather than silently truncating InterpreterDispatch.cpp.
|
||||
if b"int ExecInstruction(MIPSOpcode op)" not in generated:
|
||||
if b"int ExecInstruction(MIPSState *mips, MIPSOpcode op)" not in generated:
|
||||
sys.stderr.write("error: generated output doesn't look right (missing ExecInstruction) - not overwriting %s\n" % OUT_PATH)
|
||||
return 1
|
||||
|
||||
|
||||
Reference in new issue
Block a user