From 83ba53137cbc45fa49ee225392cef27cf0bb08a9 Mon Sep 17 00:00:00 2001 From: SimoneN64 Date: Sun, 22 Oct 2023 20:59:46 +0200 Subject: [PATCH] Don't ask "useOldPC" and instead just pass the thing --- src/backend/core/Interpreter.cpp | 6 +- src/backend/core/JIT/decode.cpp | 10 +-- src/backend/core/JIT/instructions.cpp | 72 ++++++++-------- src/backend/core/interpreter/decode.cpp | 10 +-- src/backend/core/interpreter/instructions.cpp | 86 +++++++++---------- src/backend/core/registers/Cop0.cpp | 5 +- src/backend/core/registers/Cop0.hpp | 2 +- src/backend/core/registers/Cop1.hpp | 2 +- .../core/registers/cop/cop1instructions.cpp | 13 +-- 9 files changed, 103 insertions(+), 103 deletions(-) diff --git a/src/backend/core/Interpreter.cpp b/src/backend/core/Interpreter.cpp index be0614a5..ffa3cb57 100644 --- a/src/backend/core/Interpreter.cpp +++ b/src/backend/core/Interpreter.cpp @@ -9,21 +9,21 @@ int Interpreter::Step() { if(check_address_error(0b11, u64(regs.pc))) [[unlikely]] { HandleTLBException(regs, regs.pc); - FireException(regs, ExceptionCode::AddressErrorLoad, 0, false); + FireException(regs, ExceptionCode::AddressErrorLoad, 0, regs.pc); return 1; } u32 paddr = 0; if(!MapVAddr(regs, LOAD, regs.pc, paddr)) { HandleTLBException(regs, regs.pc); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, false); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.pc); return 1; } u32 instruction = mem.Read32(regs, paddr); if(ShouldServiceInterrupt()) { - FireException(regs, ExceptionCode::Interrupt, 0, false); + FireException(regs, ExceptionCode::Interrupt, 0, regs.pc); return 1; } diff --git a/src/backend/core/JIT/decode.cpp b/src/backend/core/JIT/decode.cpp index 63beee59..5a21cea2 100644 --- a/src/backend/core/JIT/decode.cpp +++ b/src/backend/core/JIT/decode.cpp @@ -18,8 +18,8 @@ void JIT::special(u32 instr) { case 0x07: srav(instr); break; case 0x08: jr(instr); break; case 0x09: jalr(instr); break; - case 0x0C: FireException(regs, ExceptionCode::Syscall, 0, true); break; - case 0x0D: FireException(regs, ExceptionCode::Breakpoint, 0, true); break; + case 0x0C: FireException(regs, ExceptionCode::Syscall, 0, regs.oldPC); break; + case 0x0D: FireException(regs, ExceptionCode::Breakpoint, 0, regs.oldPC); break; case 0x0F: break; // SYNC case 0x10: mfhi(instr); break; case 0x11: mthi(instr); break; @@ -116,7 +116,7 @@ void JIT::regimm(u32 instr) { void JIT::cop2Decode(u32 instr) { if(!regs.cop0.status.cu2) { - FireException(regs, ExceptionCode::CoprocessorUnusable, 2, true); + FireException(regs, ExceptionCode::CoprocessorUnusable, 2, regs.oldPC); return; } switch(RS(instr)) { @@ -127,7 +127,7 @@ void JIT::cop2Decode(u32 instr) { case 0x05: dmtc2(instr); break; case 0x06: ctc2(instr); break; default: - FireException(regs, ExceptionCode::ReservedInstruction, 2, true); + FireException(regs, ExceptionCode::ReservedInstruction, 2, regs.oldPC); } } @@ -190,7 +190,7 @@ void JIT::Emit(u32 instr) { case 0x19: daddiu(instr); break; case 0x1A: ldl(instr); break; case 0x1B: ldr(instr); break; - case 0x1F: FireException(regs, ExceptionCode::ReservedInstruction, 0, true); break; + case 0x1F: FireException(regs, ExceptionCode::ReservedInstruction, 0, regs.oldPC); break; case 0x20: lb(instr); break; case 0x21: lh(instr); break; case 0x22: lwl(instr); break; diff --git a/src/backend/core/JIT/instructions.cpp b/src/backend/core/JIT/instructions.cpp index aa50d2c7..9793f579 100644 --- a/src/backend/core/JIT/instructions.cpp +++ b/src/backend/core/JIT/instructions.cpp @@ -291,14 +291,14 @@ void JIT::lh(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; if ((address & 0b1) > 0) { HandleTLBException(regs, address); - FireException(regs, ExceptionCode::AddressErrorLoad, 0, true); + FireException(regs, ExceptionCode::AddressErrorLoad, 0, regs.oldPC); return; } u32 paddr = 0; if(!MapVAddr(regs, LOAD, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { regs.gpr[RT(instr)] = (s16)mem.Read16(regs, paddr); } @@ -309,14 +309,14 @@ void JIT::lw(u32 instr) { u64 address = regs.gpr[RS(instr)] + offset; if (check_address_error(0b11, address)) { HandleTLBException(regs, address); - FireException(regs, ExceptionCode::AddressErrorLoad, 0, true); + FireException(regs, ExceptionCode::AddressErrorLoad, 0, regs.oldPC); return; } u32 physical = 0; if (!MapVAddr(regs, LOAD, address, physical)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { regs.gpr[RT(instr)] = (s32)mem.Read32(regs, physical); } @@ -327,10 +327,10 @@ void JIT::ll(u32 instr) { u32 physical; if (!MapVAddr(regs, LOAD, address, physical)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { if ((address & 0b11) > 0) { - FireException(regs, ExceptionCode::AddressErrorLoad, 0, true); + FireException(regs, ExceptionCode::AddressErrorLoad, 0, regs.oldPC); return; } else { regs.gpr[RT(instr)] = (s32)mem.Read32(regs, physical); @@ -346,7 +346,7 @@ void JIT::lwl(u32 instr) { u32 paddr = 0; if(!MapVAddr(regs, LOAD, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { u32 shift = 8 * ((address ^ 0) & 3); u32 mask = 0xFFFFFFFF << shift; @@ -361,7 +361,7 @@ void JIT::lwr(u32 instr) { u32 paddr = 0; if(!MapVAddr(regs, LOAD, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { u32 shift = 8 * ((address ^ 3) & 3); u32 mask = 0xFFFFFFFF >> shift; @@ -375,14 +375,14 @@ void JIT::ld(u32 instr) { s64 address = regs.gpr[RS(instr)] + (s16)instr; if (check_address_error(0b111, address)) { HandleTLBException(regs, address); - FireException(regs, ExceptionCode::AddressErrorLoad, 0, true); + FireException(regs, ExceptionCode::AddressErrorLoad, 0, regs.oldPC); return; } u32 paddr = 0; if(!MapVAddr(regs, LOAD, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { s64 value = mem.Read64(regs, paddr); regs.gpr[RT(instr)] = value; @@ -391,7 +391,7 @@ void JIT::ld(u32 instr) { void JIT::lld(u32 instr) { if (!regs.cop0.is_64bit_addressing && !regs.cop0.kernel_mode) { - FireException(regs, ExceptionCode::ReservedInstruction, 0, true); + FireException(regs, ExceptionCode::ReservedInstruction, 0, regs.oldPC); return; } @@ -399,10 +399,10 @@ void JIT::lld(u32 instr) { u32 paddr; if (!MapVAddr(regs, LOAD, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { if ((address & 0b111) > 0) { - FireException(regs, ExceptionCode::AddressErrorLoad, 0, true); + FireException(regs, ExceptionCode::AddressErrorLoad, 0, regs.oldPC); } else { regs.gpr[RT(instr)] = mem.Read64(regs, paddr); regs.cop0.llbit = true; @@ -416,7 +416,7 @@ void JIT::ldl(u32 instr) { u32 paddr = 0; if (!MapVAddr(regs, LOAD, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { s32 shift = 8 * ((address ^ 0) & 7); u64 mask = 0xFFFFFFFFFFFFFFFF << shift; @@ -431,7 +431,7 @@ void JIT::ldr(u32 instr) { u32 paddr; if (!MapVAddr(regs, LOAD, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { s32 shift = 8 * ((address ^ 7) & 7); u64 mask = 0xFFFFFFFFFFFFFFFF >> shift; @@ -446,7 +446,7 @@ void JIT::lbu(u32 instr) { u32 paddr; if (!MapVAddr(regs, LOAD, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { u8 value = mem.Read8(regs, paddr); regs.gpr[RT(instr)] = value; @@ -457,13 +457,13 @@ void JIT::lhu(u32 instr) { s64 address = regs.gpr[RS(instr)] + (s16)instr; if ((address & 0b1) > 0) { HandleTLBException(regs, address); - FireException(regs, ExceptionCode::AddressErrorLoad, 0, true); + FireException(regs, ExceptionCode::AddressErrorLoad, 0, regs.oldPC); return; } u32 paddr; if (!MapVAddr(regs, LOAD, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { u16 value = mem.Read16(regs, paddr); regs.gpr[RT(instr)] = value; @@ -474,14 +474,14 @@ void JIT::lwu(u32 instr) { s64 address = regs.gpr[RS(instr)] + (s16)instr; if ((address & 0b11) > 0) { HandleTLBException(regs, address); - FireException(regs, ExceptionCode::AddressErrorLoad, 0, true); + FireException(regs, ExceptionCode::AddressErrorLoad, 0, regs.oldPC); return; } u32 paddr; if (!MapVAddr(regs, LOAD, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { u32 value = mem.Read32(regs, paddr); regs.gpr[RT(instr)] = value; @@ -493,7 +493,7 @@ void JIT::sb(u32 instr) { u32 paddr; if (!MapVAddr(regs, STORE, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { mem.Write8(regs, paddr, regs.gpr[RT(instr)]); } @@ -503,7 +503,7 @@ void JIT::sc(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; if ((address & 0b11) > 0) { - FireException(regs, ExceptionCode::AddressErrorStore, 0, true); + FireException(regs, ExceptionCode::AddressErrorStore, 0, regs.oldPC); return; } @@ -512,7 +512,7 @@ void JIT::sc(u32 instr) { u32 paddr = 0; if(!MapVAddr(regs, STORE, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { mem.Write32(regs, paddr, regs.gpr[RT(instr)]); regs.gpr[RT(instr)] = 1; @@ -524,14 +524,14 @@ void JIT::sc(u32 instr) { void JIT::scd(u32 instr) { if (!regs.cop0.is_64bit_addressing && !regs.cop0.kernel_mode) { - FireException(regs, ExceptionCode::ReservedInstruction, 0, true); + FireException(regs, ExceptionCode::ReservedInstruction, 0, regs.oldPC); return; } s64 address = regs.gpr[RS(instr)] + (s16)instr; if ((address & 0b111) > 0) { HandleTLBException(regs, address); - FireException(regs, ExceptionCode::AddressErrorStore, 0, true); + FireException(regs, ExceptionCode::AddressErrorStore, 0, regs.oldPC); return; } @@ -540,7 +540,7 @@ void JIT::scd(u32 instr) { u32 paddr = 0; if(!MapVAddr(regs, STORE, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { mem.Write32(regs, paddr, regs.gpr[RT(instr)]); regs.gpr[RT(instr)] = 1; @@ -556,7 +556,7 @@ void JIT::sh(u32 instr) { u32 physical; if(!MapVAddr(regs, STORE, address, physical)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { mem.Write16(regs, physical, regs.gpr[RT(instr)]); } @@ -567,14 +567,14 @@ void JIT::sw(u32 instr) { u64 address = regs.gpr[RS(instr)] + offset; if (check_address_error(0b11, address)) { HandleTLBException(regs, address); - FireException(regs, ExceptionCode::AddressErrorStore, 0, true); + FireException(regs, ExceptionCode::AddressErrorStore, 0, regs.oldPC); return; } u32 physical; if(!MapVAddr(regs, STORE, address, physical)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { mem.Write32(regs, physical, regs.gpr[RT(instr)]); } @@ -584,14 +584,14 @@ void JIT::sd(u32 instr) { s64 address = regs.gpr[RS(instr)] + (s16)instr; if (check_address_error(0b111, address)) { HandleTLBException(regs, address); - FireException(regs, ExceptionCode::AddressErrorStore, 0, true); + FireException(regs, ExceptionCode::AddressErrorStore, 0, regs.oldPC); return; } u32 physical; if(!MapVAddr(regs, STORE, address, physical)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { mem.Write64(regs, physical, regs.gpr[RT(instr)]); } @@ -602,7 +602,7 @@ void JIT::sdl(u32 instr) { u32 paddr; if (!MapVAddr(regs, STORE, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { s32 shift = 8 * ((address ^ 0) & 7); u64 mask = 0xFFFFFFFFFFFFFFFF >> shift; @@ -617,7 +617,7 @@ void JIT::sdr(u32 instr) { u32 paddr; if (!MapVAddr(regs, STORE, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { s32 shift = 8 * ((address ^ 7) & 7); u64 mask = 0xFFFFFFFFFFFFFFFF << shift; @@ -632,7 +632,7 @@ void JIT::swl(u32 instr) { u32 paddr; if (!MapVAddr(regs, STORE, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { u32 shift = 8 * ((address ^ 0) & 3); u32 mask = 0xFFFFFFFF >> shift; @@ -647,7 +647,7 @@ void JIT::swr(u32 instr) { u32 paddr; if (!MapVAddr(regs, STORE, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { u32 shift = 8 * ((address ^ 3) & 3); u32 mask = 0xFFFFFFFF << shift; @@ -1009,7 +1009,7 @@ void JIT::mthi(u32 instr) { void JIT::trap(bool cond) { if(cond) { - FireException(regs, ExceptionCode::Trap, 0, true); + FireException(regs, ExceptionCode::Trap, 0, regs.oldPC); } } diff --git a/src/backend/core/interpreter/decode.cpp b/src/backend/core/interpreter/decode.cpp index 6a9cbb76..f8b1ef34 100644 --- a/src/backend/core/interpreter/decode.cpp +++ b/src/backend/core/interpreter/decode.cpp @@ -19,8 +19,8 @@ void Interpreter::special(u32 instr) { case SRAV: srav(instr); break; case JR: jr(instr); break; case JALR: jalr(instr); break; - case SYSCALL: FireException(regs, ExceptionCode::Syscall, 0, true); break; - case BREAK: FireException(regs, ExceptionCode::Breakpoint, 0, true); break; + case SYSCALL: FireException(regs, ExceptionCode::Syscall, 0, regs.oldPC); break; + case BREAK: FireException(regs, ExceptionCode::Breakpoint, 0, regs.oldPC); break; case SYNC: break; // SYNC case MFHI: mfhi(instr); break; case MTHI: mthi(instr); break; @@ -93,7 +93,7 @@ void Interpreter::regimm(u32 instr) { void Interpreter::cop2Decode(u32 instr) { if(!regs.cop0.status.cu2) { - FireException(regs, ExceptionCode::CoprocessorUnusable, 2, true); + FireException(regs, ExceptionCode::CoprocessorUnusable, 2, regs.oldPC); return; } switch(RS(instr)) { @@ -104,7 +104,7 @@ void Interpreter::cop2Decode(u32 instr) { case 0x05: dmtc2(instr); break; case 0x06: ctc2(instr); break; default: - FireException(regs, ExceptionCode::ReservedInstruction, 2, true); + FireException(regs, ExceptionCode::ReservedInstruction, 2, regs.oldPC); } } @@ -142,7 +142,7 @@ void Interpreter::Exec(u32 instr) { case DADDIU: daddiu(instr); break; case LDL: ldl(instr); break; case LDR: ldr(instr); break; - case 0x1F: FireException(regs, ExceptionCode::ReservedInstruction, 0, true); break; + case 0x1F: FireException(regs, ExceptionCode::ReservedInstruction, 0, regs.oldPC); break; case LB: lb(instr); break; case LH: lh(instr); break; case LWL: lwl(instr); break; diff --git a/src/backend/core/interpreter/instructions.cpp b/src/backend/core/interpreter/instructions.cpp index a662b51f..12c8d9eb 100644 --- a/src/backend/core/interpreter/instructions.cpp +++ b/src/backend/core/interpreter/instructions.cpp @@ -9,7 +9,7 @@ void Interpreter::add(u32 instr) { u32 rt = (s32)regs.gpr[RT(instr)]; u32 result = rs + rt; if(check_signed_overflow(rs, rt, result)) { - FireException(regs, ExceptionCode::Overflow, 0, true); + FireException(regs, ExceptionCode::Overflow, 0, regs.oldPC); } else { if (RD(instr) != 0) [[likely]] { regs.gpr[RD(instr)] = s32(result); @@ -31,7 +31,7 @@ void Interpreter::addi(u32 instr) { u32 imm = s32(s16(instr)); u32 result = rs + imm; if(check_signed_overflow(rs, imm, result)) { - FireException(regs, ExceptionCode::Overflow, 0, true); + FireException(regs, ExceptionCode::Overflow, 0, regs.oldPC); } else { if (RT(instr) != 0) [[likely]] { regs.gpr[RT(instr)] = s32(result); @@ -53,7 +53,7 @@ void Interpreter::dadd(u32 instr) { u64 rt = regs.gpr[RT(instr)]; u64 result = rt + rs; if(check_signed_overflow(rs, rt, result)) { - FireException(regs, ExceptionCode::Overflow, 0, true); + FireException(regs, ExceptionCode::Overflow, 0, regs.oldPC); } else { if (RD(instr) != 0) [[likely]] { regs.gpr[RD(instr)] = result; @@ -74,7 +74,7 @@ void Interpreter::daddi(u32 instr) { u64 rs = regs.gpr[RS(instr)]; u64 result = imm + rs; if(check_signed_overflow(rs, imm, result)) { - FireException(regs, ExceptionCode::Overflow, 0, true); + FireException(regs, ExceptionCode::Overflow, 0, regs.oldPC); } else { if (RT(instr) != 0) [[likely]] { regs.gpr[RT(instr)] = result; @@ -217,7 +217,7 @@ void Interpreter::lb(u32 instr) { u32 paddr = 0; if(!MapVAddr(regs, LOAD, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { if (RT(instr) != 0) [[likely]] { regs.gpr[RT(instr)] = (s8) mem.Read8(regs, paddr); @@ -229,14 +229,14 @@ void Interpreter::lh(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; if (check_address_error(0b1, address)) { HandleTLBException(regs, address); - FireException(regs, ExceptionCode::AddressErrorLoad, 0, true); + FireException(regs, ExceptionCode::AddressErrorLoad, 0, regs.oldPC); return; } u32 paddr = 0; if(!MapVAddr(regs, LOAD, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { if (RT(instr) != 0) [[likely]] { regs.gpr[RT(instr)] = (s16) mem.Read16(regs, paddr); @@ -249,14 +249,14 @@ void Interpreter::lw(u32 instr) { u64 address = regs.gpr[RS(instr)] + offset; if (check_address_error(0b11, address)) { HandleTLBException(regs, address); - FireException(regs, ExceptionCode::AddressErrorLoad, 0, true); + FireException(regs, ExceptionCode::AddressErrorLoad, 0, regs.oldPC); return; } u32 physical = 0; if (!MapVAddr(regs, LOAD, address, physical)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { if(RT(instr) != 0) [[likely]] { regs.gpr[RT(instr)] = (s32) mem.Read32(regs, physical); @@ -269,11 +269,11 @@ void Interpreter::ll(u32 instr) { u32 physical; if (!MapVAddr(regs, LOAD, address, physical)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { s32 result = mem.Read32(regs, physical); if (check_address_error(0b11, address)) { - FireException(regs, ExceptionCode::AddressErrorLoad, 0, true); + FireException(regs, ExceptionCode::AddressErrorLoad, 0, regs.oldPC); return; } @@ -291,7 +291,7 @@ void Interpreter::lwl(u32 instr) { u32 paddr = 0; if(!MapVAddr(regs, LOAD, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { u32 shift = 8 * ((address ^ 0) & 3); u32 mask = 0xFFFFFFFF << shift; @@ -308,7 +308,7 @@ void Interpreter::lwr(u32 instr) { u32 paddr = 0; if(!MapVAddr(regs, LOAD, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { u32 shift = 8 * ((address ^ 3) & 3); u32 mask = 0xFFFFFFFF >> shift; @@ -324,14 +324,14 @@ void Interpreter::ld(u32 instr) { s64 address = regs.gpr[RS(instr)] + (s16)instr; if (check_address_error(0b111, address)) { HandleTLBException(regs, address); - FireException(regs, ExceptionCode::AddressErrorLoad, 0, true); + FireException(regs, ExceptionCode::AddressErrorLoad, 0, regs.oldPC); return; } u32 paddr = 0; if(!MapVAddr(regs, LOAD, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { s64 value = mem.Read64(regs, paddr); if (RT(instr) != 0) [[likely]] { @@ -342,7 +342,7 @@ void Interpreter::ld(u32 instr) { void Interpreter::lld(u32 instr) { if (!regs.cop0.is_64bit_addressing && !regs.cop0.kernel_mode) { - FireException(regs, ExceptionCode::ReservedInstruction, 0, true); + FireException(regs, ExceptionCode::ReservedInstruction, 0, regs.oldPC); return; } @@ -350,10 +350,10 @@ void Interpreter::lld(u32 instr) { u32 paddr; if (!MapVAddr(regs, LOAD, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { if (check_address_error(0b111, address)) { - FireException(regs, ExceptionCode::AddressErrorLoad, 0, true); + FireException(regs, ExceptionCode::AddressErrorLoad, 0, regs.oldPC); } else { if (RT(instr) != 0) [[likely]] { regs.gpr[RT(instr)] = mem.Read64(regs, paddr); @@ -369,7 +369,7 @@ void Interpreter::ldl(u32 instr) { u32 paddr = 0; if (!MapVAddr(regs, LOAD, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { s32 shift = 8 * ((address ^ 0) & 7); u64 mask = 0xFFFFFFFFFFFFFFFF << shift; @@ -386,7 +386,7 @@ void Interpreter::ldr(u32 instr) { u32 paddr; if (!MapVAddr(regs, LOAD, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { s32 shift = 8 * ((address ^ 7) & 7); u64 mask = 0xFFFFFFFFFFFFFFFF >> shift; @@ -403,7 +403,7 @@ void Interpreter::lbu(u32 instr) { u32 paddr; if (!MapVAddr(regs, LOAD, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { u8 value = mem.Read8(regs, paddr); if (RT(instr) != 0) [[likely]] { @@ -416,13 +416,13 @@ void Interpreter::lhu(u32 instr) { s64 address = regs.gpr[RS(instr)] + (s16)instr; if (check_address_error(0b1, address)) { HandleTLBException(regs, address); - FireException(regs, ExceptionCode::AddressErrorLoad, 0, true); + FireException(regs, ExceptionCode::AddressErrorLoad, 0, regs.oldPC); return; } u32 paddr; if (!MapVAddr(regs, LOAD, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { u16 value = mem.Read16(regs, paddr); if (RT(instr) != 0) [[likely]] { @@ -435,14 +435,14 @@ void Interpreter::lwu(u32 instr) { s64 address = regs.gpr[RS(instr)] + (s16)instr; if (check_address_error(0b11, address)) { HandleTLBException(regs, address); - FireException(regs, ExceptionCode::AddressErrorLoad, 0, true); + FireException(regs, ExceptionCode::AddressErrorLoad, 0, regs.oldPC); return; } u32 paddr; if (!MapVAddr(regs, LOAD, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { u32 value = mem.Read32(regs, paddr); if (RT(instr) != 0) [[likely]] { @@ -456,7 +456,7 @@ void Interpreter::sb(u32 instr) { u32 paddr; if (!MapVAddr(regs, STORE, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { mem.Write8(regs, paddr, regs.gpr[RT(instr)]); } @@ -466,7 +466,7 @@ void Interpreter::sc(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; if (check_address_error(0b11, address)) { - FireException(regs, ExceptionCode::AddressErrorStore, 0, true); + FireException(regs, ExceptionCode::AddressErrorStore, 0, regs.oldPC); return; } @@ -475,7 +475,7 @@ void Interpreter::sc(u32 instr) { u32 paddr = 0; if(!MapVAddr(regs, STORE, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { mem.Write32(regs, paddr, regs.gpr[RT(instr)]); if (RT(instr) != 0) [[likely]] { @@ -491,14 +491,14 @@ void Interpreter::sc(u32 instr) { void Interpreter::scd(u32 instr) { if (!regs.cop0.is_64bit_addressing && !regs.cop0.kernel_mode) { - FireException(regs, ExceptionCode::ReservedInstruction, 0, true); + FireException(regs, ExceptionCode::ReservedInstruction, 0, regs.oldPC); return; } s64 address = regs.gpr[RS(instr)] + (s16)instr; if (check_address_error(0b111, address)) { HandleTLBException(regs, address); - FireException(regs, ExceptionCode::AddressErrorStore, 0, true); + FireException(regs, ExceptionCode::AddressErrorStore, 0, regs.oldPC); return; } @@ -507,7 +507,7 @@ void Interpreter::scd(u32 instr) { u32 paddr = 0; if(!MapVAddr(regs, STORE, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { mem.Write32(regs, paddr, regs.gpr[RT(instr)]); if (RT(instr) != 0) [[likely]] { @@ -527,7 +527,7 @@ void Interpreter::sh(u32 instr) { u32 physical; if(!MapVAddr(regs, STORE, address, physical)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { mem.Write16(regs, physical, regs.gpr[RT(instr)]); } @@ -538,14 +538,14 @@ void Interpreter::sw(u32 instr) { u64 address = regs.gpr[RS(instr)] + offset; if (check_address_error(0b11, address)) { HandleTLBException(regs, address); - FireException(regs, ExceptionCode::AddressErrorStore, 0, true); + FireException(regs, ExceptionCode::AddressErrorStore, 0, regs.oldPC); return; } u32 physical; if(!MapVAddr(regs, STORE, address, physical)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { mem.Write32(regs, physical, regs.gpr[RT(instr)]); } @@ -555,14 +555,14 @@ void Interpreter::sd(u32 instr) { s64 address = regs.gpr[RS(instr)] + (s16)instr; if (check_address_error(0b111, address)) { HandleTLBException(regs, address); - FireException(regs, ExceptionCode::AddressErrorStore, 0, true); + FireException(regs, ExceptionCode::AddressErrorStore, 0, regs.oldPC); return; } u32 physical; if(!MapVAddr(regs, STORE, address, physical)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { mem.Write64(regs, physical, regs.gpr[RT(instr)]); } @@ -573,7 +573,7 @@ void Interpreter::sdl(u32 instr) { u32 paddr; if (!MapVAddr(regs, STORE, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { s32 shift = 8 * ((address ^ 0) & 7); u64 mask = 0xFFFFFFFFFFFFFFFF >> shift; @@ -588,7 +588,7 @@ void Interpreter::sdr(u32 instr) { u32 paddr; if (!MapVAddr(regs, STORE, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { s32 shift = 8 * ((address ^ 7) & 7); u64 mask = 0xFFFFFFFFFFFFFFFF << shift; @@ -603,7 +603,7 @@ void Interpreter::swl(u32 instr) { u32 paddr; if (!MapVAddr(regs, STORE, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { u32 shift = 8 * ((address ^ 0) & 3); u32 mask = 0xFFFFFFFF >> shift; @@ -618,7 +618,7 @@ void Interpreter::swr(u32 instr) { u32 paddr; if (!MapVAddr(regs, STORE, address, paddr)) { HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { u32 shift = 8 * ((address ^ 3) & 3); u32 mask = 0xFFFFFFFF << shift; @@ -863,7 +863,7 @@ void Interpreter::dsub(u32 instr) { s64 rs = regs.gpr[RS(instr)]; s64 result = rs - rt; if(check_signed_underflow(rs, rt, result)) { - FireException(regs, ExceptionCode::Overflow, 0, true); + FireException(regs, ExceptionCode::Overflow, 0, regs.oldPC); } else { if (RD(instr) != 0) [[likely]] { regs.gpr[RD(instr)] = result; @@ -885,7 +885,7 @@ void Interpreter::sub(u32 instr) { s32 rs = regs.gpr[RS(instr)]; s32 result = rs - rt; if(check_signed_underflow(rs, rt, result)) { - FireException(regs, ExceptionCode::Overflow, 0, true); + FireException(regs, ExceptionCode::Overflow, 0, regs.oldPC); } else { if (RD(instr) != 0) [[likely]] { regs.gpr[RD(instr)] = result; @@ -956,7 +956,7 @@ void Interpreter::mthi(u32 instr) { void Interpreter::trap(bool cond) { if(cond) { - FireException(regs, ExceptionCode::Trap, 0, true); + FireException(regs, ExceptionCode::Trap, 0, regs.oldPC); } } diff --git a/src/backend/core/registers/Cop0.cpp b/src/backend/core/registers/Cop0.cpp index 6c12d01d..3279457b 100644 --- a/src/backend/core/registers/Cop0.cpp +++ b/src/backend/core/registers/Cop0.cpp @@ -250,11 +250,10 @@ FORCE_INLINE bool Is64BitAddressing(Cop0& cp0, u64 addr) { } } -void FireException(Registers& regs, ExceptionCode code, int cop, bool useOldPC) { +void FireException(Registers& regs, ExceptionCode code, int cop, s64 pc) { bool old_exl = regs.cop0.status.exl; - s64 pc = useOldPC ? regs.oldPC : regs.pc; - if(!old_exl) { + if(!regs.cop0.status.exl) { if(regs.prevDelaySlot) { regs.cop0.cause.branchDelay = true; pc -= 4; diff --git a/src/backend/core/registers/Cop0.hpp b/src/backend/core/registers/Cop0.hpp index aeea19e0..ccec09bd 100644 --- a/src/backend/core/registers/Cop0.hpp +++ b/src/backend/core/registers/Cop0.hpp @@ -189,7 +189,7 @@ enum class ExceptionCode : u8 { Watch = 23 }; -void FireException(Registers& regs, ExceptionCode code, int cop, bool useOldPC); +void FireException(Registers& regs, ExceptionCode code, int cop, s64 pc); union Cop0Context { u64 raw; diff --git a/src/backend/core/registers/Cop1.hpp b/src/backend/core/registers/Cop1.hpp index ccb07a06..4987ae11 100644 --- a/src/backend/core/registers/Cop1.hpp +++ b/src/backend/core/registers/Cop1.hpp @@ -71,7 +71,7 @@ struct JIT; struct Registers; struct Cop1 { -#define CheckFPUUsable_PreserveCause() do { if(!regs.cop0.status.cu1) { FireException(regs, ExceptionCode::CoprocessorUnusable, 1, true); return; } } while(0) +#define CheckFPUUsable_PreserveCause() do { if(!regs.cop0.status.cu1) { FireException(regs, ExceptionCode::CoprocessorUnusable, 1, regs.oldPC); return; } } while(0) #define CheckFPUUsable() do { CheckFPUUsable_PreserveCause(); regs.cop1.fcr31.cause = 0; } while(0) Cop1(); u32 fcr0{}; diff --git a/src/backend/core/registers/cop/cop1instructions.cpp b/src/backend/core/registers/cop/cop1instructions.cpp index 25977240..89970685 100644 --- a/src/backend/core/registers/cop/cop1instructions.cpp +++ b/src/backend/core/registers/cop/cop1instructions.cpp @@ -9,8 +9,9 @@ namespace n64 { FORCE_INLINE bool FireFPUException(Registers& regs) { FCR31& fcr31 = regs.cop1.fcr31; - if(fcr31.cause & ((1 << 5) | fcr31.enable)) { - FireException(regs, ExceptionCode::FloatingPointError, 0, true); + u32 enable = fcr31.enable | (1 << 5); + if(fcr31.cause & enable) { + FireException(regs, ExceptionCode::FloatingPointError, 0, regs.oldPC); return true; } @@ -759,7 +760,7 @@ void Cop1::lwc1Interp(Registers& regs, Mem& mem, u32 instr) { u32 physical; if(!MapVAddr(regs, LOAD, addr, physical)) { HandleTLBException(regs, addr); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { u32 data = mem.Read32(regs, physical); SetFGR_FR(regs.cop0, FT(instr), data); @@ -772,7 +773,7 @@ void Cop1::swc1Interp(Registers& regs, Mem& mem, u32 instr) { u32 physical; if(!MapVAddr(regs, STORE, addr, physical)) { HandleTLBException(regs, addr); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { mem.Write32(regs, physical, GetFGR_FR(regs.cop0, FT(instr))); } @@ -790,7 +791,7 @@ void Cop1::ldc1Interp(Registers& regs, Mem& mem, u32 instr) { u32 physical; if(!MapVAddr(regs, LOAD, addr, physical)) { HandleTLBException(regs, addr); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); } else { u64 data = mem.Read64(regs, physical); SetFGR_FR(regs.cop0, FT(instr), data); @@ -803,7 +804,7 @@ void Cop1::sdc1Interp(Registers& regs, Mem& mem, u32 instr) { u32 physical; if(!MapVAddr(regs, STORE, addr, physical)) { HandleTLBException(regs, addr); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, true); + FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); } else { mem.Write64(regs, physical, GetFGR_FR(regs.cop0, FT(instr))); }