diff --git a/src/backend/core/Interpreter.cpp b/src/backend/core/Interpreter.cpp index 046101a8..8567f114 100644 --- a/src/backend/core/Interpreter.cpp +++ b/src/backend/core/Interpreter.cpp @@ -28,22 +28,22 @@ int Interpreter::Step() { regs.delaySlot = false; if(check_address_error(0b11, u64(regs.pc))) [[unlikely]] { - HandleTLBException(regs, regs.pc); - FireException(regs, ExceptionCode::AddressErrorLoad, 0, regs.pc); + regs.cop0.HandleTLBException(regs.pc); + regs.cop0.FireException(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, regs.pc); + if(!regs.cop0.MapVAddr(Cop0::LOAD, regs.pc, paddr)) { + regs.cop0.HandleTLBException(regs.pc); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.pc); return 1; } u32 instruction = mem.Read(regs, paddr); if(ShouldServiceInterrupt()) { - FireException(regs, ExceptionCode::Interrupt, 0, regs.pc); + regs.cop0.FireException(ExceptionCode::Interrupt, 0, regs.pc); return 1; } diff --git a/src/backend/core/Interpreter.hpp b/src/backend/core/Interpreter.hpp index 4ba4deae..e9f4a6a0 100644 --- a/src/backend/core/Interpreter.hpp +++ b/src/backend/core/Interpreter.hpp @@ -12,7 +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)) +#define check_address_error(mask, vaddr) (((!regs.cop0.is64BitAddressing) && (s32)(vaddr) != (vaddr)) || (((vaddr) & (mask)) != 0)) bool ShouldServiceInterrupt() override; void CheckCompareInterrupt() override; std::vector Serialize() override; diff --git a/src/backend/core/interpreter/decode.cpp b/src/backend/core/interpreter/decode.cpp index f8b1ef34..d27cdbc7 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, regs.oldPC); break; - case BREAK: FireException(regs, ExceptionCode::Breakpoint, 0, regs.oldPC); break; + case SYSCALL: regs.cop0.FireException(ExceptionCode::Syscall, 0, regs.oldPC); break; + case BREAK: regs.cop0.FireException(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, regs.oldPC); + regs.cop0.FireException(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, regs.oldPC); + regs.cop0.FireException(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, regs.oldPC); break; + case 0x1F: regs.cop0.FireException(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 8bea976c..f38b42e3 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, regs.oldPC); + regs.cop0.FireException(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, regs.oldPC); + regs.cop0.FireException(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, regs.oldPC); + regs.cop0.FireException(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, regs.oldPC); + regs.cop0.FireException(ExceptionCode::Overflow, 0, regs.oldPC); } else { if (RT(instr) != 0) [[likely]] { regs.gpr[RT(instr)] = result; @@ -215,9 +215,9 @@ void Interpreter::lui(u32 instr) { void Interpreter::lb(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr = 0; - if(!MapVAddr(regs, LOAD, address, paddr)) { - HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); + if(!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { if (RT(instr) != 0) [[likely]] { regs.gpr[RT(instr)] = (s8) mem.Read(regs, paddr); @@ -228,15 +228,15 @@ void Interpreter::lb(u32 instr) { 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, regs.oldPC); + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(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, regs.oldPC); + if(!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { if (RT(instr) != 0) [[likely]] { regs.gpr[RT(instr)] = (s16) mem.Read(regs, paddr); @@ -248,15 +248,15 @@ void Interpreter::lw(u32 instr) { s16 offset = instr; u64 address = regs.gpr[RS(instr)] + offset; if (check_address_error(0b11, address)) { - HandleTLBException(regs, address); - FireException(regs, ExceptionCode::AddressErrorLoad, 0, regs.oldPC); + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(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, regs.oldPC); + if (!regs.cop0.MapVAddr(Cop0::LOAD, address, physical)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { if(RT(instr) != 0) [[likely]] { regs.gpr[RT(instr)] = (s32) mem.Read(regs, physical); @@ -267,13 +267,13 @@ void Interpreter::lw(u32 instr) { void Interpreter::ll(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 physical; - if (!MapVAddr(regs, LOAD, address, physical)) { - HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); + if (!regs.cop0.MapVAddr(Cop0::LOAD, address, physical)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { s32 result = mem.Read(regs, physical); if (check_address_error(0b11, address)) { - FireException(regs, ExceptionCode::AddressErrorLoad, 0, regs.oldPC); + regs.cop0.FireException(ExceptionCode::AddressErrorLoad, 0, regs.oldPC); return; } @@ -289,9 +289,9 @@ void Interpreter::ll(u32 instr) { void Interpreter::lwl(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr = 0; - if(!MapVAddr(regs, LOAD, address, paddr)) { - HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); + if(!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { u32 shift = 8 * ((address ^ 0) & 3); u32 mask = 0xFFFFFFFF << shift; @@ -306,9 +306,9 @@ void Interpreter::lwl(u32 instr) { void Interpreter::lwr(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr = 0; - if(!MapVAddr(regs, LOAD, address, paddr)) { - HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); + if(!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { u32 shift = 8 * ((address ^ 3) & 3); u32 mask = 0xFFFFFFFF >> shift; @@ -323,15 +323,15 @@ void Interpreter::lwr(u32 instr) { 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, regs.oldPC); + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(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, regs.oldPC); + if(!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { s64 value = mem.Read(regs, paddr); if (RT(instr) != 0) [[likely]] { @@ -341,19 +341,19 @@ 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, regs.oldPC); + if (!regs.cop0.is64BitAddressing && !regs.cop0.kernelMode) { + regs.cop0.FireException(ExceptionCode::ReservedInstruction, 0, regs.oldPC); return; } u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr; - if (!MapVAddr(regs, LOAD, address, paddr)) { - HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); + if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { if (check_address_error(0b111, address)) { - FireException(regs, ExceptionCode::AddressErrorLoad, 0, regs.oldPC); + regs.cop0.FireException(ExceptionCode::AddressErrorLoad, 0, regs.oldPC); } else { if (RT(instr) != 0) [[likely]] { regs.gpr[RT(instr)] = mem.Read(regs, paddr); @@ -367,9 +367,9 @@ void Interpreter::lld(u32 instr) { void Interpreter::ldl(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr = 0; - if (!MapVAddr(regs, LOAD, address, paddr)) { - HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); + if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { s32 shift = 8 * ((address ^ 0) & 7); u64 mask = 0xFFFFFFFFFFFFFFFF << shift; @@ -384,9 +384,9 @@ void Interpreter::ldl(u32 instr) { void Interpreter::ldr(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr; - if (!MapVAddr(regs, LOAD, address, paddr)) { - HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); + if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { s32 shift = 8 * ((address ^ 7) & 7); u64 mask = 0xFFFFFFFFFFFFFFFF >> shift; @@ -401,9 +401,9 @@ void Interpreter::ldr(u32 instr) { void Interpreter::lbu(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr; - if (!MapVAddr(regs, LOAD, address, paddr)) { - HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); + if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { u8 value = mem.Read(regs, paddr); if (RT(instr) != 0) [[likely]] { @@ -415,14 +415,14 @@ void Interpreter::lbu(u32 instr) { 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, regs.oldPC); + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(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, regs.oldPC); + if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { u16 value = mem.Read(regs, paddr); if (RT(instr) != 0) [[likely]] { @@ -434,15 +434,15 @@ void Interpreter::lhu(u32 instr) { 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, regs.oldPC); + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(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, regs.oldPC); + if (!regs.cop0.MapVAddr(Cop0::LOAD, address, paddr)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { u32 value = mem.Read(regs, paddr); if (RT(instr) != 0) [[likely]] { @@ -454,9 +454,9 @@ void Interpreter::lwu(u32 instr) { void Interpreter::sb(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr; - if (!MapVAddr(regs, STORE, address, paddr)) { - HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); + if (!regs.cop0.MapVAddr(Cop0::STORE, address, paddr)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { mem.Write(regs, paddr, regs.gpr[RT(instr)]); } @@ -466,16 +466,16 @@ void Interpreter::sc(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; if (check_address_error(0b11, address)) { - FireException(regs, ExceptionCode::AddressErrorStore, 0, regs.oldPC); + regs.cop0.FireException(ExceptionCode::AddressErrorStore, 0, regs.oldPC); return; } if(regs.cop0.llbit) { regs.cop0.llbit = false; u32 paddr = 0; - if(!MapVAddr(regs, STORE, address, paddr)) { - HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); + if(!regs.cop0.MapVAddr(Cop0::STORE, address, paddr)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { mem.Write(regs, paddr, regs.gpr[RT(instr)]); if (RT(instr) != 0) [[likely]] { @@ -490,24 +490,24 @@ 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, regs.oldPC); + if (!regs.cop0.is64BitAddressing && !regs.cop0.kernelMode) { + regs.cop0.FireException(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, regs.oldPC); + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(ExceptionCode::AddressErrorStore, 0, regs.oldPC); return; } if(regs.cop0.llbit) { regs.cop0.llbit = false; u32 paddr = 0; - if(!MapVAddr(regs, STORE, address, paddr)) { - HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); + if(!regs.cop0.MapVAddr(Cop0::STORE, address, paddr)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { mem.Write(regs, paddr, regs.gpr[RT(instr)]); if (RT(instr) != 0) [[likely]] { @@ -525,9 +525,9 @@ void Interpreter::sh(u32 instr) { s64 address = regs.gpr[RS(instr)] + (s16)instr; u32 physical; - if(!MapVAddr(regs, STORE, address, physical)) { - HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); + if(!regs.cop0.MapVAddr(Cop0::STORE, address, physical)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { mem.Write(regs, physical, regs.gpr[RT(instr)]); } @@ -537,15 +537,15 @@ void Interpreter::sw(u32 instr) { s16 offset = instr; u64 address = regs.gpr[RS(instr)] + offset; if (check_address_error(0b11, address)) { - HandleTLBException(regs, address); - FireException(regs, ExceptionCode::AddressErrorStore, 0, regs.oldPC); + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(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, regs.oldPC); + if(!regs.cop0.MapVAddr(Cop0::STORE, address, physical)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { mem.Write(regs, physical, regs.gpr[RT(instr)]); } @@ -554,15 +554,15 @@ void Interpreter::sw(u32 instr) { 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, regs.oldPC); + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(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, regs.oldPC); + if(!regs.cop0.MapVAddr(Cop0::STORE, address, physical)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { mem.Write(regs, physical, regs.gpr[RT(instr)]); } @@ -571,9 +571,9 @@ void Interpreter::sd(u32 instr) { void Interpreter::sdl(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr; - if (!MapVAddr(regs, STORE, address, paddr)) { - HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); + if (!regs.cop0.MapVAddr(Cop0::STORE, address, paddr)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { s32 shift = 8 * ((address ^ 0) & 7); u64 mask = 0xFFFFFFFFFFFFFFFF >> shift; @@ -586,9 +586,9 @@ void Interpreter::sdl(u32 instr) { void Interpreter::sdr(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr; - if (!MapVAddr(regs, STORE, address, paddr)) { - HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); + if (!regs.cop0.MapVAddr(Cop0::STORE, address, paddr)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { s32 shift = 8 * ((address ^ 7) & 7); u64 mask = 0xFFFFFFFFFFFFFFFF << shift; @@ -601,9 +601,9 @@ void Interpreter::sdr(u32 instr) { void Interpreter::swl(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr; - if (!MapVAddr(regs, STORE, address, paddr)) { - HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); + if (!regs.cop0.MapVAddr(Cop0::STORE, address, paddr)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { u32 shift = 8 * ((address ^ 0) & 3); u32 mask = 0xFFFFFFFF >> shift; @@ -616,9 +616,9 @@ void Interpreter::swl(u32 instr) { void Interpreter::swr(u32 instr) { u64 address = regs.gpr[RS(instr)] + (s16)instr; u32 paddr; - if (!MapVAddr(regs, STORE, address, paddr)) { - HandleTLBException(regs, address); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); + if (!regs.cop0.MapVAddr(Cop0::STORE, address, paddr)) { + regs.cop0.HandleTLBException(address); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::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, regs.oldPC); + regs.cop0.FireException(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, regs.oldPC); + regs.cop0.FireException(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, regs.oldPC); + regs.cop0.FireException(ExceptionCode::Trap, 0, regs.oldPC); } } diff --git a/src/backend/core/mmio/PIF.cpp b/src/backend/core/mmio/PIF.cpp index 369a8097..1f571e22 100644 --- a/src/backend/core/mmio/PIF.cpp +++ b/src/backend/core/mmio/PIF.cpp @@ -60,7 +60,7 @@ void PIF::MaybeLoadMempak() { } } -FORCE_INLINE size_t getSaveSize(SaveType saveType) { +FORCE_INLINE size_t GetSaveSize(SaveType saveType) { switch (saveType) { case SAVE_NONE: return 0; @@ -87,7 +87,7 @@ void PIF::LoadEeprom(SaveType saveType, const std::string& path) { eeprom.unmap(); } - eepromSize = getSaveSize(saveType); + eepromSize = GetSaveSize(saveType); FILE *f = fopen(eepromPath.c_str(), "rb"); if (!f) { f = fopen(eepromPath.c_str(), "wb"); @@ -133,11 +133,11 @@ void PIF::CICChallenge() { } } -FORCE_INLINE u8 data_crc(const u8* data) { +FORCE_INLINE u8 DataCRC(const u8* data) { u8 crc = 0; for (int i = 0; i <= 32; i++) { for (int j = 7; j >= 0; j--) { - u8 xor_val = ((crc & 0x80) != 0) ? 0x85 : 0x00; + u8 xorVal = ((crc & 0x80) != 0) ? 0x85 : 0x00; crc <<= 1; if (i < 32) { @@ -146,7 +146,7 @@ FORCE_INLINE u8 data_crc(const u8* data) { } } - crc ^= xor_val; + crc ^= xorVal; } } @@ -260,7 +260,7 @@ void PIF::MempakRead(const u8* cmd, u8* res) { // offset must be 32-byte aligned offset &= ~0x1F; - switch (getAccessoryType()) { + switch (GetAccessoryType()) { case ACCESSORY_NONE: break; case ACCESSORY_MEMPACK: @@ -274,7 +274,7 @@ void PIF::MempakRead(const u8* cmd, u8* res) { } // CRC byte - res[32] = data_crc(res); + res[32] = DataCRC(res); } void PIF::MempakWrite(u8* cmd, u8* res) { @@ -288,7 +288,7 @@ void PIF::MempakWrite(u8* cmd, u8* res) { // offset must be 32-byte aligned offset &= ~0x1F; - switch (getAccessoryType()) { + switch (GetAccessoryType()) { case ACCESSORY_NONE: break; case ACCESSORY_MEMPACK: @@ -299,14 +299,14 @@ void PIF::MempakWrite(u8* cmd, u8* res) { case ACCESSORY_RUMBLE_PACK: break; } // CRC byte - res[0] = data_crc(&cmd[5]); + res[0] = DataCRC(&cmd[5]); } void PIF::EepromRead(const u8* cmd, u8* res, const Mem& mem) const { assert(mem.saveType == SAVE_EEPROM_4k || mem.saveType == SAVE_EEPROM_16k); if (channel == 4) { u8 offset = cmd[3]; - if ((offset * 8) >= getSaveSize(mem.saveType)) { + if ((offset * 8) >= GetSaveSize(mem.saveType)) { Util::panic("Out of range EEPROM read! offset: {:02X}", offset); } @@ -320,7 +320,7 @@ void PIF::EepromWrite(const u8* cmd, u8* res, const Mem& mem) { assert(mem.saveType == SAVE_EEPROM_4k || mem.saveType == SAVE_EEPROM_16k); if (channel == 4) { u8 offset = cmd[3]; - if ((offset * 8) >= getSaveSize(mem.saveType)) { + if ((offset * 8) >= GetSaveSize(mem.saveType)) { Util::panic("Out of range EEPROM write! offset: {:02X}", offset); } diff --git a/src/backend/core/mmio/PIF.hpp b/src/backend/core/mmio/PIF.hpp index 07e91775..d78e02e5 100644 --- a/src/backend/core/mmio/PIF.hpp +++ b/src/backend/core/mmio/PIF.hpp @@ -191,7 +191,7 @@ struct PIF { ram[addr & PIF_RAM_DSIZE] = val; } - FORCE_INLINE AccessoryType getAccessoryType() const { + FORCE_INLINE AccessoryType GetAccessoryType() const { if (channel >= 4 || joybusDevices[channel].type != JOYBUS_CONTROLLER) { return ACCESSORY_NONE; } else { diff --git a/src/backend/core/mmio/SI.hpp b/src/backend/core/mmio/SI.hpp index e19e642b..81ca5ea4 100644 --- a/src/backend/core/mmio/SI.hpp +++ b/src/backend/core/mmio/SI.hpp @@ -34,7 +34,5 @@ struct SI { PIF pif; }; -// just to silence warning, it is used. -[[maybe_unused]] static void DMA(Mem& mem, Registers& regs); #define SI_DMA_DELAY (65536 * 2) } \ No newline at end of file diff --git a/src/backend/core/registers/Cop0.cpp b/src/backend/core/registers/Cop0.cpp index 5663af0c..c20f2cb1 100644 --- a/src/backend/core/registers/Cop0.cpp +++ b/src/backend/core/registers/Cop0.cpp @@ -3,7 +3,7 @@ #include namespace n64 { -Cop0::Cop0() { +Cop0::Cop0(Registers& regs) : regs(regs) { Reset(); } @@ -176,7 +176,7 @@ static FORCE_INLINE u64 getVPN(u64 addr, u64 pageMask) { return vpn & ~mask; } -TLBEntry* TLBTryMatch(Registers& regs, u64 vaddr, int* match) { +TLBEntry* Cop0::TLBTryMatch(u64 vaddr, int* match) { for(int i = 0; i < 32; i++) { TLBEntry *entry = ®s.cop0.tlb[i]; if(entry->initialized) { @@ -198,8 +198,8 @@ TLBEntry* TLBTryMatch(Registers& regs, u64 vaddr, int* match) { return nullptr; } -bool ProbeTLB(Registers& regs, TLBAccessType access_type, u64 vaddr, u32& paddr, int* match) { - TLBEntry* entry = TLBTryMatch(regs, vaddr, match); +bool Cop0::ProbeTLB(TLBAccessType access_type, u64 vaddr, u32& paddr, int* match) { + TLBEntry* entry = TLBTryMatch(vaddr, match); if(!entry) { regs.cop0.tlbError = MISS; return false; @@ -250,7 +250,7 @@ FORCE_INLINE bool Is64BitAddressing(Cop0& cp0, u64 addr) { } } -void FireException(Registers& regs, ExceptionCode code, int cop, s64 pc) { +void Cop0::FireException(ExceptionCode code, int cop, s64 pc) { bool old_exl = regs.cop0.status.exl; if(!regs.cop0.status.exl) { @@ -294,7 +294,7 @@ void FireException(Registers& regs, ExceptionCode code, int cop, s64 pc) { regs.cop0.Update(); } -void HandleTLBException(Registers& regs, u64 vaddr) { +void Cop0::HandleTLBException(u64 vaddr) { u64 vpn2 = (vaddr >> 13) & 0x7FFFF; u64 xvpn2 = (vaddr >> 13) & 0x7FFFFFF; regs.cop0.badVaddr = vaddr; @@ -305,7 +305,7 @@ void HandleTLBException(Registers& regs, u64 vaddr) { regs.cop0.entryHi.r = (vaddr >> 62) & 3; } -ExceptionCode GetTLBExceptionCode(TLBError error, TLBAccessType accessType) { +ExceptionCode Cop0::GetTLBExceptionCode(TLBError error, TLBAccessType accessType) { switch(error) { case NONE: Util::panic("Getting TLB exception with error NONE"); case INVALID: case MISS: @@ -324,7 +324,7 @@ ExceptionCode GetTLBExceptionCode(TLBError error, TLBAccessType accessType) { template void Cop0::decode(T& cpu, u32 instr) { if constexpr (std::is_same_v) { - decodeInterp(cpu.regs, instr); + decodeInterp(instr); } else if constexpr (std::is_same_v) { decodeJIT(cpu, instr); } else { @@ -339,21 +339,21 @@ void Cop0::decodeJIT(JIT& cpu, u32 instr) { } -void Cop0::decodeInterp(Registers& regs, u32 instr) { +void Cop0::decodeInterp(u32 instr) { u8 mask_cop = (instr >> 21) & 0x1F; u8 mask_cop2 = instr & 0x3F; switch(mask_cop) { - case 0x00: mfc0(regs, instr); break; - case 0x01: dmfc0(regs, instr); break; - case 0x04: mtc0(regs, instr); break; - case 0x05: dmtc0(regs, instr); break; + case 0x00: mfc0(instr); break; + case 0x01: dmfc0(instr); break; + case 0x04: mtc0(instr); break; + case 0x05: dmtc0(instr); break; case 0x10 ... 0x1F: switch(mask_cop2) { case 0x01: tlbr(); break; case 0x02: tlbw(index.i); break; case 0x06: tlbw(GetRandom()); break; - case 0x08: tlbp(regs); break; - case 0x18: eret(regs); break; + case 0x08: tlbp(); break; + case 0x18: eret(); break; default: Util::panic("Unimplemented COP0 function {} {} ({:08X}) ({:016lX})", mask_cop2 >> 3, mask_cop2 & 7, instr, regs.oldPC); } break; @@ -361,23 +361,23 @@ void Cop0::decodeInterp(Registers& regs, u32 instr) { } } -bool MapVAddr(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr) { - if(regs.cop0.is_64bit_addressing) [[unlikely]] { - if (regs.cop0.kernel_mode) [[likely]] { - return MapVAddr64(regs, accessType, vaddr, paddr); - } else if (regs.cop0.user_mode) { - return UserMapVAddr64(regs, accessType, vaddr, paddr); - } else if (regs.cop0.supervisor_mode) { +bool Cop0::MapVAddr(TLBAccessType accessType, u64 vaddr, u32& paddr) { + if(regs.cop0.is64BitAddressing) [[unlikely]] { + if (regs.cop0.kernelMode) [[likely]] { + return MapVAddr64(accessType, vaddr, paddr); + } else if (regs.cop0.userMode) { + return UserMapVAddr64(accessType, vaddr, paddr); + } else if (regs.cop0.supervisorMode) { Util::panic("Supervisor mode memory access, 64 bit mode"); } else { Util::panic("Unknown mode! This should never happen!"); } } else { - if (regs.cop0.kernel_mode) [[likely]] { - return MapVAddr32(regs, accessType, vaddr, paddr); - } else if (regs.cop0.user_mode) { - return UserMapVAddr32(regs, accessType, vaddr, paddr); - } else if (regs.cop0.supervisor_mode) { + if (regs.cop0.kernelMode) [[likely]] { + return MapVAddr32(accessType, vaddr, paddr); + } else if (regs.cop0.userMode) { + return UserMapVAddr32(accessType, vaddr, paddr); + } else if (regs.cop0.supervisorMode) { Util::panic("Supervisor mode memory access, 32 bit mode"); } else { Util::panic("Unknown mode! This should never happen!"); @@ -385,20 +385,20 @@ bool MapVAddr(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr) } } -bool UserMapVAddr32(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr) { +bool Cop0::UserMapVAddr32(TLBAccessType accessType, u64 vaddr, u32& paddr) { switch (vaddr) { case VREGION_KUSEG: - return ProbeTLB(regs, accessType, s64(s32(vaddr)), paddr, nullptr); + return ProbeTLB(accessType, s64(s32(vaddr)), paddr, nullptr); default: regs.cop0.tlbError = DISALLOWED_ADDRESS; return false; } } -bool MapVAddr32(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr) { +bool Cop0::MapVAddr32(TLBAccessType accessType, u64 vaddr, u32& paddr) { switch((u32(vaddr) >> 29) & 7) { case 0 ... 3: case 7: - return ProbeTLB(regs, accessType, s64(s32(vaddr)), paddr, nullptr); + return ProbeTLB(accessType, s64(s32(vaddr)), paddr, nullptr); case 4 ... 5: paddr = vaddr & 0x1FFFFFFF; return true; @@ -410,22 +410,22 @@ bool MapVAddr32(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr return false; } -bool UserMapVAddr64(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr) { +bool Cop0::UserMapVAddr64(TLBAccessType accessType, u64 vaddr, u32& paddr) { switch (vaddr) { case VREGION_XKUSEG: - return ProbeTLB(regs, accessType, vaddr, paddr, nullptr); + return ProbeTLB(accessType, vaddr, paddr, nullptr); default: regs.cop0.tlbError = DISALLOWED_ADDRESS; return false; } } -bool MapVAddr64(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr) { +bool Cop0::MapVAddr64(TLBAccessType accessType, u64 vaddr, u32& paddr) { switch (vaddr) { case VREGION_XKUSEG: case VREGION_XKSSEG: - return ProbeTLB(regs, accessType, vaddr, paddr, nullptr); + return ProbeTLB(accessType, vaddr, paddr, nullptr); case VREGION_XKPHYS: { - if (!regs.cop0.kernel_mode) { + if (!regs.cop0.kernelMode) { Util::panic("Access to XKPHYS address 0x{:016X} when outside kernel mode!", vaddr); } u8 high_two_bits = (vaddr >> 62) & 0b11; @@ -444,7 +444,7 @@ bool MapVAddr64(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr return true; } case VREGION_XKSEG: - return ProbeTLB(regs, accessType, vaddr, paddr, nullptr); + return ProbeTLB(accessType, vaddr, paddr, nullptr); case VREGION_CKSEG0: // Identical to kseg0 in 32 bit mode. // Unmapped translation. Subtract the base address of the space to get the physical address. @@ -460,7 +460,7 @@ bool MapVAddr64(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr case VREGION_CKSSEG: Util::panic("Resolving virtual address 0x{:016X} (VREGION_CKSSEG) in 64 bit mode", vaddr); case VREGION_CKSEG3: - return ProbeTLB(regs, accessType, vaddr, paddr, nullptr); + return ProbeTLB(accessType, vaddr, paddr, nullptr); case VREGION_XBAD1: case VREGION_XBAD2: case VREGION_XBAD3: diff --git a/src/backend/core/registers/Cop0.hpp b/src/backend/core/registers/Cop0.hpp index 80cc6b96..1807126c 100644 --- a/src/backend/core/registers/Cop0.hpp +++ b/src/backend/core/registers/Cop0.hpp @@ -189,8 +189,6 @@ enum class ExceptionCode : u8 { Watch = 23 }; -void FireException(Registers& regs, ExceptionCode code, int cop, s64 pc); - union Cop0Context { u64 raw; struct { @@ -211,7 +209,7 @@ union Cop0XContext { }; struct Cop0 { - Cop0(); + Cop0(Registers&); u32 GetReg32(u8); [[nodiscard]] u64 GetReg64(u8) const; @@ -221,10 +219,10 @@ struct Cop0 { void Reset(); - bool kernel_mode{true}; - bool supervisor_mode{false}; - bool user_mode{false}; - bool is_64bit_addressing{false}; + bool kernelMode{true}; + bool supervisorMode{false}; + bool userMode{false}; + bool is64BitAddressing{false}; bool llbit{}; PageMask pageMask{}; @@ -267,47 +265,45 @@ struct Cop0 { FORCE_INLINE void Update() { bool exception = status.exl || status.erl; - kernel_mode = exception || status.ksu == 0; - supervisor_mode = !exception && status.ksu == 1; - user_mode = !exception && status.ksu == 2; - is_64bit_addressing = - (kernel_mode && status.kx) - || (supervisor_mode && status.sx) - || (user_mode && status.ux); + kernelMode = exception || status.ksu == 0; + supervisorMode = !exception && status.ksu == 1; + userMode = !exception && status.ksu == 2; + is64BitAddressing = + (kernelMode && status.kx) + || (supervisorMode && status.sx) + || (userMode && status.ux); } + + enum TLBAccessType { + LOAD, STORE + }; + + bool ProbeTLB(TLBAccessType access_type, u64 vaddr, u32& paddr, int* match); + void FireException(ExceptionCode code, int cop, s64 pc); + bool MapVAddr(TLBAccessType accessType, u64 vaddr, u32& paddr); + bool UserMapVAddr32(TLBAccessType accessType, u64 vaddr, u32& paddr); + bool MapVAddr32(TLBAccessType accessType, u64 vaddr, u32& paddr); + bool UserMapVAddr64(TLBAccessType accessType, u64 vaddr, u32& paddr); + bool MapVAddr64(TLBAccessType accessType, u64 vaddr, u32& paddr); + + TLBEntry* TLBTryMatch(u64 vaddr, int* match); + void HandleTLBException(u64 vaddr); + ExceptionCode GetTLBExceptionCode(TLBError error, TLBAccessType access_type); private: + Registers& regs; [[nodiscard]] FORCE_INLINE u32 GetWired() const { return wired & 0x3F; } [[nodiscard]] FORCE_INLINE u32 GetCount() const { return u32(u64(count >> 1)); } - void decodeInterp(Registers&, u32); + void decodeInterp(u32); void decodeJIT(JIT&, u32); - void mtc0(Registers&, u32); - void dmtc0(Registers&, u32); - void mfc0(Registers&, u32); - void dmfc0(Registers&, u32) const; - void eret(Registers&); + void mtc0(u32); + void dmtc0(u32); + void mfc0(u32); + void dmfc0(u32) const; + void eret(); void tlbr(); void tlbw(int); - void tlbp(n64::Registers&); + void tlbp(); }; - -struct Registers; -enum class ExceptionCode : u8; - -enum TLBAccessType { - LOAD, STORE -}; - -bool ProbeTLB(Registers& regs, TLBAccessType access_type, u64 vaddr, u32& paddr, int* match); - -bool MapVAddr(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr); -bool UserMapVAddr32(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr); -bool MapVAddr32(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr); -bool UserMapVAddr64(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr); -bool MapVAddr64(Registers& regs, TLBAccessType accessType, u64 vaddr, u32& paddr); - -TLBEntry* TLBTryMatch(Registers& regs, u64 vaddr, int* match); -void HandleTLBException(Registers& regs, u64 vaddr); -ExceptionCode GetTLBExceptionCode(TLBError error, TLBAccessType access_type); } \ No newline at end of file diff --git a/src/backend/core/registers/Cop1.hpp b/src/backend/core/registers/Cop1.hpp index 2cccfba5..bbbb63ed 100644 --- a/src/backend/core/registers/Cop1.hpp +++ b/src/backend/core/registers/Cop1.hpp @@ -89,7 +89,7 @@ struct JIT; struct Registers; struct Cop1 { -#define CheckFPUUsable_PreserveCause() do { if(!regs.cop0.status.cu1) { FireException(regs, ExceptionCode::CoprocessorUnusable, 1, regs.oldPC); return; } } while(0) +#define CheckFPUUsable_PreserveCause() do { if(!regs.cop0.status.cu1) { regs.cop0.FireException(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/Registers.cpp b/src/backend/core/registers/Registers.cpp index 8eecf253..0ca35ada 100644 --- a/src/backend/core/registers/Registers.cpp +++ b/src/backend/core/registers/Registers.cpp @@ -1,7 +1,7 @@ #include namespace n64 { -Registers::Registers() { +Registers::Registers() : cop0(*this) { Reset(); } diff --git a/src/backend/core/registers/cop/cop0instructions.cpp b/src/backend/core/registers/cop/cop0instructions.cpp index 9f901eee..2bc1da5d 100644 --- a/src/backend/core/registers/cop/cop0instructions.cpp +++ b/src/backend/core/registers/cop/cop0instructions.cpp @@ -3,23 +3,23 @@ #include namespace n64 { -void Cop0::mtc0(Registers& regs, u32 instr) { +void Cop0::mtc0(u32 instr) { SetReg32(RD(instr), regs.gpr[RT(instr)]); } -void Cop0::dmtc0(Registers& regs, u32 instr) { +void Cop0::dmtc0(u32 instr) { SetReg64(RD(instr), regs.gpr[RT(instr)]); } -void Cop0::mfc0(Registers& regs, u32 instr) { +void Cop0::mfc0(u32 instr) { regs.gpr[RT(instr)] = s32(GetReg32(RD(instr))); } -void Cop0::dmfc0(Registers& regs, u32 instr) const { +void Cop0::dmfc0(u32 instr) const { regs.gpr[RT(instr)] = s64(GetReg64(RD(instr))); } -void Cop0::eret(Registers& regs) { +void Cop0::eret() { if(status.erl) { regs.SetPC64(ErrorEPC); status.erl = false; @@ -69,9 +69,9 @@ void Cop0::tlbw(int index_) { tlb[index_].initialized = true; } -void Cop0::tlbp(Registers& regs) { +void Cop0::tlbp() { int match = -1; - TLBEntry* entry = TLBTryMatch(regs, entryHi.raw, &match); + TLBEntry* entry = TLBTryMatch(entryHi.raw, &match); if(entry && match >= 0) { index.raw = match; } else { diff --git a/src/backend/core/registers/cop/cop1instructions.cpp b/src/backend/core/registers/cop/cop1instructions.cpp index b30b9b4e..e94e1e3d 100644 --- a/src/backend/core/registers/cop/cop1instructions.cpp +++ b/src/backend/core/registers/cop/cop1instructions.cpp @@ -58,7 +58,7 @@ FORCE_INLINE bool FireFPUException(Registers& regs) { FCR31& fcr31 = regs.cop1.fcr31; u32 enable = fcr31.enable | (1 << 5); if(fcr31.cause & enable) { - FireException(regs, ExceptionCode::FloatingPointError, 0, regs.oldPC); + regs.cop0.FireException(ExceptionCode::FloatingPointError, 0, regs.oldPC); return true; } @@ -982,9 +982,9 @@ void Cop1::lwc1Interp(Registers& regs, Mem& mem, u32 instr) { u64 addr = (s64)(s16)instr + regs.gpr[BASE(instr)]; u32 physical; - if(!MapVAddr(regs, LOAD, addr, physical)) { - HandleTLBException(regs, addr); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); + if(!regs.cop0.MapVAddr(Cop0::LOAD, addr, physical)) { + regs.cop0.HandleTLBException(addr); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { u32 data = mem.Read(regs, physical); FGR(regs.cop0.status, FT(instr)) = data; @@ -995,9 +995,9 @@ void Cop1::swc1Interp(Registers& regs, Mem& mem, u32 instr) { u64 addr = (s64)(s16)instr + regs.gpr[BASE(instr)]; u32 physical; - if(!MapVAddr(regs, STORE, addr, physical)) { - HandleTLBException(regs, addr); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); + if(!regs.cop0.MapVAddr(Cop0::STORE, addr, physical)) { + regs.cop0.HandleTLBException(addr); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { mem.Write(regs, physical, FGR(regs.cop0.status, FT(instr))); } @@ -1013,9 +1013,9 @@ void Cop1::ldc1Interp(Registers& regs, Mem& mem, u32 instr) { u64 addr = (s64)(s16)instr + regs.gpr[BASE(instr)]; u32 physical; - if(!MapVAddr(regs, LOAD, addr, physical)) { - HandleTLBException(regs, addr); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, LOAD), 0, regs.oldPC); + if(!regs.cop0.MapVAddr(Cop0::LOAD, addr, physical)) { + regs.cop0.HandleTLBException(addr); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); } else { u64 data = mem.Read(regs, physical); FGR(regs.cop0.status, FT(instr)) = data; @@ -1026,9 +1026,9 @@ void Cop1::sdc1Interp(Registers& regs, Mem& mem, u32 instr) { u64 addr = (s64)(s16)instr + regs.gpr[BASE(instr)]; u32 physical; - if(!MapVAddr(regs, STORE, addr, physical)) { - HandleTLBException(regs, addr); - FireException(regs, GetTLBExceptionCode(regs.cop0.tlbError, STORE), 0, regs.oldPC); + if(!regs.cop0.MapVAddr(Cop0::STORE, addr, physical)) { + regs.cop0.HandleTLBException(addr); + regs.cop0.FireException(regs.cop0.GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { mem.Write(regs, physical, FGR(regs.cop0.status, FT(instr))); }