diff --git a/src/core/cpu_core.cpp b/src/core/cpu_core.cpp index caf813c67..7b1dd098a 100644 --- a/src/core/cpu_core.cpp +++ b/src/core/cpu_core.cpp @@ -2557,13 +2557,13 @@ template } // fetch the next instruction - even if this fails, it'll still refetch on the flush so we can continue - if (!FetchInstruction()) + if (!FetchInstruction()) [[unlikely]] continue; // trace functionality if constexpr (debug) { - if (s_locals.trace_to_log) + if (s_locals.trace_to_log) [[unlikely]] LogInstruction(g_state.current_instruction.bits, g_state.current_instruction_pc, true); // handle all mirrors of the syscall trampoline. will catch 200000A0 etc, but those aren't fetchable anyway @@ -2973,6 +2973,9 @@ ALWAYS_INLINE_RELEASE bool CPU::FetchInstruction() DebugAssert(Common::IsAlignedPow2(g_state.npc, 4)); const PhysicalMemoryAddress address = g_state.npc; + g_state.pc = g_state.npc; + g_state.npc += sizeof(g_state.next_instruction.bits); + switch (address >> 29) { case 0x00: // KUSEG 0M-512M @@ -2991,25 +2994,24 @@ ALWAYS_INLINE_RELEASE bool CPU::FetchInstruction() case 0x05: // KSEG1 - physical memory uncached { - if (!DoInstructionRead(address, &g_state.next_instruction.bits)) + if (!DoInstructionRead(address, &g_state.next_instruction.bits)) [[unlikely]] return false; } break; - case 0x01: // KUSEG 512M-1024M - case 0x02: // KUSEG 1024M-1536M - case 0x03: // KUSEG 1536M-2048M - case 0x06: // KSEG2 - case 0x07: // KSEG2 - default: + [[unlikely]] case 0x01: // KUSEG 512M-1024M + [[unlikely]] case 0x02: // KUSEG 1024M-1536M + [[unlikely]] case 0x03: // KUSEG 1536M-2048M + [[unlikely]] case 0x06: // KSEG2 + [[unlikely]] case 0x07: // KSEG2 { CPU::RaiseException(Cop0Registers::CAUSE::MakeValueForException(Exception::IBE, false, false, 0), address); return false; } + + DefaultCaseIsUnreachable(); } - g_state.pc = g_state.npc; - g_state.npc += sizeof(g_state.next_instruction.bits); return true; } @@ -3024,11 +3026,14 @@ bool CPU::FetchInstructionForInterpreterFallback() } const PhysicalMemoryAddress address = g_state.npc; + g_state.pc = g_state.npc; + g_state.npc += sizeof(g_state.next_instruction.bits); + switch (address >> 29) { - case 0x00: // KUSEG 0M-512M - case 0x04: // KSEG0 - physical memory cached - case 0x05: // KSEG1 - physical memory uncached + [[unlikely]] case 0x00: // KUSEG 0M-512M + [[unlikely]] case 0x04: // KSEG0 - physical memory cached + [[unlikely]] 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)) [[unlikely]] @@ -3036,12 +3041,11 @@ bool CPU::FetchInstructionForInterpreterFallback() } break; - case 0x01: // KUSEG 512M-1024M - case 0x02: // KUSEG 1024M-1536M - case 0x03: // KUSEG 1536M-2048M - case 0x06: // KSEG2 - case 0x07: // KSEG2 - default: + [[unlikely]] case 0x01: // KUSEG 512M-1024M + [[unlikely]] case 0x02: // KUSEG 1024M-1536M + [[unlikely]] case 0x03: // KUSEG 1536M-2048M + [[unlikely]] case 0x06: // KSEG2 + [[unlikely]] case 0x07: // KSEG2 { CPU::RaiseException(Cop0Registers::CAUSE::MakeValueForException(Exception::IBE, g_state.current_instruction_in_branch_delay_slot, @@ -3049,10 +3053,10 @@ bool CPU::FetchInstructionForInterpreterFallback() address); return false; } + + DefaultCaseIsUnreachable(); } - g_state.pc = g_state.npc; - g_state.npc += sizeof(g_state.next_instruction.bits); return true; } @@ -3068,15 +3072,14 @@ bool CPU::SafeReadInstruction(VirtualMemoryAddress addr, u32* value) return DoInstructionRead(addr, value); } - case 0x01: // KUSEG 512M-1024M - case 0x02: // KUSEG 1024M-1536M - case 0x03: // KUSEG 1536M-2048M - case 0x06: // KSEG2 - case 0x07: // KSEG2 - default: - { + [[unlikely]] case 0x01: // KUSEG 512M-1024M + [[unlikely]] case 0x02: // KUSEG 1024M-1536M + [[unlikely]] case 0x03: // KUSEG 1536M-2048M + [[unlikely]] case 0x06: // KSEG2 + [[unlikely]] case 0x07: // KSEG2 return false; - } + + DefaultCaseIsUnreachable(); } } @@ -3134,11 +3137,11 @@ ALWAYS_INLINE bool CPU::DoSafeMemoryAccess(VirtualMemoryAddress address, u32& va } break; - case 0x01: // KUSEG 512M-1024M - case 0x02: // KUSEG 1024M-1536M - case 0x03: // KUSEG 1536M-2048M - case 0x06: // KSEG2 - case 0x07: // KSEG2 + [[unlikely]] case 0x01: // KUSEG 512M-1024M + [[unlikely]] case 0x02: // KUSEG 1024M-1536M + [[unlikely]] case 0x03: // KUSEG 1536M-2048M + [[unlikely]] case 0x06: // KSEG2 + [[unlikely]] case 0x07: // KSEG2 { // Above 512mb raises an exception. return false; @@ -3480,12 +3483,12 @@ ALWAYS_INLINE_RELEASE bool CPU::DoAlignmentCheck(VirtualMemoryAddress address) { if constexpr (size == MemoryAccessSize::HalfWord) { - if (Common::IsAlignedPow2(address, 2)) + if (Common::IsAlignedPow2(address, 2)) [[likely]] return true; } else if constexpr (size == MemoryAccessSize::Word) { - if (Common::IsAlignedPow2(address, 4)) + if (Common::IsAlignedPow2(address, 4)) [[likely]] return true; } else @@ -3567,7 +3570,7 @@ bool CPU::ReadMemoryByte(VirtualMemoryAddress addr, u8* value) bool CPU::ReadMemoryHalfWord(VirtualMemoryAddress addr, u16* value) { - if (!DoAlignmentCheck(addr)) + if (!DoAlignmentCheck(addr)) [[unlikely]] return false; *value = Truncate16(GetMemoryReadHandler(addr, MemoryAccessSize::HalfWord)(addr)); @@ -3584,7 +3587,7 @@ bool CPU::ReadMemoryHalfWord(VirtualMemoryAddress addr, u16* value) bool CPU::ReadMemoryWord(VirtualMemoryAddress addr, u32* value) { - if (!DoAlignmentCheck(addr)) + if (!DoAlignmentCheck(addr)) [[unlikely]] return false; *value = GetMemoryReadHandler(addr, MemoryAccessSize::Word)(addr); @@ -3618,7 +3621,7 @@ bool CPU::WriteMemoryHalfWord(VirtualMemoryAddress addr, u32 value) { MEMORY_BREAKPOINT(MemoryAccessType::Write, MemoryAccessSize::HalfWord, addr, value); - if (!DoAlignmentCheck(addr)) + if (!DoAlignmentCheck(addr)) [[unlikely]] return false; GetMemoryWriteHandler(addr, MemoryAccessSize::HalfWord)(addr, value); @@ -3636,7 +3639,7 @@ bool CPU::WriteMemoryWord(VirtualMemoryAddress addr, u32 value) { MEMORY_BREAKPOINT(MemoryAccessType::Write, MemoryAccessSize::Word, addr, value); - if (!DoAlignmentCheck(addr)) + if (!DoAlignmentCheck(addr)) [[unlikely]] return false; GetMemoryWriteHandler(addr, MemoryAccessSize::Word)(addr, value);