12 changes: 6 additions & 6 deletions Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStoreFloating.cpp
Expand Up @@ -79,7 +79,7 @@ void JitArm64::lfXX(UGeckoInstruction inst)

gpr.Lock(ARM64Reg::W0, ARM64Reg::W30);
fpr.Lock(ARM64Reg::Q0);
if (!jo.fastmem_arena)
if (!jo.fastmem)
gpr.Lock(ARM64Reg::W2);

const ARM64Reg VD = fpr.RW(inst.FD, type, false);
Expand Down Expand Up @@ -168,7 +168,7 @@ void JitArm64::lfXX(UGeckoInstruction inst)
BitSet32 fprs_in_use = fpr.GetCallerSavedUsed();
if (!update || early_update)
regs_in_use[DecodeReg(ARM64Reg::W0)] = 0;
if (!jo.fastmem_arena)
if (!jo.fastmem)
regs_in_use[DecodeReg(ARM64Reg::W2)] = 0;
fprs_in_use[DecodeReg(ARM64Reg::Q0)] = 0;
if (!jo.memcheck)
Expand All @@ -194,7 +194,7 @@ void JitArm64::lfXX(UGeckoInstruction inst)

gpr.Unlock(ARM64Reg::W0, ARM64Reg::W30);
fpr.Unlock(ARM64Reg::Q0);
if (!jo.fastmem_arena)
if (!jo.fastmem)
gpr.Unlock(ARM64Reg::W2);
}

Expand Down Expand Up @@ -279,7 +279,7 @@ void JitArm64::stfXX(UGeckoInstruction inst)
}

gpr.Lock(ARM64Reg::W0, ARM64Reg::W1, ARM64Reg::W30);
if (!jo.fastmem_arena)
if (!jo.fastmem)
gpr.Lock(ARM64Reg::W2);

ARM64Reg addr_reg = ARM64Reg::W1;
Expand Down Expand Up @@ -372,7 +372,7 @@ void JitArm64::stfXX(UGeckoInstruction inst)
regs_in_use[DecodeReg(ARM64Reg::W0)] = 0;
if (!update || early_update)
regs_in_use[DecodeReg(ARM64Reg::W1)] = 0;
if (!jo.fastmem_arena)
if (!jo.fastmem)
regs_in_use[DecodeReg(ARM64Reg::W2)] = 0;
fprs_in_use[DecodeReg(ARM64Reg::Q0)] = 0;

Expand Down Expand Up @@ -428,6 +428,6 @@ void JitArm64::stfXX(UGeckoInstruction inst)

gpr.Unlock(ARM64Reg::W0, ARM64Reg::W1, ARM64Reg::W30);
fpr.Unlock(ARM64Reg::Q0);
if (!jo.fastmem_arena)
if (!jo.fastmem)
gpr.Unlock(ARM64Reg::W2);
}
24 changes: 12 additions & 12 deletions Source/Core/Core/PowerPC/JitArm64/JitArm64_LoadStorePaired.cpp
Expand Up @@ -22,8 +22,8 @@ void JitArm64::psq_lXX(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITLoadStorePairedOff);

// If we have a fastmem arena, the asm routines assume address translation is on.
FALLBACK_IF(!js.assumeNoPairedQuantize && jo.fastmem_arena && !m_ppc_state.msr.DR);
// If fastmem is enabled, the asm routines assume address translation is on.
FALLBACK_IF(!js.assumeNoPairedQuantize && jo.fastmem && !m_ppc_state.msr.DR);

// X30 is LR
// X0 is the address
Expand All @@ -44,7 +44,7 @@ void JitArm64::psq_lXX(UGeckoInstruction inst)
gpr.Lock(ARM64Reg::W1, ARM64Reg::W2, ARM64Reg::W3);
fpr.Lock(ARM64Reg::Q1);
}
else if (!jo.fastmem_arena)
else if (!jo.fastmem)
{
gpr.Lock(ARM64Reg::W2);
}
Expand Down Expand Up @@ -86,7 +86,7 @@ void JitArm64::psq_lXX(UGeckoInstruction inst)
// Wipe the registers we are using as temporaries
if (!update || early_update)
gprs_in_use[DecodeReg(ARM64Reg::W0)] = false;
if (!jo.fastmem_arena)
if (!jo.fastmem)
gprs_in_use[DecodeReg(ARM64Reg::W2)] = false;
fprs_in_use[DecodeReg(ARM64Reg::Q0)] = false;
if (!jo.memcheck)
Expand Down Expand Up @@ -136,7 +136,7 @@ void JitArm64::psq_lXX(UGeckoInstruction inst)
gpr.Unlock(ARM64Reg::W1, ARM64Reg::W2, ARM64Reg::W3);
fpr.Unlock(ARM64Reg::Q1);
}
else if (!jo.fastmem_arena)
else if (!jo.fastmem)
{
gpr.Unlock(ARM64Reg::W2);
}
Expand All @@ -147,8 +147,8 @@ void JitArm64::psq_stXX(UGeckoInstruction inst)
INSTRUCTION_START
JITDISABLE(bJITLoadStorePairedOff);

// If we have a fastmem arena, the asm routines assume address translation is on.
FALLBACK_IF(!js.assumeNoPairedQuantize && jo.fastmem_arena && !m_ppc_state.msr.DR);
// If fastmem is enabled, the asm routines assume address translation is on.
FALLBACK_IF(!js.assumeNoPairedQuantize && jo.fastmem && !m_ppc_state.msr.DR);

// X30 is LR
// X0 contains the scale
Expand Down Expand Up @@ -199,9 +199,9 @@ void JitArm64::psq_stXX(UGeckoInstruction inst)
}

gpr.Lock(ARM64Reg::W0, ARM64Reg::W1, ARM64Reg::W30);
if (!js.assumeNoPairedQuantize || !jo.fastmem_arena)
if (!js.assumeNoPairedQuantize || !jo.fastmem)
gpr.Lock(ARM64Reg::W2);
if (!js.assumeNoPairedQuantize && !jo.fastmem_arena)
if (!js.assumeNoPairedQuantize && !jo.fastmem)
gpr.Lock(ARM64Reg::W3);

constexpr ARM64Reg scale_reg = ARM64Reg::W0;
Expand Down Expand Up @@ -241,7 +241,7 @@ void JitArm64::psq_stXX(UGeckoInstruction inst)
gprs_in_use[DecodeReg(ARM64Reg::W0)] = false;
if (!update || early_update)
gprs_in_use[DecodeReg(ARM64Reg::W1)] = false;
if (!jo.fastmem_arena)
if (!jo.fastmem)
gprs_in_use[DecodeReg(ARM64Reg::W2)] = false;

u32 flags = BackPatchInfo::FLAG_STORE | BackPatchInfo::FLAG_FLOAT | BackPatchInfo::FLAG_SIZE_32;
Expand Down Expand Up @@ -275,9 +275,9 @@ void JitArm64::psq_stXX(UGeckoInstruction inst)

gpr.Unlock(ARM64Reg::W0, ARM64Reg::W1, ARM64Reg::W30);
fpr.Unlock(ARM64Reg::Q0);
if (!js.assumeNoPairedQuantize || !jo.fastmem_arena)
if (!js.assumeNoPairedQuantize || !jo.fastmem)
gpr.Unlock(ARM64Reg::W2);
if (!js.assumeNoPairedQuantize && !jo.fastmem_arena)
if (!js.assumeNoPairedQuantize && !jo.fastmem)
gpr.Unlock(ARM64Reg::W3);
if (!js.assumeNoPairedQuantize)
fpr.Unlock(ARM64Reg::Q1);
Expand Down
4 changes: 2 additions & 2 deletions Source/Core/Core/PowerPC/JitArm64/JitAsm.cpp
Expand Up @@ -724,7 +724,7 @@ void JitArm64::GenerateQuantizedStores()
// X0 is the scale
// X1 is the address
// X2 is a temporary
// X3 is a temporary if jo.fastmem_arena is false (used in EmitBackpatchRoutine)
// X3 is a temporary if jo.fastmem is false (used in EmitBackpatchRoutine)
// X30 is LR
// Q0 is the register
// Q1 is a temporary
Expand All @@ -733,7 +733,7 @@ void JitArm64::GenerateQuantizedStores()
BitSet32 gprs_to_push = CALLER_SAVED_GPRS & ~BitSet32{0, 2};
if (!jo.memcheck)
gprs_to_push &= ~BitSet32{1};
if (!jo.fastmem_arena)
if (!jo.fastmem)
gprs_to_push &= ~BitSet32{3};
BitSet32 fprs_to_push = BitSet32(0xFFFFFFFF) & ~BitSet32{0, 1};
ARM64FloatEmitter float_emit(this);
Expand Down
14 changes: 7 additions & 7 deletions Source/Core/Core/PowerPC/JitCommon/JitBase.cpp
Expand Up @@ -115,7 +115,7 @@ bool JitBase::DoesConfigNeedRefresh()
});
}

void JitBase::RefreshConfig(InitFastmemArena init_fastmem_arena)
void JitBase::RefreshConfig()
{
for (const auto& [member, config_info] : JIT_SETTINGS)
this->*member = Config::Get(*config_info);
Expand All @@ -132,12 +132,6 @@ void JitBase::RefreshConfig(InitFastmemArena init_fastmem_arena)
analyzer.SetFloatExceptionsEnabled(m_enable_float_exceptions);
analyzer.SetDivByZeroExceptionsEnabled(m_enable_div_by_zero_exceptions);

if (init_fastmem_arena != InitFastmemArena::No)
{
auto& memory = m_system.GetMemory();
jo.fastmem_arena = m_fastmem_enabled && memory.InitFastmemArena();
}

bool any_watchpoints = m_system.GetPowerPC().GetMemChecks().HasAny();
jo.fastmem = m_fastmem_enabled && jo.fastmem_arena && (m_ppc_state.msr.DR || !any_watchpoints) &&
EMM::IsExceptionHandlerSupported();
Expand All @@ -146,6 +140,12 @@ void JitBase::RefreshConfig(InitFastmemArena init_fastmem_arena)
jo.div_by_zero_exceptions = m_enable_div_by_zero_exceptions;
}

void JitBase::InitFastmemArena()
{
auto& memory = m_system.GetMemory();
jo.fastmem_arena = Config::Get(Config::MAIN_FASTMEM_ARENA) && memory.InitFastmemArena();
}

void JitBase::InitBLROptimization()
{
m_enable_blr_optimization =
Expand Down
10 changes: 3 additions & 7 deletions Source/Core/Core/PowerPC/JitCommon/JitBase.h
Expand Up @@ -163,14 +163,10 @@ class JitBase : public CPUCoreBase

static const std::array<std::pair<bool JitBase::*, const Config::Info<bool>*>, 22> JIT_SETTINGS;

enum class InitFastmemArena
{
No,
Yes,
};

bool DoesConfigNeedRefresh();
void RefreshConfig(InitFastmemArena init_fastmem_arena);
void RefreshConfig();

void InitFastmemArena();

void InitBLROptimization();
void ProtectStack();
Expand Down
10 changes: 8 additions & 2 deletions Source/Core/Core/PowerPC/JitInterface.cpp
Expand Up @@ -105,15 +105,21 @@ void JitInterface::UpdateMembase()

auto& ppc_state = m_system.GetPPCState();
auto& memory = m_system.GetMemory();
#ifdef _M_ARM_64
// JitArm64 is currently using the no fastmem arena code path even when only fastmem is off.
const bool fastmem_arena = m_jit->jo.fastmem;
#else
const bool fastmem_arena = m_jit->jo.fastmem_arena;
#endif
if (ppc_state.msr.DR)
{
ppc_state.mem_ptr =
m_jit->jo.fastmem_arena ? memory.GetLogicalBase() : memory.GetLogicalPageMappingsBase();
fastmem_arena ? memory.GetLogicalBase() : memory.GetLogicalPageMappingsBase();
}
else
{
ppc_state.mem_ptr =
m_jit->jo.fastmem_arena ? memory.GetPhysicalBase() : memory.GetPhysicalPageMappingsBase();
fastmem_arena ? memory.GetPhysicalBase() : memory.GetPhysicalPageMappingsBase();
}
}

Expand Down
6 changes: 6 additions & 0 deletions Source/Core/Core/PowerPC/MMU.cpp
Expand Up @@ -914,6 +914,9 @@ bool MMU::IsOptimizableRAMAddress(const u32 address) const
if (!m_ppc_state.msr.DR)
return false;

if (m_ppc_state.m_enable_dcache)
return false;

// TODO: This API needs to take an access size
//
// We store whether an access can be optimized to an unchecked access
Expand Down Expand Up @@ -1211,6 +1214,9 @@ u32 MMU::IsOptimizableMMIOAccess(u32 address, u32 access_size) const
if (!m_ppc_state.msr.DR)
return 0;

if (m_ppc_state.m_enable_dcache)
return 0;

// Translate address
// If we also optimize for TLB mappings, we'd have to clear the
// JitCache on each TLB invalidation.
Expand Down
21 changes: 19 additions & 2 deletions Source/Core/Core/PowerPC/PowerPC.cpp
Expand Up @@ -18,6 +18,7 @@
#include "Common/FloatUtils.h"
#include "Common/Logging/Log.h"

#include "Core/CPUThreadConfigCallback.h"
#include "Core/Config/MainSettings.h"
#include "Core/ConfigManager.h"
#include "Core/Core.h"
Expand Down Expand Up @@ -262,8 +263,25 @@ CPUCore DefaultCPUCore()
#endif
}

void PowerPCManager::RefreshConfig()
{
const bool old_enable_dcache = m_ppc_state.m_enable_dcache;

m_ppc_state.m_enable_dcache = Config::Get(Config::MAIN_ACCURATE_CPU_CACHE);

if (old_enable_dcache && !m_ppc_state.m_enable_dcache)
{
INFO_LOG_FMT(POWERPC, "Flushing data cache");
m_ppc_state.dCache.FlushAll();
}
}

void PowerPCManager::Init(CPUCore cpu_core)
{
m_registered_config_callback_id =
CPUThreadConfigCallback::AddConfigChangedCallback([this] { RefreshConfig(); });
RefreshConfig();

m_invalidate_cache_thread_safe =
m_system.GetCoreTiming().RegisterEvent("invalidateEmulatedCache", InvalidateCacheThreadSafe);

Expand All @@ -273,8 +291,6 @@ void PowerPCManager::Init(CPUCore cpu_core)
m_ppc_state.iCache.Init();
m_ppc_state.dCache.Init();

m_ppc_state.m_enable_dcache = Config::Get(Config::MAIN_ACCURATE_CPU_CACHE);

if (Config::Get(Config::MAIN_ENABLE_DEBUGGING))
m_breakpoints.ClearAllTemporary();
}
Expand Down Expand Up @@ -307,6 +323,7 @@ void PowerPCManager::ScheduleInvalidateCacheThreadSafe(u32 address)

void PowerPCManager::Shutdown()
{
CPUThreadConfigCallback::RemoveConfigChangedCallback(m_registered_config_callback_id);
InjectExternalCPUCore(nullptr);
m_system.GetJitInterface().Shutdown();
m_system.GetInterpreter().Shutdown();
Expand Down
4 changes: 4 additions & 0 deletions Source/Core/Core/PowerPC/PowerPC.h
Expand Up @@ -13,6 +13,7 @@

#include "Common/CommonTypes.h"

#include "Core/CPUThreadConfigCallback.h"
#include "Core/Debugger/PPCDebugInterface.h"
#include "Core/PowerPC/BreakPoints.h"
#include "Core/PowerPC/ConditionRegister.h"
Expand Down Expand Up @@ -297,6 +298,7 @@ class PowerPCManager
void InitializeCPUCore(CPUCore cpu_core);
void ApplyMode();
void ResetRegisters();
void RefreshConfig();

PowerPCState m_ppc_state;

Expand All @@ -308,6 +310,8 @@ class PowerPCManager
MemChecks m_memchecks;
PPCDebugInterface m_debug_interface;

CPUThreadConfigCallback::ConfigChangedCallbackID m_registered_config_callback_id;

CoreTiming::EventType* m_invalidate_cache_thread_safe = nullptr;

Core::System& m_system;
Expand Down
7 changes: 7 additions & 0 deletions Source/Core/DolphinQt/MenuBar.cpp
Expand Up @@ -139,6 +139,7 @@ void MenuBar::OnEmulationStateChanged(Core::State state)
m_jit_interpreter_core->setEnabled(running);
m_jit_block_linking->setEnabled(!running);
m_jit_disable_cache->setEnabled(!running);
m_jit_disable_fastmem_arena->setEnabled(!running);
m_jit_clear_cache->setEnabled(running);
m_jit_log_coverage->setEnabled(!running);
m_jit_search_instruction->setEnabled(running);
Expand Down Expand Up @@ -847,6 +848,12 @@ void MenuBar::AddJITMenu()
connect(m_jit_disable_fastmem, &QAction::toggled,
[](bool enabled) { Config::SetBaseOrCurrent(Config::MAIN_FASTMEM, !enabled); });

m_jit_disable_fastmem_arena = m_jit->addAction(tr("Disable Fastmem Arena"));
m_jit_disable_fastmem_arena->setCheckable(true);
m_jit_disable_fastmem_arena->setChecked(!Config::Get(Config::MAIN_FASTMEM_ARENA));
connect(m_jit_disable_fastmem_arena, &QAction::toggled,
[](bool enabled) { Config::SetBaseOrCurrent(Config::MAIN_FASTMEM_ARENA, !enabled); });

m_jit_clear_cache = m_jit->addAction(tr("Clear Cache"), this, &MenuBar::ClearCache);

m_jit->addSeparator();
Expand Down
1 change: 1 addition & 0 deletions Source/Core/DolphinQt/MenuBar.h
Expand Up @@ -264,6 +264,7 @@ class MenuBar final : public QMenuBar
QAction* m_jit_block_linking;
QAction* m_jit_disable_cache;
QAction* m_jit_disable_fastmem;
QAction* m_jit_disable_fastmem_arena;
QAction* m_jit_clear_cache;
QAction* m_jit_log_coverage;
QAction* m_jit_search_instruction;
Expand Down
1 change: 0 additions & 1 deletion Source/Core/DolphinQt/Settings/AdvancedPane.cpp
Expand Up @@ -255,7 +255,6 @@ void AdvancedPane::Update()
m_cpu_emulation_engine_combobox->setEnabled(!running);
m_enable_mmu_checkbox->setEnabled(!running);
m_pause_on_panic_checkbox->setEnabled(!running);
m_accurate_cpu_cache_checkbox->setEnabled(!running);

{
QFont bf = font();
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoCommon/VertexLoaderARM64.cpp
Expand Up @@ -56,7 +56,7 @@ VertexLoaderARM64::VertexLoaderARM64(const TVtxDesc& vtx_desc, const VAT& vtx_at
const Common::ScopedJITPageWriteAndNoExecute enable_jit_page_writes;
ClearCodeSpace();
GenerateVertexLoader();
WriteProtect();
WriteProtect(true);
}

// Returns the register to use as the base and an offset from that register.
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoCommon/VertexLoaderX64.cpp
Expand Up @@ -49,7 +49,7 @@ VertexLoaderX64::VertexLoaderX64(const TVtxDesc& vtx_desc, const VAT& vtx_att)
AllocCodeSpace(4096);
ClearCodeSpace();
GenerateVertexLoader();
WriteProtect();
WriteProtect(true);

Common::JitRegister::Register(region, GetCodePtr(), "VertexLoaderX64\nVtx desc: \n{}\nVAT:\n{}",
vtx_desc, vtx_att);
Expand Down