Skip to content

Commit fcd48b7

Browse files
authored
Merge pull request #19128 from hrydgard/more-ir-interpreter-tweaks
More IR interpreter optimizations
2 parents ad541f2 + fae846e commit fcd48b7

File tree

6 files changed

+42
-26
lines changed

6 files changed

+42
-26
lines changed

Core/MIPS/IR/IRInst.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
// MIPS->target JITs.
1919

2020
enum class IROp : uint8_t {
21-
Nop,
22-
2321
SetConst,
2422
SetConstF,
2523

@@ -230,6 +228,8 @@ enum class IROp : uint8_t {
230228
ValidateAddress16,
231229
ValidateAddress32,
232230
ValidateAddress128,
231+
232+
Nop,
233233
};
234234

235235
enum IRComparison {
@@ -358,7 +358,7 @@ struct IRInst {
358358
};
359359

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

363363
// Each IR block gets a constant pool.
364364
class IRWriter {

Core/MIPS/IR/IRInterpreter.cpp

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,9 @@ u32 RunValidateAddress(u32 pc, u32 addr, u32 isWrite) {
108108
}
109109

110110
// We cannot use NEON on ARM32 here until we make it a hard dependency. We can, however, on ARM64.
111-
u32 IRInterpret(MIPSState *mips, const IRInst *inst, int count) {
112-
const IRInst *end = inst + count;
113-
while (inst != end) {
111+
u32 IRInterpret(MIPSState *mips, const IRInst *inst) {
112+
while (true) {
114113
switch (inst->op) {
115-
case IROp::Nop:
116-
_assert_(false);
117-
break;
118114
case IROp::SetConst:
119115
mips->r[inst->dest] = inst->constant;
120116
break;
@@ -1121,19 +1117,21 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, int count) {
11211117
case IROp::UpdateRoundingMode:
11221118
// TODO: Implement
11231119
break;
1124-
1120+
case IROp::Nop:
1121+
_assert_(false);
1122+
break;
11251123
default:
11261124
// Unimplemented IR op. Bad.
11271125
Crash();
11281126
}
1129-
inst++;
1130-
}
11311127

11321128
#ifdef _DEBUG
1133-
if (mips->r[0] != 0)
1134-
Crash();
1129+
if (mips->r[0] != 0)
1130+
Crash();
11351131
#endif
1132+
inst++;
1133+
}
11361134

1137-
// We hit count. If this is a full block, it was badly constructed.
1135+
// We should not reach here anymore.
11381136
return 0;
11391137
}

Core/MIPS/IR/IRInterpreter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ inline static u32 ReverseBits32(u32 v) {
2323
u32 IRRunBreakpoint(u32 pc);
2424
u32 IRRunMemCheck(u32 pc, u32 addr);
2525

26-
u32 IRInterpret(MIPSState *ms, const IRInst *inst, int count);
26+
u32 IRInterpret(MIPSState *ms, const IRInst *inst);

Core/MIPS/IR/IRJit.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -246,21 +246,23 @@ void IRJit::RunLoopUntil(u64 globalticks) {
246246
if (coreState != 0) {
247247
break;
248248
}
249-
while (mips_->downcount >= 0) {
250-
u32 inst = Memory::ReadUnchecked_U32(mips_->pc);
249+
250+
MIPSState *mips = mips_;
251+
252+
while (mips->downcount >= 0) {
253+
u32 inst = Memory::ReadUnchecked_U32(mips->pc);
251254
u32 opcode = inst & 0xFF000000;
252255
if (opcode == MIPS_EMUHACK_OPCODE) {
253256
IRBlock *block = blocks_.GetBlockUnchecked(inst & 0xFFFFFF);
254-
u32 startPC = mips_->pc;
255-
mips_->pc = IRInterpret(mips_, block->GetInstructions(), block->GetNumInstructions());
257+
mips->pc = IRInterpret(mips, block->GetInstructions());
256258
// Note: this will "jump to zero" on a badly constructed block missing exits.
257-
if (!Memory::IsValidAddress(mips_->pc) || (mips_->pc & 3) != 0) {
258-
Core_ExecException(mips_->pc, startPC, ExecExceptionType::JUMP);
259+
if (!Memory::IsValid4AlignedAddress(mips->pc)) {
260+
Core_ExecException(mips->pc, block->GetOriginalStart(), ExecExceptionType::JUMP);
259261
break;
260262
}
261263
} else {
262264
// RestoreRoundingMode(true);
263-
Compile(mips_->pc);
265+
Compile(mips->pc);
264266
// ApplyRoundingMode(true);
265267
}
266268
}

Core/MIPS/IR/IRNativeCommon.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,14 @@ void IRNativeBackend::DoMIPSInst(uint32_t value) {
153153
}
154154

155155
uint32_t IRNativeBackend::DoIRInst(uint64_t value) {
156-
IRInst inst;
156+
IRInst inst[2];
157157
memcpy(&inst, &value, sizeof(inst));
158158

159159
if constexpr (enableDebugStats)
160-
debugSeenNotCompiledIR[(uint8_t)inst.op]++;
160+
debugSeenNotCompiledIR[(uint8_t)inst[0].op]++;
161161

162-
return IRInterpret(currentMIPS, &inst, 1);
162+
inst[1].op = IROp::ExitToPC;
163+
return IRInterpret(currentMIPS, &inst[0]);
163164
}
164165

165166
int IRNativeBackend::ReportBadAddress(uint32_t addr, uint32_t alignment, uint32_t isWrite) {

Core/MemMap.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,21 @@ inline bool IsValidAddress(const u32 address) {
296296
}
297297
}
298298

299+
inline bool IsValid4AlignedAddress(const u32 address) {
300+
if ((address & 0x3E000003) == 0x08000000) {
301+
return true;
302+
} else if ((address & 0x3F800003) == 0x04000000) {
303+
return true;
304+
} else if ((address & 0xBFFFC003) == 0x00010000) {
305+
return true;
306+
} else if ((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) {
307+
return (address & 3) == 0;
308+
} else {
309+
return false;
310+
}
311+
}
312+
313+
299314
inline u32 MaxSizeAtAddress(const u32 address){
300315
if ((address & 0x3E000000) == 0x08000000) {
301316
return 0x08000000 + g_MemorySize - (address & 0x3FFFFFFF);

0 commit comments

Comments
 (0)