Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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