From eedd2806f9d6c7505130db9fe57d97ce7415e2ba Mon Sep 17 00:00:00 2001 From: Jaklyy <102590697+Jaklyy@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:37:42 -0400 Subject: [PATCH] Reapply "Improve accuracy of prefetch aborts" This reverts commit 0dc619d6155b0f6533ff35d13cf5f00add4b1939. --- src/ARM.cpp | 38 ++++++++++++++++++-------------------- src/CP15.cpp | 29 ++++++++++++++--------------- 2 files changed, 32 insertions(+), 35 deletions(-) diff --git a/src/ARM.cpp b/src/ARM.cpp index 6ac387b2..ae55514a 100644 --- a/src/ARM.cpp +++ b/src/ARM.cpp @@ -343,12 +343,6 @@ void ARMv5::JumpTo(u32 addr, bool restorecpsr) CPSR &= ~0x20; } - if (!(PU_Map[addr>>12] & 0x04)) - { - PrefetchAbort(); - return; - } - NDS.MonitorARM9Jump(addr); } @@ -575,15 +569,6 @@ void ARMv5::PrefetchAbort() CPSR |= 0x97; UpdateMode(oldcpsr, CPSR); - // this shouldn't happen, but if it does, we're stuck in some nasty endless loop - // so better take care of it - if (!(PU_Map[ExceptionBase>>12] & 0x04)) - { - Log(LogLevel::Error, "!!!!! EXCEPTION REGION NOT EXECUTABLE. THIS IS VERY BAD!!\n"); - NDS.Stop(Platform::StopReason::BadExceptionRegion); - return; - } - R_ABT[2] = oldcpsr; R[14] = R[15] + (oldcpsr & 0x20 ? 2 : 0); JumpTo(ExceptionBase + 0x0C); @@ -685,10 +670,18 @@ void ARMv5::Execute() NextInstr[0] = NextInstr[1]; if (R[15] & 0x2) { NextInstr[1] >>= 16; CodeCycles = 0; } else NextInstr[1] = CodeRead32(R[15], false); - + + // handle aborted instructions + if (!(PU_Map[(R[15]-4)>>12] & 0x04)) [[unlikely]] + { + PrefetchAbort(); + } // actually execute - u32 icode = (CurInstr >> 6) & 0x3FF; - ARMInterpreter::THUMBInstrTable[icode](this); + else [[likely]] + { + u32 icode = (CurInstr >> 6) & 0x3FF; + ARMInterpreter::THUMBInstrTable[icode](this); + } } else { @@ -700,9 +693,14 @@ void ARMv5::Execute() CurInstr = NextInstr[0]; NextInstr[0] = NextInstr[1]; NextInstr[1] = CodeRead32(R[15], false); - + + // handle aborted instructions + if (!(PU_Map[(R[15]-8)>>12] & 0x04)) [[unlikely]] // todo: check for bkpt instruction? + { + PrefetchAbort(); + } // actually execute - if (CheckCondition(CurInstr >> 28)) + else if (CheckCondition(CurInstr >> 28)) [[likely]] { u32 icode = ((CurInstr >> 4) & 0xF) | ((CurInstr >> 16) & 0xFF0); ARMInterpreter::ARMInstrTable[icode](this); diff --git a/src/CP15.cpp b/src/CP15.cpp index bf1d2edc..6fcaff93 100644 --- a/src/CP15.cpp +++ b/src/CP15.cpp @@ -773,14 +773,13 @@ u32 ARMv5::CP15Read(u32 id) const u32 ARMv5::CodeRead32(u32 addr, bool branch) { - /*if (branch || (!(addr & 0xFFF))) + // prefetch abort + // the actual exception is not raised until the aborted instruction is executed + if (!(PU_Map[addr>>12] & 0x04)) [[unlikely]] { - if (!(PU_Map[addr>>12] & 0x04)) - { - PrefetchAbort(); - return 0; - } - }*/ + CodeCycles = 1; + return 0; + } if (addr < ITCMSize) { @@ -807,7 +806,7 @@ u32 ARMv5::CodeRead32(u32 addr, bool branch) bool ARMv5::DataRead8(u32 addr, u32* val) { - if (!(PU_Map[addr>>12] & 0x01)) + if (!(PU_Map[addr>>12] & 0x01)) [[unlikely]] { DataAbort(); return false; @@ -833,7 +832,7 @@ bool ARMv5::DataRead8(u32 addr, u32* val) bool ARMv5::DataRead16(u32 addr, u32* val) { - if (!(PU_Map[addr>>12] & 0x01)) + if (!(PU_Map[addr>>12] & 0x01)) [[unlikely]] { DataAbort(); return false; @@ -861,7 +860,7 @@ bool ARMv5::DataRead16(u32 addr, u32* val) bool ARMv5::DataRead32(u32 addr, u32* val) { - if (!(PU_Map[addr>>12] & 0x01)) + if (!(PU_Map[addr>>12] & 0x01)) [[unlikely]] { DataAbort(); return false; @@ -889,7 +888,7 @@ bool ARMv5::DataRead32(u32 addr, u32* val) bool ARMv5::DataRead32S(u32 addr, u32* val) { - if (!(PU_Map[addr>>12] & 0x01)) + if (!(PU_Map[addr>>12] & 0x01)) [[unlikely]] { DataAbort(); return false; @@ -917,7 +916,7 @@ bool ARMv5::DataRead32S(u32 addr, u32* val) bool ARMv5::DataWrite8(u32 addr, u8 val) { - if (!(PU_Map[addr>>12] & 0x02)) + if (!(PU_Map[addr>>12] & 0x02)) [[unlikely]] { DataAbort(); return false; @@ -944,7 +943,7 @@ bool ARMv5::DataWrite8(u32 addr, u8 val) bool ARMv5::DataWrite16(u32 addr, u16 val) { - if (!(PU_Map[addr>>12] & 0x02)) + if (!(PU_Map[addr>>12] & 0x02)) [[unlikely]] { DataAbort(); return false; @@ -973,7 +972,7 @@ bool ARMv5::DataWrite16(u32 addr, u16 val) bool ARMv5::DataWrite32(u32 addr, u32 val) { - if (!(PU_Map[addr>>12] & 0x02)) + if (!(PU_Map[addr>>12] & 0x02)) [[unlikely]] { DataAbort(); return false; @@ -1002,7 +1001,7 @@ bool ARMv5::DataWrite32(u32 addr, u32 val) bool ARMv5::DataWrite32S(u32 addr, u32 val, bool dataabort) { - if (!(PU_Map[addr>>12] & 0x02)) + if (!(PU_Map[addr>>12] & 0x02)) [[unlikely]] { if (!dataabort) DataAbort(); return false;