From 367a82c11d4c7f4ce4f8a8cedfd1b17b93775f53 Mon Sep 17 00:00:00 2001 From: SimoneN64 Date: Mon, 28 Aug 2023 15:58:18 +0200 Subject: [PATCH] Cop0's Index as a union --- src/backend/core/registers/Cop0.cpp | 14 ++++---- src/backend/core/registers/Cop0.hpp | 12 ++++++- .../core/registers/cop/cop0instructions.cpp | 32 +++++++++---------- 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/backend/core/registers/Cop0.cpp b/src/backend/core/registers/Cop0.cpp index e56c468e..dc32365f 100644 --- a/src/backend/core/registers/Cop0.cpp +++ b/src/backend/core/registers/Cop0.cpp @@ -19,13 +19,13 @@ void Cop0::Reset() { EPC = 0xFFFFFFFFFFFFFFFFll; ErrorEPC = 0xFFFFFFFFFFFFFFFFll; wired = 0; - index = 63; + index.raw = 63; badVaddr = 0xFFFFFFFFFFFFFFFF; } u32 Cop0::GetReg32(u8 addr) { switch(addr) { - case COP0_REG_INDEX: return index & 0x8000003F; + case COP0_REG_INDEX: return index.raw & INDEX_MASK; case COP0_REG_RANDOM: return GetRandom(); case COP0_REG_ENTRYLO0: return entryLo0.raw; case COP0_REG_ENTRYLO1: return entryLo1.raw; @@ -54,7 +54,7 @@ u32 Cop0::GetReg32(u8 addr) { case 23: case 24: case 25: case 31: return openbus; default: - Util::panic("Unsupported word read from COP0 register {}", index); + Util::panic("Unsupported word read from COP0 register {}", addr); } } @@ -75,14 +75,14 @@ u64 Cop0::GetReg64(u8 addr) const { case 23: case 24: case 25: case 31: return openbus; default: - Util::panic("Unsupported dword read from COP0 register {}", index); + Util::panic("Unsupported dword read from COP0 register {}", addr); } } void Cop0::SetReg32(u8 addr, u32 value) { openbus = value & 0xFFFFFFFF; switch(addr) { - case COP0_REG_INDEX: index = value; break; + case COP0_REG_INDEX: index.raw = value & INDEX_MASK; break; case COP0_REG_RANDOM: break; case COP0_REG_ENTRYLO0: entryLo0.raw = value & ENTRY_LO_MASK; @@ -137,7 +137,7 @@ void Cop0::SetReg32(u8 addr, u32 value) { case 23: case 24: case 25: case 31: break; default: - Util::panic("Unsupported word write from COP0 register {}", index); + Util::panic("Unsupported word write from COP0 register {}", addr); } } @@ -352,7 +352,7 @@ void Cop0::decodeInterp(Registers& regs, u32 instr) { case 0x10 ... 0x1F: switch(mask_cop2) { case 0x01: tlbr(); break; - case 0x02: tlbw(index & 0x3F); break; + case 0x02: tlbw(index.i); break; case 0x06: tlbw(GetRandom()); break; case 0x08: tlbp(regs); break; case 0x18: eret(regs); break; diff --git a/src/backend/core/registers/Cop0.hpp b/src/backend/core/registers/Cop0.hpp index 4b190e9c..d9b33201 100644 --- a/src/backend/core/registers/Cop0.hpp +++ b/src/backend/core/registers/Cop0.hpp @@ -5,6 +5,7 @@ namespace n64 { #define STATUS_MASK 0xFF57FFFF #define CONFIG_MASK 0x0F00800F +#define INDEX_MASK 0x8000003F #define COP0_REG_INDEX 0 #define COP0_REG_RANDOM 1 #define COP0_REG_ENTRYLO0 2 @@ -133,6 +134,15 @@ union PageMask { }; }; +union Index { + u32 raw; + struct { + unsigned i:6; + unsigned:25; + unsigned p:1; + }; +}; + struct TLBEntry { bool initialized; union { @@ -220,7 +230,7 @@ struct Cop0 { PageMask pageMask{}; EntryHi entryHi{}; EntryLo entryLo0{}, entryLo1{}; - u32 index{}; + Index index{}; Cop0Context context{}; u32 wired{}, r7{}; u64 badVaddr{}, count{}; diff --git a/src/backend/core/registers/cop/cop0instructions.cpp b/src/backend/core/registers/cop/cop0instructions.cpp index 0dffe94e..e89e5e1c 100644 --- a/src/backend/core/registers/cop/cop0instructions.cpp +++ b/src/backend/core/registers/cop/cop0instructions.cpp @@ -32,12 +32,11 @@ void Cop0::eret(Registers& regs) { void Cop0::tlbr() { - u8 Index = index & 0b111111; - if (Index >= 32) { - Util::panic("TLBR with TLB index {}", index); + if (index.i >= 32) { + Util::panic("TLBR with TLB index {}", index.i); } - TLBEntry entry = tlb[Index]; + TLBEntry entry = tlb[index.i]; entryHi.raw = entry.entryHi.raw; entryLo0.raw = entry.entryLo0.raw & 0x3FFFFFFF; @@ -48,34 +47,35 @@ void Cop0::tlbr() { pageMask.raw = entry.pageMask.raw; } -void Cop0::tlbw(int index) { +void Cop0::tlbw(int index_) { PageMask page_mask{}; page_mask = pageMask; u32 top = page_mask.mask & 0xAAA; page_mask.mask = top | (top >> 1); - if(index >= 32) { - Util::panic("TLBWI with TLB index {}", index); + if(index_ >= 32) { + Util::panic("TLBWI with TLB index {}", index_); } - tlb[index].entryHi.raw = entryHi.raw; - tlb[index].entryHi.vpn2 &= ~page_mask.mask; + tlb[index_].entryHi.raw = entryHi.raw; + tlb[index_].entryHi.vpn2 &= ~page_mask.mask; - tlb[index].entryLo0.raw = entryLo0.raw & 0x03FFFFFE; - tlb[index].entryLo1.raw = entryLo1.raw & 0x03FFFFFE; - tlb[index].pageMask.raw = page_mask.raw; + tlb[index_].entryLo0.raw = entryLo0.raw & 0x03FFFFFE; + tlb[index_].entryLo1.raw = entryLo1.raw & 0x03FFFFFE; + tlb[index_].pageMask.raw = page_mask.raw; - tlb[index].global = entryLo0.g && entryLo1.g; - tlb[index].initialized = true; + tlb[index_].global = entryLo0.g && entryLo1.g; + tlb[index_].initialized = true; } void Cop0::tlbp(Registers& regs) { int match = -1; TLBEntry* entry = TLBTryMatch(regs, entryHi.raw, &match); if(entry && match >= 0) { - index = match; + index.i = match; + index.p = 0; } else { - index = 0x80000000; + index.p = 1; } }