diff --git a/src/core/cpu_core.cpp b/src/core/cpu_core.cpp index a6e9e000f..8c726dd60 100644 --- a/src/core/cpu_core.cpp +++ b/src/core/cpu_core.cpp @@ -2706,10 +2706,13 @@ ALWAYS_INLINE_RELEASE bool CPU::DoInstructionRead(PhysicalMemoryAddress address, return true; } - else + else [[unlikely]] { if (raise_exceptions) - CPU::RaiseException(address, Cop0Registers::CAUSE::MakeValueForException(Exception::IBE, false, false, 0)); + { + g_state.cop0_regs.BadVaddr = address; + RaiseException(Cop0Registers::CAUSE::MakeValueForException(Exception::IBE, false, false, 0), address); + } std::memset(data, 0, sizeof(u32) * word_count); return false; @@ -2871,7 +2874,13 @@ ALWAYS_INLINE_RELEASE bool CPU::FetchInstruction() bool CPU::FetchInstructionForInterpreterFallback() { - DebugAssert(Common::IsAlignedPow2(g_state.npc, 4)); + if (!Common::IsAlignedPow2(g_state.npc, 4)) [[unlikely]] + { + // The BadVaddr and EPC must be set to the fetching address, not the instruction about to execute. + g_state.cop0_regs.BadVaddr = g_state.npc; + RaiseException(Cop0Registers::CAUSE::MakeValueForException(Exception::AdEL, false, false, 0), g_state.npc); + return false; + } const PhysicalMemoryAddress address = g_state.npc; switch (address >> 29) @@ -2881,7 +2890,7 @@ bool CPU::FetchInstructionForInterpreterFallback() case 0x05: // KSEG1 - physical memory uncached { // We don't use the icache when doing interpreter fallbacks, because it's probably stale. - if (!DoInstructionRead(address, &g_state.next_instruction.bits)) + if (!DoInstructionRead(address, &g_state.next_instruction.bits)) [[unlikely]] return false; } break;