From e2aa2243000b53af5ff050f98981d4d1c0900acb Mon Sep 17 00:00:00 2001 From: Gaberboo Date: Fri, 19 May 2023 10:27:44 -0700 Subject: [PATCH] Make BAT table updates lazy --- .../Interpreter/Interpreter_Branch.cpp | 13 +++++++ .../Interpreter_SystemRegisters.cpp | 37 ++++++++++++++++--- .../Core/Core/PowerPC/Jit64/Jit64_Tables.cpp | 8 ++-- .../Core/PowerPC/JitArm64/JitArm64_Tables.cpp | 30 +++++++-------- Source/Core/Core/PowerPC/PowerPC.h | 3 ++ 5 files changed, 67 insertions(+), 24 deletions(-) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp index e2cdff4fd6..48c921a547 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp @@ -9,6 +9,7 @@ #include "Core/Core.h" #include "Core/HLE/HLE.h" #include "Core/PowerPC/Interpreter/ExceptionUtils.h" +#include "Core/PowerPC/MMU.h" #include "Core/PowerPC/PowerPC.h" #include "Core/System.h" @@ -115,6 +116,18 @@ void Interpreter::rfi(Interpreter& interpreter, UGeckoInstruction inst) { auto& ppc_state = interpreter.m_ppc_state; + if (ppc_state.ibat_update_pending) + { + interpreter.m_mmu.IBATUpdated(); + ppc_state.ibat_update_pending = false; + } + + if (ppc_state.dbat_update_pending) + { + interpreter.m_mmu.DBATUpdated(); + ppc_state.dbat_update_pending = false; + } + if (ppc_state.msr.PR) { GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction); diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp index 80ddc8efc3..2736ad16d7 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp @@ -173,6 +173,19 @@ void Interpreter::mfsrin(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::mtmsr(Interpreter& interpreter, UGeckoInstruction inst) { auto& ppc_state = interpreter.m_ppc_state; + + if (ppc_state.ibat_update_pending) + { + interpreter.m_mmu.IBATUpdated(); + ppc_state.ibat_update_pending = false; + } + + if (ppc_state.dbat_update_pending) + { + interpreter.m_mmu.DBATUpdated(); + ppc_state.dbat_update_pending = false; + } + if (ppc_state.msr.PR) { GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction); @@ -379,8 +392,8 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst) if (old_value != ppc_state.spr[index]) { INFO_LOG_FMT(POWERPC, "HID4 updated {:x} {:x}", old_value, ppc_state.spr[index]); - interpreter.m_mmu.IBATUpdated(); - interpreter.m_mmu.DBATUpdated(); + ppc_state.ibat_update_pending = true; + ppc_state.dbat_update_pending = true; } break; @@ -462,7 +475,7 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst) if (old_value != ppc_state.spr[index]) { INFO_LOG_FMT(POWERPC, "DBAT updated {} {:x} {:x}", index, old_value, ppc_state.spr[index]); - interpreter.m_mmu.DBATUpdated(); + ppc_state.dbat_update_pending = true; } break; @@ -485,7 +498,7 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst) if (old_value != ppc_state.spr[index]) { INFO_LOG_FMT(POWERPC, "IBAT updated {} {:x} {:x}", index, old_value, ppc_state.spr[index]); - interpreter.m_mmu.IBATUpdated(); + ppc_state.ibat_update_pending = true; } break; @@ -603,7 +616,21 @@ void Interpreter::mcrf(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::isync(Interpreter& interpreter, UGeckoInstruction inst) { - // shouldn't do anything + // useful hook for lazy updating of BATs + + auto& ppc_state = interpreter.m_ppc_state; + + if (ppc_state.ibat_update_pending && ppc_state.msr.IR) + { + interpreter.m_mmu.IBATUpdated(); + ppc_state.ibat_update_pending = false; + } + + if (ppc_state.dbat_update_pending && ppc_state.msr.DR) + { + interpreter.m_mmu.DBATUpdated(); + ppc_state.dbat_update_pending = false; + } } // the following commands read from FPSCR diff --git a/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp b/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp index 61eb1c9450..917ad6615d 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit64_Tables.cpp @@ -144,10 +144,10 @@ constexpr std::array s_table19{{ {417, &Jit64::crXXX}, // crorc {193, &Jit64::crXXX}, // crxor - {150, &Jit64::DoNothing}, // isync - {0, &Jit64::mcrf}, // mcrf + {150, &Jit64::FallBackToInterpreter}, // isync + {0, &Jit64::mcrf}, // mcrf - {50, &Jit64::rfi}, // rfi + {50, &Jit64::FallBackToInterpreter}, // rfi }}; constexpr std::array s_table31{{ @@ -270,7 +270,7 @@ constexpr std::array s_table31{{ {19, &Jit64::mfcr}, // mfcr {83, &Jit64::mfmsr}, // mfmsr {144, &Jit64::mtcrf}, // mtcrf - {146, &Jit64::mtmsr}, // mtmsr + {146, &Jit64::FallBackToInterpreter}, // mtmsr {210, &Jit64::FallBackToInterpreter}, // mtsr {242, &Jit64::FallBackToInterpreter}, // mtsrin {339, &Jit64::mfspr}, // mfspr diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp index d75ba2a94a..2836b8ac3e 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp @@ -144,10 +144,10 @@ constexpr std::array s_table19{{ {417, &JitArm64::crXXX}, // crorc {193, &JitArm64::crXXX}, // crxor - {150, &JitArm64::DoNothing}, // isync - {0, &JitArm64::mcrf}, // mcrf + {150, &JitArm64::FallBackToInterpreter}, // isync + {0, &JitArm64::mcrf}, // mcrf - {50, &JitArm64::rfi}, // rfi + {50, &JitArm64::FallBackToInterpreter}, // rfi }}; constexpr std::array s_table31{{ @@ -267,18 +267,18 @@ constexpr std::array s_table31{{ {759, &JitArm64::stfXX}, // stfdux {983, &JitArm64::stfXX}, // stfiwx - {19, &JitArm64::mfcr}, // mfcr - {83, &JitArm64::mfmsr}, // mfmsr - {144, &JitArm64::mtcrf}, // mtcrf - {146, &JitArm64::mtmsr}, // mtmsr - {210, &JitArm64::mtsr}, // mtsr - {242, &JitArm64::mtsrin}, // mtsrin - {339, &JitArm64::mfspr}, // mfspr - {467, &JitArm64::mtspr}, // mtspr - {371, &JitArm64::mftb}, // mftb - {512, &JitArm64::mcrxr}, // mcrxr - {595, &JitArm64::mfsr}, // mfsr - {659, &JitArm64::mfsrin}, // mfsrin + {19, &JitArm64::mfcr}, // mfcr + {83, &JitArm64::mfmsr}, // mfmsr + {144, &JitArm64::mtcrf}, // mtcrf + {146, &JitArm64::FallBackToInterpreter}, // mtmsr + {210, &JitArm64::mtsr}, // mtsr + {242, &JitArm64::mtsrin}, // mtsrin + {339, &JitArm64::mfspr}, // mfspr + {467, &JitArm64::mtspr}, // mtspr + {371, &JitArm64::mftb}, // mftb + {512, &JitArm64::mcrxr}, // mcrxr + {595, &JitArm64::mfsr}, // mfsr + {659, &JitArm64::mfsrin}, // mfsrin {4, &JitArm64::twx}, // tw {598, &JitArm64::DoNothing}, // sync diff --git a/Source/Core/Core/PowerPC/PowerPC.h b/Source/Core/Core/PowerPC/PowerPC.h index 42545f2c1f..32da0619fb 100644 --- a/Source/Core/Core/PowerPC/PowerPC.h +++ b/Source/Core/Core/PowerPC/PowerPC.h @@ -162,6 +162,9 @@ struct PowerPCState u32 sr[16]{}; // Segment registers. + bool ibat_update_pending = false; + bool dbat_update_pending = false; + // special purpose registers - controls quantizers, DMA, and lots of other misc extensions. // also for power management, but we don't care about that. // JitArm64 needs 64-bit alignment for SPR_TL.