Skip to content

Commit

Permalink
Merge pull request #19128 from hrydgard/more-ir-interpreter-tweaks
Browse files Browse the repository at this point in the history
More IR interpreter optimizations
  • Loading branch information
hrydgard committed May 11, 2024
2 parents ad541f2 + fae846e commit fcd48b7
Show file tree
Hide file tree
Showing 6 changed files with 42 additions and 26 deletions.
6 changes: 3 additions & 3 deletions Core/MIPS/IR/IRInst.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
// MIPS->target JITs.

enum class IROp : uint8_t {
Nop,

SetConst,
SetConstF,

Expand Down Expand Up @@ -230,6 +228,8 @@ enum class IROp : uint8_t {
ValidateAddress16,
ValidateAddress32,
ValidateAddress128,

Nop,
};

enum IRComparison {
Expand Down Expand Up @@ -358,7 +358,7 @@ struct IRInst {
};

// Returns the new PC.
u32 IRInterpret(MIPSState *ms, const IRInst *inst, int count);
u32 IRInterpret(MIPSState *ms, const IRInst *inst);

// Each IR block gets a constant pool.
class IRWriter {
Expand Down
22 changes: 10 additions & 12 deletions Core/MIPS/IR/IRInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,9 @@ u32 RunValidateAddress(u32 pc, u32 addr, u32 isWrite) {
}

// We cannot use NEON on ARM32 here until we make it a hard dependency. We can, however, on ARM64.
u32 IRInterpret(MIPSState *mips, const IRInst *inst, int count) {
const IRInst *end = inst + count;
while (inst != end) {
u32 IRInterpret(MIPSState *mips, const IRInst *inst) {
while (true) {
switch (inst->op) {
case IROp::Nop:
_assert_(false);
break;
case IROp::SetConst:
mips->r[inst->dest] = inst->constant;
break;
Expand Down Expand Up @@ -1121,19 +1117,21 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, int count) {
case IROp::UpdateRoundingMode:
// TODO: Implement
break;

case IROp::Nop:
_assert_(false);
break;
default:
// Unimplemented IR op. Bad.
Crash();
}
inst++;
}

#ifdef _DEBUG
if (mips->r[0] != 0)
Crash();
if (mips->r[0] != 0)
Crash();
#endif
inst++;
}

// We hit count. If this is a full block, it was badly constructed.
// We should not reach here anymore.
return 0;
}
2 changes: 1 addition & 1 deletion Core/MIPS/IR/IRInterpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ inline static u32 ReverseBits32(u32 v) {
u32 IRRunBreakpoint(u32 pc);
u32 IRRunMemCheck(u32 pc, u32 addr);

u32 IRInterpret(MIPSState *ms, const IRInst *inst, int count);
u32 IRInterpret(MIPSState *ms, const IRInst *inst);
16 changes: 9 additions & 7 deletions Core/MIPS/IR/IRJit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -246,21 +246,23 @@ void IRJit::RunLoopUntil(u64 globalticks) {
if (coreState != 0) {
break;
}
while (mips_->downcount >= 0) {
u32 inst = Memory::ReadUnchecked_U32(mips_->pc);

MIPSState *mips = mips_;

while (mips->downcount >= 0) {
u32 inst = Memory::ReadUnchecked_U32(mips->pc);
u32 opcode = inst & 0xFF000000;
if (opcode == MIPS_EMUHACK_OPCODE) {
IRBlock *block = blocks_.GetBlockUnchecked(inst & 0xFFFFFF);
u32 startPC = mips_->pc;
mips_->pc = IRInterpret(mips_, block->GetInstructions(), block->GetNumInstructions());
mips->pc = IRInterpret(mips, block->GetInstructions());
// Note: this will "jump to zero" on a badly constructed block missing exits.
if (!Memory::IsValidAddress(mips_->pc) || (mips_->pc & 3) != 0) {
Core_ExecException(mips_->pc, startPC, ExecExceptionType::JUMP);
if (!Memory::IsValid4AlignedAddress(mips->pc)) {
Core_ExecException(mips->pc, block->GetOriginalStart(), ExecExceptionType::JUMP);
break;
}
} else {
// RestoreRoundingMode(true);
Compile(mips_->pc);
Compile(mips->pc);
// ApplyRoundingMode(true);
}
}
Expand Down
7 changes: 4 additions & 3 deletions Core/MIPS/IR/IRNativeCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,14 @@ void IRNativeBackend::DoMIPSInst(uint32_t value) {
}

uint32_t IRNativeBackend::DoIRInst(uint64_t value) {
IRInst inst;
IRInst inst[2];
memcpy(&inst, &value, sizeof(inst));

if constexpr (enableDebugStats)
debugSeenNotCompiledIR[(uint8_t)inst.op]++;
debugSeenNotCompiledIR[(uint8_t)inst[0].op]++;

return IRInterpret(currentMIPS, &inst, 1);
inst[1].op = IROp::ExitToPC;
return IRInterpret(currentMIPS, &inst[0]);
}

int IRNativeBackend::ReportBadAddress(uint32_t addr, uint32_t alignment, uint32_t isWrite) {
Expand Down
15 changes: 15 additions & 0 deletions Core/MemMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,21 @@ inline bool IsValidAddress(const u32 address) {
}
}

inline bool IsValid4AlignedAddress(const u32 address) {
if ((address & 0x3E000003) == 0x08000000) {
return true;
} else if ((address & 0x3F800003) == 0x04000000) {
return true;
} else if ((address & 0xBFFFC003) == 0x00010000) {
return true;
} else if ((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) {
return (address & 3) == 0;
} else {
return false;
}
}


inline u32 MaxSizeAtAddress(const u32 address){
if ((address & 0x3E000000) == 0x08000000) {
return 0x08000000 + g_MemorySize - (address & 0x3FFFFFFF);
Expand Down

0 comments on commit fcd48b7

Please sign in to comment.