Make BAT table updates lazy

This commit is contained in:
Gaberboo 2023-05-19 10:27:44 -07:00
parent dadbeb4bae
commit e2aa224300
5 changed files with 67 additions and 24 deletions

View File

@ -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);

View File

@ -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

View File

@ -144,10 +144,10 @@ constexpr std::array<Jit64OpTemplate, 13> s_table19{{
{417, &Jit64::crXXX}, // crorc
{193, &Jit64::crXXX}, // crxor
{150, &Jit64::DoNothing}, // isync
{150, &Jit64::FallBackToInterpreter}, // isync
{0, &Jit64::mcrf}, // mcrf
{50, &Jit64::rfi}, // rfi
{50, &Jit64::FallBackToInterpreter}, // rfi
}};
constexpr std::array<Jit64OpTemplate, 107> s_table31{{
@ -270,7 +270,7 @@ constexpr std::array<Jit64OpTemplate, 107> 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

View File

@ -144,10 +144,10 @@ constexpr std::array<JitArm64OpTemplate, 13> s_table19{{
{417, &JitArm64::crXXX}, // crorc
{193, &JitArm64::crXXX}, // crxor
{150, &JitArm64::DoNothing}, // isync
{150, &JitArm64::FallBackToInterpreter}, // isync
{0, &JitArm64::mcrf}, // mcrf
{50, &JitArm64::rfi}, // rfi
{50, &JitArm64::FallBackToInterpreter}, // rfi
}};
constexpr std::array<JitArm64OpTemplate, 107> s_table31{{
@ -270,7 +270,7 @@ constexpr std::array<JitArm64OpTemplate, 107> s_table31{{
{19, &JitArm64::mfcr}, // mfcr
{83, &JitArm64::mfmsr}, // mfmsr
{144, &JitArm64::mtcrf}, // mtcrf
{146, &JitArm64::mtmsr}, // mtmsr
{146, &JitArm64::FallBackToInterpreter}, // mtmsr
{210, &JitArm64::mtsr}, // mtsr
{242, &JitArm64::mtsrin}, // mtsrin
{339, &JitArm64::mfspr}, // mfspr

View File

@ -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.