Make BAT table updates lazy
This commit is contained in:
parent
dadbeb4bae
commit
e2aa224300
|
@ -9,6 +9,7 @@
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/HLE/HLE.h"
|
#include "Core/HLE/HLE.h"
|
||||||
#include "Core/PowerPC/Interpreter/ExceptionUtils.h"
|
#include "Core/PowerPC/Interpreter/ExceptionUtils.h"
|
||||||
|
#include "Core/PowerPC/MMU.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
#include "Core/System.h"
|
#include "Core/System.h"
|
||||||
|
|
||||||
|
@ -115,6 +116,18 @@ void Interpreter::rfi(Interpreter& interpreter, UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
auto& ppc_state = interpreter.m_ppc_state;
|
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)
|
if (ppc_state.msr.PR)
|
||||||
{
|
{
|
||||||
GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
|
GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
|
||||||
|
|
|
@ -173,6 +173,19 @@ void Interpreter::mfsrin(Interpreter& interpreter, UGeckoInstruction inst)
|
||||||
void Interpreter::mtmsr(Interpreter& interpreter, UGeckoInstruction inst)
|
void Interpreter::mtmsr(Interpreter& interpreter, UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
auto& ppc_state = interpreter.m_ppc_state;
|
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)
|
if (ppc_state.msr.PR)
|
||||||
{
|
{
|
||||||
GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
|
GenerateProgramException(ppc_state, ProgramExceptionCause::PrivilegedInstruction);
|
||||||
|
@ -379,8 +392,8 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst)
|
||||||
if (old_value != ppc_state.spr[index])
|
if (old_value != ppc_state.spr[index])
|
||||||
{
|
{
|
||||||
INFO_LOG_FMT(POWERPC, "HID4 updated {:x} {:x}", old_value, ppc_state.spr[index]);
|
INFO_LOG_FMT(POWERPC, "HID4 updated {:x} {:x}", old_value, ppc_state.spr[index]);
|
||||||
interpreter.m_mmu.IBATUpdated();
|
ppc_state.ibat_update_pending = true;
|
||||||
interpreter.m_mmu.DBATUpdated();
|
ppc_state.dbat_update_pending = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -462,7 +475,7 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst)
|
||||||
if (old_value != ppc_state.spr[index])
|
if (old_value != ppc_state.spr[index])
|
||||||
{
|
{
|
||||||
INFO_LOG_FMT(POWERPC, "DBAT updated {} {:x} {:x}", index, 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;
|
break;
|
||||||
|
|
||||||
|
@ -485,7 +498,7 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst)
|
||||||
if (old_value != ppc_state.spr[index])
|
if (old_value != ppc_state.spr[index])
|
||||||
{
|
{
|
||||||
INFO_LOG_FMT(POWERPC, "IBAT updated {} {:x} {:x}", index, 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;
|
break;
|
||||||
|
|
||||||
|
@ -603,7 +616,21 @@ void Interpreter::mcrf(Interpreter& interpreter, UGeckoInstruction inst)
|
||||||
|
|
||||||
void Interpreter::isync(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
|
// the following commands read from FPSCR
|
||||||
|
|
|
@ -144,10 +144,10 @@ constexpr std::array<Jit64OpTemplate, 13> s_table19{{
|
||||||
{417, &Jit64::crXXX}, // crorc
|
{417, &Jit64::crXXX}, // crorc
|
||||||
{193, &Jit64::crXXX}, // crxor
|
{193, &Jit64::crXXX}, // crxor
|
||||||
|
|
||||||
{150, &Jit64::DoNothing}, // isync
|
{150, &Jit64::FallBackToInterpreter}, // isync
|
||||||
{0, &Jit64::mcrf}, // mcrf
|
{0, &Jit64::mcrf}, // mcrf
|
||||||
|
|
||||||
{50, &Jit64::rfi}, // rfi
|
{50, &Jit64::FallBackToInterpreter}, // rfi
|
||||||
}};
|
}};
|
||||||
|
|
||||||
constexpr std::array<Jit64OpTemplate, 107> s_table31{{
|
constexpr std::array<Jit64OpTemplate, 107> s_table31{{
|
||||||
|
@ -270,7 +270,7 @@ constexpr std::array<Jit64OpTemplate, 107> s_table31{{
|
||||||
{19, &Jit64::mfcr}, // mfcr
|
{19, &Jit64::mfcr}, // mfcr
|
||||||
{83, &Jit64::mfmsr}, // mfmsr
|
{83, &Jit64::mfmsr}, // mfmsr
|
||||||
{144, &Jit64::mtcrf}, // mtcrf
|
{144, &Jit64::mtcrf}, // mtcrf
|
||||||
{146, &Jit64::mtmsr}, // mtmsr
|
{146, &Jit64::FallBackToInterpreter}, // mtmsr
|
||||||
{210, &Jit64::FallBackToInterpreter}, // mtsr
|
{210, &Jit64::FallBackToInterpreter}, // mtsr
|
||||||
{242, &Jit64::FallBackToInterpreter}, // mtsrin
|
{242, &Jit64::FallBackToInterpreter}, // mtsrin
|
||||||
{339, &Jit64::mfspr}, // mfspr
|
{339, &Jit64::mfspr}, // mfspr
|
||||||
|
|
|
@ -144,10 +144,10 @@ constexpr std::array<JitArm64OpTemplate, 13> s_table19{{
|
||||||
{417, &JitArm64::crXXX}, // crorc
|
{417, &JitArm64::crXXX}, // crorc
|
||||||
{193, &JitArm64::crXXX}, // crxor
|
{193, &JitArm64::crXXX}, // crxor
|
||||||
|
|
||||||
{150, &JitArm64::DoNothing}, // isync
|
{150, &JitArm64::FallBackToInterpreter}, // isync
|
||||||
{0, &JitArm64::mcrf}, // mcrf
|
{0, &JitArm64::mcrf}, // mcrf
|
||||||
|
|
||||||
{50, &JitArm64::rfi}, // rfi
|
{50, &JitArm64::FallBackToInterpreter}, // rfi
|
||||||
}};
|
}};
|
||||||
|
|
||||||
constexpr std::array<JitArm64OpTemplate, 107> s_table31{{
|
constexpr std::array<JitArm64OpTemplate, 107> s_table31{{
|
||||||
|
@ -267,18 +267,18 @@ constexpr std::array<JitArm64OpTemplate, 107> s_table31{{
|
||||||
{759, &JitArm64::stfXX}, // stfdux
|
{759, &JitArm64::stfXX}, // stfdux
|
||||||
{983, &JitArm64::stfXX}, // stfiwx
|
{983, &JitArm64::stfXX}, // stfiwx
|
||||||
|
|
||||||
{19, &JitArm64::mfcr}, // mfcr
|
{19, &JitArm64::mfcr}, // mfcr
|
||||||
{83, &JitArm64::mfmsr}, // mfmsr
|
{83, &JitArm64::mfmsr}, // mfmsr
|
||||||
{144, &JitArm64::mtcrf}, // mtcrf
|
{144, &JitArm64::mtcrf}, // mtcrf
|
||||||
{146, &JitArm64::mtmsr}, // mtmsr
|
{146, &JitArm64::FallBackToInterpreter}, // mtmsr
|
||||||
{210, &JitArm64::mtsr}, // mtsr
|
{210, &JitArm64::mtsr}, // mtsr
|
||||||
{242, &JitArm64::mtsrin}, // mtsrin
|
{242, &JitArm64::mtsrin}, // mtsrin
|
||||||
{339, &JitArm64::mfspr}, // mfspr
|
{339, &JitArm64::mfspr}, // mfspr
|
||||||
{467, &JitArm64::mtspr}, // mtspr
|
{467, &JitArm64::mtspr}, // mtspr
|
||||||
{371, &JitArm64::mftb}, // mftb
|
{371, &JitArm64::mftb}, // mftb
|
||||||
{512, &JitArm64::mcrxr}, // mcrxr
|
{512, &JitArm64::mcrxr}, // mcrxr
|
||||||
{595, &JitArm64::mfsr}, // mfsr
|
{595, &JitArm64::mfsr}, // mfsr
|
||||||
{659, &JitArm64::mfsrin}, // mfsrin
|
{659, &JitArm64::mfsrin}, // mfsrin
|
||||||
|
|
||||||
{4, &JitArm64::twx}, // tw
|
{4, &JitArm64::twx}, // tw
|
||||||
{598, &JitArm64::DoNothing}, // sync
|
{598, &JitArm64::DoNothing}, // sync
|
||||||
|
|
|
@ -162,6 +162,9 @@ struct PowerPCState
|
||||||
|
|
||||||
u32 sr[16]{}; // Segment registers.
|
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.
|
// special purpose registers - controls quantizers, DMA, and lots of other misc extensions.
|
||||||
// also for power management, but we don't care about that.
|
// also for power management, but we don't care about that.
|
||||||
// JitArm64 needs 64-bit alignment for SPR_TL.
|
// JitArm64 needs 64-bit alignment for SPR_TL.
|
||||||
|
|
Loading…
Reference in New Issue