From 5ae2af0f331a53c44e2b39aa81a80185962eaca9 Mon Sep 17 00:00:00 2001 From: iris Date: Wed, 27 May 2026 18:09:59 +0200 Subject: [PATCH] maybe we need to use the physical address?? --- .gitignore | 3 +- src/backend/core/Cache.cpp | 2 + src/backend/core/Interpreter.cpp | 67 ++++++------------- src/backend/core/Interpreter.hpp | 16 ++--- src/backend/core/RDP.cpp | 4 -- .../core/interpreter/cop1instructions.cpp | 4 +- src/backend/core/interpreter/instructions.cpp | 20 +++--- 7 files changed, 44 insertions(+), 72 deletions(-) diff --git a/.gitignore b/.gitignore index c72e622..3665593 100644 --- a/.gitignore +++ b/.gitignore @@ -27,4 +27,5 @@ compile_commands.json *.diagsession tests/ .DS_Store -resources/version.hpp \ No newline at end of file +resources/version.hpp +__cmake_systeminformation/CMakeFiles/ diff --git a/src/backend/core/Cache.cpp b/src/backend/core/Cache.cpp index 94bad01..1f4367d 100644 --- a/src/backend/core/Cache.cpp +++ b/src/backend/core/Cache.cpp @@ -52,6 +52,7 @@ void DataCache::WriteBack(u64 vaddr, u32 paddr) { u32 origPhysAddr = (line.ptag << 12) | (paddr & 0xfff); u32 lineStart = GetDCacheLineStart(origPhysAddr); + Core::GetInstance().interpreter.EvictCachedBlock(vaddr); for (int i = 0; i < 16; i++) { mmio.rdp.WriteRDRAM(lineStart + i, line.data[i]); } @@ -86,6 +87,7 @@ void InstructionCache::WriteBack(u64 vaddr, u32 paddr, u32 ptag) { if (line.ptag == ptag && line.valid) { u32 origPhysAddr = (line.ptag << 12) | (paddr & 0xfff); u32 lineStart = GetICacheLineStart(origPhysAddr); + Core::GetInstance().interpreter.EvictCachedBlock(vaddr); for (int i = 0; i < 16; i++) { mmio.rdp.WriteRDRAM(lineStart + i, line.data[i]); } diff --git a/src/backend/core/Interpreter.cpp b/src/backend/core/Interpreter.cpp index 105158c..addd948 100644 --- a/src/backend/core/Interpreter.cpp +++ b/src/backend/core/Interpreter.cpp @@ -96,26 +96,6 @@ u32 Interpreter::Step() { return 1; } -const CachedLine &CachedState::GetLine(u64 addr) { - u32 offset; - u32 page = DivideAddr(addr, offset); - return blocks[page].lines[offset]; -} - -void CachedState::InsertLine(u64 addr, const CachedLine &line) { - u32 offset; - u32 page = DivideAddr(addr, offset); - - blocks[page].lines[offset] = line; -} - -void CachedState::EvictLine(u64 addr) { - u32 offset; - u32 page = DivideAddr(addr, offset); - - blocks[page].lines[offset] = CachedLine(); -} - u32 Interpreter::ExecuteCached() { auto addr = regs.pc; auto blockAddr = addr; @@ -123,46 +103,38 @@ u32 Interpreter::ExecuteCached() { auto offset = addr & 0xfff; auto &blocks = cachedState.blocks; - if (page >= blocks.size()) - blocks.push_back(); - - if (page < blocks.size()) { + if (blocks[page].code.size() >= offset) { const auto &block = blocks[page]; - if (blocks[page].len > 0) { - for (u32 i = 0; i < block.len; i++) { - if (!MaybeAdvance()) - return i + 1; + for (u32 i = 0; i < block.code.size(); i++) { + if (!MaybeAdvance()) + return i + 1; - Instruction instr = block.code[i]; - DecodeExecute(instr); + Instruction instr = block.code[i]; + DecodeExecute(instr); - // Branch likely with false condition, it wasn't taken so don't execute the delay slot - if (IsBranchLikely(instr) && !regs.delaySlot) - break; - } - - if (block.cycles == 0) - Scheduler::GetInstance().SkipToNext(); - - return block.cycles; + // Branch likely with false condition, it wasn't taken so don't execute the delay slot + if (IsBranchLikely(instr) && !regs.delaySlot) + break; } + + if (block.cycles == 0) + Scheduler::GetInstance().SkipToNext(); + + return block.cycles; } - if (line.code.size() > 0) { - } - - std::vector code; - code.resize(MAX_INSTRUCTION_PER_LINE); + auto &block = blocks[page]; + block.code.resize(MAX_INSTRUCTION_PER_BLOCK); u32 i; bool fetchDelaySlot = false; - for (i = 0; i < MAX_INSTRUCTION_PER_LINE; i++) { + for (i = 0; i < MAX_INSTRUCTION_PER_BLOCK; i++) { Instruction instr; if (!Fetch(instr, addr)) return i + 1; addr += 4; - code[i] = instr; + block.code[i] = instr; if (fetchDelaySlot) { i++; @@ -178,7 +150,8 @@ u32 Interpreter::ExecuteCached() { } } - cachedState.InsertLine(blockAddr, {code, i, i}); + blocks[page].cycles = i; + blocks[page].len = i; return ExecuteCached(); } diff --git a/src/backend/core/Interpreter.hpp b/src/backend/core/Interpreter.hpp index a029eb6..6000029 100644 --- a/src/backend/core/Interpreter.hpp +++ b/src/backend/core/Interpreter.hpp @@ -5,27 +5,25 @@ namespace n64 { struct Core; +static constexpr u32 MAX_BLOCKS = 1 << 20; static constexpr u32 MAX_INSTRUCTION_PER_BLOCK = 1 << 12; struct CachedBlock { - std::array code = {}; - u32 cycles = 0; + std::vector code = {}; u32 len = 0; -}; + u32 cycles = 0; +} __attribute__((__packed__)); struct CachedState { - CachedState() {} + CachedState() { blocks.resize(MAX_BLOCKS); } std::vector blocks = {}; bool exception = false; void Reset() { blocks = {}; + blocks.resize(MAX_BLOCKS); exception = false; } - - const CachedLine &GetLine(u64); - void InsertLine(u64, const CachedLine &); - void EvictLine(u64); }; struct Interpreter final { @@ -36,6 +34,8 @@ struct Interpreter final { bool FetchThenMaybeAdvance(Instruction &); bool MaybeAdvance(); + void EvictCachedBlock(u64 addr) { cachedState.blocks[(addr >> 12) & 0xfffff] = {}; } + void Reset() { cop2Latch = {}; cachedState.Reset(); diff --git a/src/backend/core/RDP.cpp b/src/backend/core/RDP.cpp index ea2df52..02a72a8 100644 --- a/src/backend/core/RDP.cpp +++ b/src/backend/core/RDP.cpp @@ -19,7 +19,6 @@ template <> void RDP::WriteRDRAM(const size_t idx, const u8 v) { if (const size_t real = BYTE_ADDRESS(idx); real < RDRAM_SIZE) [[likely]] { rdram[real] = v; - Core::GetInstance().interpreter.cachedState.EvictLine(idx); } } @@ -27,7 +26,6 @@ template <> void RDP::WriteRDRAM(const size_t idx, const u16 v) { if (const size_t real = HALF_ADDRESS(idx); real < RDRAM_SIZE) [[likely]] { ircolib::WriteAccess(rdram, real, v); - Core::GetInstance().interpreter.cachedState.EvictLine(idx); } } @@ -35,7 +33,6 @@ template <> void RDP::WriteRDRAM(const size_t idx, const u32 v) { if (idx < RDRAM_SIZE) [[likely]] { ircolib::WriteAccess(rdram, idx, v); - Core::GetInstance().interpreter.cachedState.EvictLine(idx); } } @@ -43,7 +40,6 @@ template <> void RDP::WriteRDRAM(const size_t idx, const u64 v) { if (idx < RDRAM_SIZE) [[likely]] { ircolib::WriteAccess(rdram, idx, v); - Core::GetInstance().interpreter.cachedState.EvictLine(idx); } } diff --git a/src/backend/core/interpreter/cop1instructions.cpp b/src/backend/core/interpreter/cop1instructions.cpp index 4281edc..e4dc15d 100644 --- a/src/backend/core/interpreter/cop1instructions.cpp +++ b/src/backend/core/interpreter/cop1instructions.cpp @@ -1310,8 +1310,8 @@ void Cop1::swc1(const Instruction instr) { regs.cop0.HandleTLBException(addr); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { + Core::GetInstance().interpreter.EvictCachedBlock(addr); mem.Write(physical, FGR_T(regs.cop0.status, instr.ft())); - Core::GetInstance().interpreter.cachedState.EvictLine(addr); } } @@ -1338,8 +1338,8 @@ void Cop1::sdc1(const Instruction instr) { regs.cop0.HandleTLBException(addr); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { + Core::GetInstance().interpreter.EvictCachedBlock(addr); mem.Write(physical, FGR_T(regs.cop0.status, instr.ft())); - Core::GetInstance().interpreter.cachedState.EvictLine(addr); } } diff --git a/src/backend/core/interpreter/instructions.cpp b/src/backend/core/interpreter/instructions.cpp index 55a6b34..ef0b599 100644 --- a/src/backend/core/interpreter/instructions.cpp +++ b/src/backend/core/interpreter/instructions.cpp @@ -407,7 +407,7 @@ void Interpreter::sb(const Instruction instr) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { - cachedState.EvictLine(address); + EvictCachedBlock(address); mem.Write(paddr, regs.Read(instr.rt())); } } @@ -431,7 +431,7 @@ void Interpreter::sc(const Instruction instr) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { - cachedState.EvictLine(address); + EvictCachedBlock(address); mem.Write(paddr, regs.Read(instr.rt())); regs.Write(instr.rt(), 1); } @@ -464,7 +464,7 @@ void Interpreter::scd(const Instruction instr) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { - cachedState.EvictLine(address); + EvictCachedBlock(address); mem.Write(paddr, regs.Read(instr.rt())); regs.Write(instr.rt(), 1); } @@ -481,7 +481,7 @@ void Interpreter::sh(const Instruction instr) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { - cachedState.EvictLine(address); + EvictCachedBlock(address); mem.Write(physical, regs.Read(instr.rt())); } } @@ -500,7 +500,7 @@ void Interpreter::sw(const Instruction instr) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { - cachedState.EvictLine(address); + EvictCachedBlock(address); mem.Write(physical, regs.Read(instr.rt())); } } @@ -518,7 +518,7 @@ void Interpreter::sd(const Instruction instr) { regs.cop0.HandleTLBException(address); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); } else { - cachedState.EvictLine(address); + EvictCachedBlock(address); mem.Write(physical, regs.Read(instr.rt())); } } @@ -534,8 +534,8 @@ void Interpreter::sdl(const Instruction instr) { const u64 mask = 0xFFFFFFFFFFFFFFFF >> shift; const u64 data = mem.Read(paddr & ~7); const u64 rt = regs.Read(instr.rt()); + EvictCachedBlock(address); mem.Write(paddr & ~7, (data & ~mask) | (rt >> shift)); - cachedState.EvictLine(address); } } @@ -550,8 +550,8 @@ void Interpreter::sdr(const Instruction instr) { const u64 mask = 0xFFFFFFFFFFFFFFFF << shift; const u64 data = mem.Read(paddr & ~7); const u64 rt = regs.Read(instr.rt()); + EvictCachedBlock(address); mem.Write(paddr & ~7, (data & ~mask) | (rt << shift)); - cachedState.EvictLine(address); } } @@ -566,8 +566,8 @@ void Interpreter::swl(const Instruction instr) { const u32 mask = 0xFFFFFFFF >> shift; const u32 data = mem.Read(paddr & ~3); const u32 rt = regs.Read(instr.rt()); + EvictCachedBlock(address); mem.Write(paddr & ~3, (data & ~mask) | (rt >> shift)); - cachedState.EvictLine(address); } } @@ -582,8 +582,8 @@ void Interpreter::swr(const Instruction instr) { const u32 mask = 0xFFFFFFFF << shift; const u32 data = mem.Read(paddr & ~3); const u32 rt = regs.Read(instr.rt()); + EvictCachedBlock(address); mem.Write(paddr & ~3, (data & ~mask) | (rt << shift)); - cachedState.EvictLine(address); } }