diff --git a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp index eca1afd32d..8fbed42f06 100644 --- a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp +++ b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp @@ -82,12 +82,13 @@ CachedInterpreter::~CachedInterpreter() = default; void CachedInterpreter::Init() { + RefreshConfig(); + m_code.reserve(CODE_SIZE / sizeof(Instruction)); jo.enableBlocklink = false; m_block_cache.Init(); - UpdateMemoryAndExceptionOptions(); code_block.m_stats = &js.st; code_block.m_gpa = &js.gpa; @@ -383,5 +384,5 @@ void CachedInterpreter::ClearCache() { m_code.clear(); m_block_cache.Clear(); - UpdateMemoryAndExceptionOptions(); + RefreshConfig(); } diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp index fcd9d1dc3d..e5aa885263 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp @@ -251,6 +251,8 @@ bool Jit64::BackPatch(SContext* ctx) void Jit64::Init() { + RefreshConfig(); + EnableBlockLink(); auto& memory = m_system.GetMemory(); @@ -258,7 +260,6 @@ void Jit64::Init() jo.fastmem_arena = m_fastmem_enabled && memory.InitFastmemArena(); jo.optimizeGatherPipe = true; jo.accurateSinglePrecision = true; - UpdateMemoryAndExceptionOptions(); js.fastmemLoadStore = nullptr; js.compilerPC = 0; @@ -306,7 +307,7 @@ void Jit64::ClearCache() m_const_pool.Clear(); ClearCodeSpace(); Clear(); - UpdateMemoryAndExceptionOptions(); + RefreshConfig(); ResetFreeMemoryRanges(); } diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp index 664f8a6525..99d5da4b6f 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp @@ -47,6 +47,8 @@ JitArm64::~JitArm64() = default; void JitArm64::Init() { + RefreshConfig(); + const size_t child_code_size = m_mmu_enabled ? FARCODE_SIZE_MMU : FARCODE_SIZE; AllocCodeSpace(CODE_SIZE + child_code_size); AddChildCodeSpace(&m_far_code, child_code_size); @@ -55,7 +57,6 @@ void JitArm64::Init() jo.fastmem_arena = m_fastmem_enabled && memory.InitFastmemArena(); jo.optimizeGatherPipe = true; - UpdateMemoryAndExceptionOptions(); SetBlockLinkingEnabled(true); SetOptimizationEnabled(true); gpr.Init(this); @@ -157,7 +158,7 @@ void JitArm64::ClearCache() const Common::ScopedJITPageWriteAndNoExecute enable_jit_page_writes; ClearCodeSpace(); m_far_code.ClearCodeSpace(); - UpdateMemoryAndExceptionOptions(); + RefreshConfig(); GenerateAsm(); diff --git a/Source/Core/Core/PowerPC/JitCommon/JitBase.cpp b/Source/Core/Core/PowerPC/JitCommon/JitBase.cpp index 17d9fe1bea..58d61499dc 100644 --- a/Source/Core/Core/PowerPC/JitCommon/JitBase.cpp +++ b/Source/Core/Core/PowerPC/JitCommon/JitBase.cpp @@ -3,6 +3,10 @@ #include "Core/PowerPC/JitCommon/JitBase.h" +#include +#include +#include + #include "Common/Align.h" #include "Common/CommonTypes.h" #include "Common/MemoryUtil.h" @@ -52,6 +56,31 @@ // After resetting the stack to the top, we call _resetstkoflw() to restore // the guard page at the 256kb mark. +const std::array*>, 22> JitBase::JIT_SETTINGS{{ + {&JitBase::bJITOff, &Config::MAIN_DEBUG_JIT_OFF}, + {&JitBase::bJITLoadStoreOff, &Config::MAIN_DEBUG_JIT_LOAD_STORE_OFF}, + {&JitBase::bJITLoadStorelXzOff, &Config::MAIN_DEBUG_JIT_LOAD_STORE_LXZ_OFF}, + {&JitBase::bJITLoadStorelwzOff, &Config::MAIN_DEBUG_JIT_LOAD_STORE_LWZ_OFF}, + {&JitBase::bJITLoadStorelbzxOff, &Config::MAIN_DEBUG_JIT_LOAD_STORE_LBZX_OFF}, + {&JitBase::bJITLoadStoreFloatingOff, &Config::MAIN_DEBUG_JIT_LOAD_STORE_FLOATING_OFF}, + {&JitBase::bJITLoadStorePairedOff, &Config::MAIN_DEBUG_JIT_LOAD_STORE_PAIRED_OFF}, + {&JitBase::bJITFloatingPointOff, &Config::MAIN_DEBUG_JIT_FLOATING_POINT_OFF}, + {&JitBase::bJITIntegerOff, &Config::MAIN_DEBUG_JIT_INTEGER_OFF}, + {&JitBase::bJITPairedOff, &Config::MAIN_DEBUG_JIT_PAIRED_OFF}, + {&JitBase::bJITSystemRegistersOff, &Config::MAIN_DEBUG_JIT_SYSTEM_REGISTERS_OFF}, + {&JitBase::bJITBranchOff, &Config::MAIN_DEBUG_JIT_BRANCH_OFF}, + {&JitBase::bJITRegisterCacheOff, &Config::MAIN_DEBUG_JIT_REGISTER_CACHE_OFF}, + {&JitBase::m_enable_debugging, &Config::MAIN_ENABLE_DEBUGGING}, + {&JitBase::m_enable_branch_following, &Config::MAIN_JIT_FOLLOW_BRANCH}, + {&JitBase::m_enable_float_exceptions, &Config::MAIN_FLOAT_EXCEPTIONS}, + {&JitBase::m_enable_div_by_zero_exceptions, &Config::MAIN_DIVIDE_BY_ZERO_EXCEPTIONS}, + {&JitBase::m_low_dcbz_hack, &Config::MAIN_LOW_DCBZ_HACK}, + {&JitBase::m_fprf, &Config::MAIN_FPRF}, + {&JitBase::m_accurate_nans, &Config::MAIN_ACCURATE_NANS}, + {&JitBase::m_fastmem_enabled, &Config::MAIN_FASTMEM}, + {&JitBase::m_accurate_cpu_cache_enabled, &Config::MAIN_ACCURATE_CPU_CACHE}, +}}; + const u8* JitBase::Dispatch(JitBase& jit) { return jit.GetBlockCache()->Dispatch(); @@ -66,9 +95,11 @@ JitBase::JitBase(Core::System& system) : m_code_buffer(code_buffer_size), m_system(system), m_ppc_state(system.GetPPCState()), m_mmu(system.GetMMU()) { - m_registered_config_callback_id = - CPUThreadConfigCallback::AddConfigChangedCallback([this] { RefreshConfig(); }); - RefreshConfig(); + m_registered_config_callback_id = CPUThreadConfigCallback::AddConfigChangedCallback([this] { + if (DoesConfigNeedRefresh()) + ClearCache(); + }); + // The JIT is responsible for calling RefreshConfig on Init and ClearCache } JitBase::~JitBase() @@ -76,31 +107,20 @@ JitBase::~JitBase() CPUThreadConfigCallback::RemoveConfigChangedCallback(m_registered_config_callback_id); } +bool JitBase::DoesConfigNeedRefresh() +{ + return std::any_of(JIT_SETTINGS.begin(), JIT_SETTINGS.end(), [this](const auto& pair) { + return this->*pair.first != Config::Get(*pair.second); + }); +} + void JitBase::RefreshConfig() { - bJITOff = Config::Get(Config::MAIN_DEBUG_JIT_OFF); - bJITLoadStoreOff = Config::Get(Config::MAIN_DEBUG_JIT_LOAD_STORE_OFF); - bJITLoadStorelXzOff = Config::Get(Config::MAIN_DEBUG_JIT_LOAD_STORE_LXZ_OFF); - bJITLoadStorelwzOff = Config::Get(Config::MAIN_DEBUG_JIT_LOAD_STORE_LWZ_OFF); - bJITLoadStorelbzxOff = Config::Get(Config::MAIN_DEBUG_JIT_LOAD_STORE_LBZX_OFF); - bJITLoadStoreFloatingOff = Config::Get(Config::MAIN_DEBUG_JIT_LOAD_STORE_FLOATING_OFF); - bJITLoadStorePairedOff = Config::Get(Config::MAIN_DEBUG_JIT_LOAD_STORE_PAIRED_OFF); - bJITFloatingPointOff = Config::Get(Config::MAIN_DEBUG_JIT_FLOATING_POINT_OFF); - bJITIntegerOff = Config::Get(Config::MAIN_DEBUG_JIT_INTEGER_OFF); - bJITPairedOff = Config::Get(Config::MAIN_DEBUG_JIT_PAIRED_OFF); - bJITSystemRegistersOff = Config::Get(Config::MAIN_DEBUG_JIT_SYSTEM_REGISTERS_OFF); - bJITBranchOff = Config::Get(Config::MAIN_DEBUG_JIT_BRANCH_OFF); - bJITRegisterCacheOff = Config::Get(Config::MAIN_DEBUG_JIT_REGISTER_CACHE_OFF); - m_enable_debugging = Config::Get(Config::MAIN_ENABLE_DEBUGGING); - m_enable_float_exceptions = Config::Get(Config::MAIN_FLOAT_EXCEPTIONS); - m_enable_div_by_zero_exceptions = Config::Get(Config::MAIN_DIVIDE_BY_ZERO_EXCEPTIONS); - m_low_dcbz_hack = Config::Get(Config::MAIN_LOW_DCBZ_HACK); - m_fprf = Config::Get(Config::MAIN_FPRF); - m_accurate_nans = Config::Get(Config::MAIN_ACCURATE_NANS); - m_fastmem_enabled = Config::Get(Config::MAIN_FASTMEM); + for (const auto& [member, config_info] : JIT_SETTINGS) + this->*member = Config::Get(*config_info); + m_mmu_enabled = m_system.IsMMUMode(); m_pause_on_panic_enabled = m_system.IsPauseOnPanicMode(); - m_accurate_cpu_cache_enabled = Config::Get(Config::MAIN_ACCURATE_CPU_CACHE); if (m_accurate_cpu_cache_enabled) { m_fastmem_enabled = false; @@ -109,9 +129,15 @@ void JitBase::RefreshConfig() } analyzer.SetDebuggingEnabled(m_enable_debugging); - analyzer.SetBranchFollowingEnabled(Config::Get(Config::MAIN_JIT_FOLLOW_BRANCH)); + analyzer.SetBranchFollowingEnabled(m_enable_branch_following); analyzer.SetFloatExceptionsEnabled(m_enable_float_exceptions); analyzer.SetDivByZeroExceptionsEnabled(m_enable_div_by_zero_exceptions); + + bool any_watchpoints = m_system.GetPowerPC().GetMemChecks().HasAny(); + jo.fastmem = m_fastmem_enabled && jo.fastmem_arena && (m_ppc_state.msr.DR || !any_watchpoints); + jo.memcheck = m_mmu_enabled || m_pause_on_panic_enabled || any_watchpoints; + jo.fp_exceptions = m_enable_float_exceptions; + jo.div_by_zero_exceptions = m_enable_div_by_zero_exceptions; } void JitBase::InitBLROptimization() @@ -233,15 +259,6 @@ bool JitBase::CanMergeNextInstructions(int count) const return true; } -void JitBase::UpdateMemoryAndExceptionOptions() -{ - bool any_watchpoints = m_system.GetPowerPC().GetMemChecks().HasAny(); - jo.fastmem = m_fastmem_enabled && jo.fastmem_arena && (m_ppc_state.msr.DR || !any_watchpoints); - jo.memcheck = m_mmu_enabled || m_pause_on_panic_enabled || any_watchpoints; - jo.fp_exceptions = m_enable_float_exceptions; - jo.div_by_zero_exceptions = m_enable_div_by_zero_exceptions; -} - bool JitBase::ShouldHandleFPExceptionForInstruction(const PPCAnalyst::CodeOp* op) { if (jo.fp_exceptions) diff --git a/Source/Core/Core/PowerPC/JitCommon/JitBase.h b/Source/Core/Core/PowerPC/JitCommon/JitBase.h index c2e41f8e52..2846938cf4 100644 --- a/Source/Core/Core/PowerPC/JitCommon/JitBase.h +++ b/Source/Core/Core/PowerPC/JitCommon/JitBase.h @@ -3,12 +3,15 @@ #pragma once +#include #include #include #include +#include #include "Common/BitSet.h" #include "Common/CommonTypes.h" +#include "Common/Config/ConfigInfo.h" #include "Common/x64Emitter.h" #include "Core/CPUThreadConfigCallback.h" #include "Core/ConfigManager.h" @@ -145,6 +148,7 @@ protected: bool bJITBranchOff = false; bool bJITRegisterCacheOff = false; bool m_enable_debugging = false; + bool m_enable_branch_following = false; bool m_enable_float_exceptions = false; bool m_enable_div_by_zero_exceptions = false; bool m_low_dcbz_hack = false; @@ -159,6 +163,9 @@ protected: bool m_cleanup_after_stackfault = false; u8* m_stack_guard = nullptr; + static const std::array*>, 22> JIT_SETTINGS; + + bool DoesConfigNeedRefresh(); void RefreshConfig(); void InitBLROptimization(); @@ -168,8 +175,6 @@ protected: bool CanMergeNextInstructions(int count) const; - void UpdateMemoryAndExceptionOptions(); - bool ShouldHandleFPExceptionForInstruction(const PPCAnalyst::CodeOp* op); public: diff --git a/Source/Core/DolphinQt/MenuBar.cpp b/Source/Core/DolphinQt/MenuBar.cpp index 664e40dd05..7fd00a8edc 100644 --- a/Source/Core/DolphinQt/MenuBar.cpp +++ b/Source/Core/DolphinQt/MenuBar.cpp @@ -854,10 +854,8 @@ void MenuBar::AddJITMenu() m_jit_disable_fastmem = m_jit->addAction(tr("Disable Fastmem")); m_jit_disable_fastmem->setCheckable(true); m_jit_disable_fastmem->setChecked(!Config::Get(Config::MAIN_FASTMEM)); - connect(m_jit_disable_fastmem, &QAction::toggled, [this](bool enabled) { - Config::SetBaseOrCurrent(Config::MAIN_FASTMEM, !enabled); - ClearCache(); - }); + connect(m_jit_disable_fastmem, &QAction::toggled, + [](bool enabled) { Config::SetBaseOrCurrent(Config::MAIN_FASTMEM, !enabled); }); m_jit_clear_cache = m_jit->addAction(tr("Clear Cache"), this, &MenuBar::ClearCache); @@ -873,106 +871,92 @@ void MenuBar::AddJITMenu() m_jit_off = m_jit->addAction(tr("JIT Off (JIT Core)")); m_jit_off->setCheckable(true); m_jit_off->setChecked(Config::Get(Config::MAIN_DEBUG_JIT_OFF)); - connect(m_jit_off, &QAction::toggled, [this](bool enabled) { - Config::SetBaseOrCurrent(Config::MAIN_DEBUG_JIT_OFF, enabled); - ClearCache(); - }); + connect(m_jit_off, &QAction::toggled, + [](bool enabled) { Config::SetBaseOrCurrent(Config::MAIN_DEBUG_JIT_OFF, enabled); }); m_jit_loadstore_off = m_jit->addAction(tr("JIT LoadStore Off")); m_jit_loadstore_off->setCheckable(true); m_jit_loadstore_off->setChecked(Config::Get(Config::MAIN_DEBUG_JIT_LOAD_STORE_OFF)); - connect(m_jit_loadstore_off, &QAction::toggled, [this](bool enabled) { + connect(m_jit_loadstore_off, &QAction::toggled, [](bool enabled) { Config::SetBaseOrCurrent(Config::MAIN_DEBUG_JIT_LOAD_STORE_OFF, enabled); - ClearCache(); }); m_jit_loadstore_lbzx_off = m_jit->addAction(tr("JIT LoadStore lbzx Off")); m_jit_loadstore_lbzx_off->setCheckable(true); m_jit_loadstore_lbzx_off->setChecked(Config::Get(Config::MAIN_DEBUG_JIT_LOAD_STORE_LBZX_OFF)); - connect(m_jit_loadstore_lbzx_off, &QAction::toggled, [this](bool enabled) { + connect(m_jit_loadstore_lbzx_off, &QAction::toggled, [](bool enabled) { Config::SetBaseOrCurrent(Config::MAIN_DEBUG_JIT_LOAD_STORE_LBZX_OFF, enabled); - ClearCache(); }); m_jit_loadstore_lxz_off = m_jit->addAction(tr("JIT LoadStore lXz Off")); m_jit_loadstore_lxz_off->setCheckable(true); m_jit_loadstore_lxz_off->setChecked(Config::Get(Config::MAIN_DEBUG_JIT_LOAD_STORE_LXZ_OFF)); - connect(m_jit_loadstore_lxz_off, &QAction::toggled, [this](bool enabled) { + connect(m_jit_loadstore_lxz_off, &QAction::toggled, [](bool enabled) { Config::SetBaseOrCurrent(Config::MAIN_DEBUG_JIT_LOAD_STORE_LXZ_OFF, enabled); - ClearCache(); }); m_jit_loadstore_lwz_off = m_jit->addAction(tr("JIT LoadStore lwz Off")); m_jit_loadstore_lwz_off->setCheckable(true); m_jit_loadstore_lwz_off->setChecked(Config::Get(Config::MAIN_DEBUG_JIT_LOAD_STORE_LWZ_OFF)); - connect(m_jit_loadstore_lwz_off, &QAction::toggled, [this](bool enabled) { + connect(m_jit_loadstore_lwz_off, &QAction::toggled, [](bool enabled) { Config::SetBaseOrCurrent(Config::MAIN_DEBUG_JIT_LOAD_STORE_LWZ_OFF, enabled); - ClearCache(); }); m_jit_loadstore_floating_off = m_jit->addAction(tr("JIT LoadStore Floating Off")); m_jit_loadstore_floating_off->setCheckable(true); m_jit_loadstore_floating_off->setChecked( Config::Get(Config::MAIN_DEBUG_JIT_LOAD_STORE_FLOATING_OFF)); - connect(m_jit_loadstore_floating_off, &QAction::toggled, [this](bool enabled) { + connect(m_jit_loadstore_floating_off, &QAction::toggled, [](bool enabled) { Config::SetBaseOrCurrent(Config::MAIN_DEBUG_JIT_LOAD_STORE_FLOATING_OFF, enabled); - ClearCache(); }); m_jit_loadstore_paired_off = m_jit->addAction(tr("JIT LoadStore Paired Off")); m_jit_loadstore_paired_off->setCheckable(true); m_jit_loadstore_paired_off->setChecked(Config::Get(Config::MAIN_DEBUG_JIT_LOAD_STORE_PAIRED_OFF)); - connect(m_jit_loadstore_paired_off, &QAction::toggled, [this](bool enabled) { + connect(m_jit_loadstore_paired_off, &QAction::toggled, [](bool enabled) { Config::SetBaseOrCurrent(Config::MAIN_DEBUG_JIT_LOAD_STORE_PAIRED_OFF, enabled); - ClearCache(); }); m_jit_floatingpoint_off = m_jit->addAction(tr("JIT FloatingPoint Off")); m_jit_floatingpoint_off->setCheckable(true); m_jit_floatingpoint_off->setChecked(Config::Get(Config::MAIN_DEBUG_JIT_FLOATING_POINT_OFF)); - connect(m_jit_floatingpoint_off, &QAction::toggled, [this](bool enabled) { + connect(m_jit_floatingpoint_off, &QAction::toggled, [](bool enabled) { Config::SetBaseOrCurrent(Config::MAIN_DEBUG_JIT_FLOATING_POINT_OFF, enabled); - ClearCache(); }); m_jit_integer_off = m_jit->addAction(tr("JIT Integer Off")); m_jit_integer_off->setCheckable(true); m_jit_integer_off->setChecked(Config::Get(Config::MAIN_DEBUG_JIT_INTEGER_OFF)); - connect(m_jit_integer_off, &QAction::toggled, [this](bool enabled) { + connect(m_jit_integer_off, &QAction::toggled, [](bool enabled) { Config::SetBaseOrCurrent(Config::MAIN_DEBUG_JIT_INTEGER_OFF, enabled); - ClearCache(); }); m_jit_paired_off = m_jit->addAction(tr("JIT Paired Off")); m_jit_paired_off->setCheckable(true); m_jit_paired_off->setChecked(Config::Get(Config::MAIN_DEBUG_JIT_PAIRED_OFF)); - connect(m_jit_paired_off, &QAction::toggled, [this](bool enabled) { + connect(m_jit_paired_off, &QAction::toggled, [](bool enabled) { Config::SetBaseOrCurrent(Config::MAIN_DEBUG_JIT_PAIRED_OFF, enabled); - ClearCache(); }); m_jit_systemregisters_off = m_jit->addAction(tr("JIT SystemRegisters Off")); m_jit_systemregisters_off->setCheckable(true); m_jit_systemregisters_off->setChecked(Config::Get(Config::MAIN_DEBUG_JIT_SYSTEM_REGISTERS_OFF)); - connect(m_jit_systemregisters_off, &QAction::toggled, [this](bool enabled) { + connect(m_jit_systemregisters_off, &QAction::toggled, [](bool enabled) { Config::SetBaseOrCurrent(Config::MAIN_DEBUG_JIT_SYSTEM_REGISTERS_OFF, enabled); - ClearCache(); }); m_jit_branch_off = m_jit->addAction(tr("JIT Branch Off")); m_jit_branch_off->setCheckable(true); m_jit_branch_off->setChecked(Config::Get(Config::MAIN_DEBUG_JIT_BRANCH_OFF)); - connect(m_jit_branch_off, &QAction::toggled, [this](bool enabled) { + connect(m_jit_branch_off, &QAction::toggled, [](bool enabled) { Config::SetBaseOrCurrent(Config::MAIN_DEBUG_JIT_BRANCH_OFF, enabled); - ClearCache(); }); m_jit_register_cache_off = m_jit->addAction(tr("JIT Register Cache Off")); m_jit_register_cache_off->setCheckable(true); m_jit_register_cache_off->setChecked(Config::Get(Config::MAIN_DEBUG_JIT_REGISTER_CACHE_OFF)); - connect(m_jit_register_cache_off, &QAction::toggled, [this](bool enabled) { + connect(m_jit_register_cache_off, &QAction::toggled, [](bool enabled) { Config::SetBaseOrCurrent(Config::MAIN_DEBUG_JIT_REGISTER_CACHE_OFF, enabled); - ClearCache(); }); }