diff --git a/src/backend/core/Interpreter.cpp b/src/backend/core/Interpreter.cpp index 9ea28563..be0614a5 100644 --- a/src/backend/core/Interpreter.cpp +++ b/src/backend/core/Interpreter.cpp @@ -7,6 +7,12 @@ int Interpreter::Step() { regs.prevDelaySlot = regs.delaySlot; regs.delaySlot = false; + if(check_address_error(0b11, u64(regs.pc))) [[unlikely]] { + HandleTLBException(regs, regs.pc); + FireException(regs, ExceptionCode::AddressErrorLoad, 0, false); + return 1; + } + u32 paddr = 0; if(!MapVAddr(regs, LOAD, regs.pc, paddr)) { HandleTLBException(regs, regs.pc); diff --git a/src/backend/core/Interpreter.hpp b/src/backend/core/Interpreter.hpp index 1ad122b0..fd384b95 100644 --- a/src/backend/core/Interpreter.hpp +++ b/src/backend/core/Interpreter.hpp @@ -12,6 +12,7 @@ struct Interpreter : BaseCPU { private: u64 cop2Latch{}; friend struct Cop1; +#define check_address_error(mask, vaddr) (((!regs.cop0.is_64bit_addressing) && (s32)(vaddr) != (vaddr)) || (((vaddr) & (mask)) != 0)) [[nodiscard]] FORCE_INLINE bool ShouldServiceInterrupt() override { bool interrupts_pending = (regs.cop0.status.im & regs.cop0.cause.interruptPending) != 0; diff --git a/src/backend/core/interpreter/instructions.cpp b/src/backend/core/interpreter/instructions.cpp index e3f8374d..a662b51f 100644 --- a/src/backend/core/interpreter/instructions.cpp +++ b/src/backend/core/interpreter/instructions.cpp @@ -1,6 +1,5 @@ #include -#define check_address_error(mask, vaddr) (((!regs.cop0.is_64bit_addressing) && (s32)(vaddr) != (vaddr)) || (((vaddr) & (mask)) != 0)) #define check_signed_overflow(op1, op2, res) (((~((op1) ^ (op2)) & ((op1) ^ (res))) >> ((sizeof(res) * 8) - 1)) & 1) #define check_signed_underflow(op1, op2, res) (((((op1) ^ (op2)) & ((op1) ^ (res))) >> ((sizeof(res) * 8) - 1)) & 1) @@ -663,16 +662,17 @@ void Interpreter::jal(u32 instr) { void Interpreter::jalr(u32 instr) { u64 addr = regs.gpr[RS(instr)]; - if(check_address_error(0b11, addr)) { - FireException(regs, ExceptionCode::AddressErrorLoad, 0, true); - } else { - branch(true, addr); - if (RD(instr) != 0) [[likely]] { - regs.gpr[RD(instr)] = regs.pc + 4; - } + branch(true, addr); + if (RD(instr) != 0) [[likely]] { + regs.gpr[RD(instr)] = regs.pc + 4; } } +void Interpreter::jr(u32 instr) { + u64 address = regs.gpr[RS(instr)]; + branch(true, address); +} + void Interpreter::slti(u32 instr) { s16 imm = instr; if (RT(instr) != 0) [[likely]] { @@ -858,15 +858,6 @@ void Interpreter::dsra32(u32 instr) { } } -void Interpreter::jr(u32 instr) { - s64 address = regs.gpr[RS(instr)]; - if(check_address_error(0b11, address)) { - FireException(regs, ExceptionCode::AddressErrorLoad, 0, true); - } else { - branch(true, address); - } -} - void Interpreter::dsub(u32 instr) { s64 rt = regs.gpr[RT(instr)]; s64 rs = regs.gpr[RS(instr)];