irjit: Add constructs for validing mem access.

Basically to allow slow/fast memory to work with IR, including for
alignment checks.
This commit is contained in:
Unknown W. Brackets 2022-08-21 12:44:35 -07:00
parent 5f30c88e38
commit 6715f41410
6 changed files with 78 additions and 0 deletions

View file

@ -264,6 +264,7 @@ void IRFrontend::DoJit(u32 em_address, std::vector<IRInst> &instructions, u32 &m
&OptimizeFPMoves,
&PropagateConstants,
&PurgeTemps,
&ApplyMemoryValidation,
// &ReorderLoadStore,
// &MergeLoadStore,
// &ThreeOpToTwoOp,

View file

@ -163,6 +163,11 @@ static const IRMeta irMeta[] = {
{ IROp::Breakpoint, "Breakpoint", "", IRFLAG_EXIT },
{ IROp::MemoryCheck, "MemoryCheck", "_GC", IRFLAG_EXIT },
{ IROp::ValidateAddress8, "ValidAddr8", "_GC", IRFLAG_EXIT },
{ IROp::ValidateAddress16, "ValidAddr16", "_GC", IRFLAG_EXIT },
{ IROp::ValidateAddress32, "ValidAddr32", "_GC", IRFLAG_EXIT },
{ IROp::ValidateAddress128, "ValidAddr128", "_GC", IRFLAG_EXIT },
{ IROp::RestoreRoundingMode, "RestoreRoundingMode", "" },
{ IROp::ApplyRoundingMode, "ApplyRoundingMode", "" },
{ IROp::UpdateRoundingMode, "UpdateRoundingMode", "" },

View file

@ -213,8 +213,15 @@ enum class IROp : u8 {
SetPCConst, // hack to make replacement know PC
CallReplacement,
Break,
// Debugging breakpoints.
Breakpoint,
MemoryCheck,
ValidateAddress8,
ValidateAddress16,
ValidateAddress32,
ValidateAddress128,
};
enum IRComparison {

View file

@ -79,6 +79,19 @@ u32 RunMemCheck(u32 pc, u32 addr) {
return coreState != CORE_RUNNING ? 1 : 0;
}
template <uint32_t alignment>
u32 RunValidateAddress(u32 pc, u32 addr) {
if (!Memory::IsValidRange(addr, alignment)) {
Core_MemoryException(addr, pc, MemoryExceptionType::UNKNOWN);
return coreState != CORE_RUNNING ? 1 : 0;
}
if (alignment > 1 && (addr & (alignment - 1)) != 0) {
Core_MemoryException(addr, pc, MemoryExceptionType::UNKNOWN);
return coreState != CORE_RUNNING ? 1 : 0;
}
return 0;
}
// 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;
@ -142,6 +155,31 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, int count) {
mips->r[inst->dest] = ReverseBits32(mips->r[inst->src1]);
break;
case IROp::ValidateAddress8:
if (RunValidateAddress<1>(mips->pc, mips->r[inst->src1] + inst->constant)) {
CoreTiming::ForceCheck();
return mips->pc;
}
break;
case IROp::ValidateAddress16:
if (RunValidateAddress<2>(mips->pc, mips->r[inst->src1] + inst->constant)) {
CoreTiming::ForceCheck();
return mips->pc;
}
break;
case IROp::ValidateAddress32:
if (RunValidateAddress<4>(mips->pc, mips->r[inst->src1] + inst->constant)) {
CoreTiming::ForceCheck();
return mips->pc;
}
break;
case IROp::ValidateAddress128:
if (RunValidateAddress<16>(mips->pc, mips->r[inst->src1] + inst->constant)) {
CoreTiming::ForceCheck();
return mips->pc;
}
break;
case IROp::Load8:
mips->r[inst->dest] = Memory::ReadUnchecked_U8(mips->r[inst->src1] + inst->constant);
break;

View file

@ -5,6 +5,7 @@
#include "Common/BitSet.h"
#include "Common/Data/Convert/SmallDataConvert.h"
#include "Common/Log.h"
#include "Core/Config.h"
#include "Core/MIPS/IR/IRInterpreter.h"
#include "Core/MIPS/IR/IRPassSimplify.h"
#include "Core/MIPS/IR/IRRegCache.h"
@ -622,6 +623,18 @@ bool PropagateConstants(const IRWriter &in, IRWriter &out, const IROptions &opts
}
break;
case IROp::ValidateAddress8:
case IROp::ValidateAddress16:
case IROp::ValidateAddress32:
case IROp::ValidateAddress128:
if (gpr.IsImm(inst.src1)) {
out.Write(inst.op, inst.dest, 0, out.AddConstant(gpr.GetImm(inst.src1) + inst.constant));
} else {
gpr.MapIn(inst.src1);
goto doDefault;
}
break;
case IROp::Downcount:
case IROp::SetPCConst:
goto doDefault;
@ -1428,3 +1441,16 @@ bool MergeLoadStore(const IRWriter &in, IRWriter &out, const IROptions &opts) {
}
return logBlocks;
}
bool ApplyMemoryValidation(const IRWriter &in, IRWriter &out, const IROptions &opts) {
CONDITIONAL_DISABLE;
if (g_Config.bFastMemory)
DISABLE;
bool logBlocks = false;
for (IRInst inst : in.GetInstructions()) {
// TODO
out.Write(inst);
}
return logBlocks;
}

View file

@ -14,3 +14,4 @@ bool ThreeOpToTwoOp(const IRWriter &in, IRWriter &out, const IROptions &opts);
bool OptimizeFPMoves(const IRWriter &in, IRWriter &out, const IROptions &opts);
bool ReorderLoadStore(const IRWriter &in, IRWriter &out, const IROptions &opts);
bool MergeLoadStore(const IRWriter &in, IRWriter &out, const IROptions &opts);
bool ApplyMemoryValidation(const IRWriter &in, IRWriter &out, const IROptions &opts);