From 3ebcc445de7e2a88a0be0a6ca967f5b0d9b9e01e Mon Sep 17 00:00:00 2001 From: degasus Date: Sat, 16 Nov 2019 11:25:26 +0100 Subject: [PATCH] Core/Jits: Adds an option to disable the register cache. This will help to disable all inter-instruction dependencies. So android users can check if only a single instruction is broken without compiling dolphin on their own. --- .../ui/SettingsFragmentPresenter.java | 5 ++++ .../features/settings/utils/SettingsFile.java | 1 + .../app/src/main/res/values/strings.xml | 1 + Source/Core/Core/ConfigManager.cpp | 3 +++ Source/Core/Core/ConfigManager.h | 1 + Source/Core/Core/PowerPC/Jit64/Jit.cpp | 26 ++++++++++++------- Source/Core/Core/PowerPC/JitArm64/Jit.cpp | 7 +++++ Source/Core/DolphinQt/MenuBar.cpp | 10 ++++++- Source/Core/DolphinQt/MenuBar.h | 1 + 9 files changed, 45 insertions(+), 10 deletions(-) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java index 83817cae95..d903b86e2f 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java @@ -640,6 +640,8 @@ public final class SettingsFragmentPresenter Setting jitSystemRegistersOff = debugSection.getSetting(SettingsFile.KEY_DEBUG_JITSYSTEMREGISTEROFF); Setting jitBranchOff = debugSection.getSetting(SettingsFile.KEY_DEBUG_JITBRANCHOFF); + Setting jitRegisterCacheOff = + debugSection.getSetting(SettingsFile.KEY_DEBUG_JITREGISTERCACHEOFF); sl.add(new HeaderSetting(null, null, R.string.debug_warning, 0)); @@ -672,6 +674,9 @@ public final class SettingsFragmentPresenter sl.add(new CheckBoxSetting(SettingsFile.KEY_DEBUG_JITBRANCHOFF, Settings.SECTION_DEBUG, R.string.debug_jitbranchoff, 0, false, jitBranchOff)); + sl.add(new CheckBoxSetting(SettingsFile.KEY_DEBUG_JITREGISTERCACHEOFF, Settings.SECTION_DEBUG, + R.string.debug_jitregistercacheoff, 0, false, + jitRegisterCacheOff)); } private void addStereoSettings(ArrayList sl) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java index aac139266f..3265e6bc9f 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/utils/SettingsFile.java @@ -102,6 +102,7 @@ public final class SettingsFile public static final String KEY_DEBUG_JITPAIREDOFF = "JitPairedOff"; public static final String KEY_DEBUG_JITSYSTEMREGISTEROFF = "JitSystemRegistersOff"; public static final String KEY_DEBUG_JITBRANCHOFF = "JitBranchOff"; + public static final String KEY_DEBUG_JITREGISTERCACHEOFF = "JitRegisterCacheOff"; public static final String KEY_GCPAD_TYPE = "SIDevice"; public static final String KEY_GCPAD_G_TYPE = "PadType"; diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml index 2ecbb07df7..c4bfe23807 100644 --- a/Source/Android/app/src/main/res/values/strings.xml +++ b/Source/Android/app/src/main/res/values/strings.xml @@ -254,6 +254,7 @@ Jit Paired Disabled Jit System Registers Disabled Jit Branch Disabled + Jit Register Cache Disabled Yes diff --git a/Source/Core/Core/ConfigManager.cpp b/Source/Core/Core/ConfigManager.cpp index 1aa1b3f0a6..7bce80bfd2 100644 --- a/Source/Core/Core/ConfigManager.cpp +++ b/Source/Core/Core/ConfigManager.cpp @@ -352,6 +352,7 @@ void SConfig::SaveJitDebugSettings(IniFile& ini) section->Set("JitPairedOff", bJITPairedOff); section->Set("JitSystemRegistersOff", bJITSystemRegistersOff); section->Set("JitBranchOff", bJITBranchOff); + section->Set("JitRegisterCacheOff", bJITRegisterCacheOff); } void SConfig::LoadSettings() @@ -644,6 +645,7 @@ void SConfig::LoadJitDebugSettings(IniFile& ini) section->Get("JitPairedOff", &bJITPairedOff, false); section->Get("JitSystemRegistersOff", &bJITSystemRegistersOff, false); section->Get("JitBranchOff", &bJITBranchOff, false); + section->Get("JitRegisterCacheOff", &bJITRegisterCacheOff, false); } void SConfig::ResetRunningGameMetadata() @@ -800,6 +802,7 @@ void SConfig::LoadDefaults() bJITPairedOff = false; bJITSystemRegistersOff = false; bJITBranchOff = false; + bJITRegisterCacheOff = false; ResetRunningGameMetadata(); } diff --git a/Source/Core/Core/ConfigManager.h b/Source/Core/Core/ConfigManager.h index 36f7ac353a..f94b6dee84 100644 --- a/Source/Core/Core/ConfigManager.h +++ b/Source/Core/Core/ConfigManager.h @@ -105,6 +105,7 @@ struct SConfig bool bJITPairedOff = false; bool bJITSystemRegistersOff = false; bool bJITBranchOff = false; + bool bJITRegisterCacheOff = false; bool bFastmem; bool bFPRF = false; diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp index aa6fa49047..265655a6c1 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp @@ -997,15 +997,23 @@ u8* Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC) SetJumpTarget(noBreakpoint); } - // If we have an input register that is going to be used again, load it pre-emptively, - // even if the instruction doesn't strictly need it in a register, to avoid redundant - // loads later. Of course, don't do this if we're already out of registers. - // As a bit of a heuristic, make sure we have at least one register left over for the - // output, which needs to be bound in the actual instruction compilation. - // TODO: make this smarter in the case that we're actually register-starved, i.e. - // prioritize the more important registers. - gpr.PreloadRegisters(op.regsIn & op.gprInReg); - fpr.PreloadRegisters(op.fregsIn & op.fprInXmm); + if (SConfig::GetInstance().bJITRegisterCacheOff) + { + gpr.Flush(); + fpr.Flush(); + } + else + { + // If we have an input register that is going to be used again, load it pre-emptively, + // even if the instruction doesn't strictly need it in a register, to avoid redundant + // loads later. Of course, don't do this if we're already out of registers. + // As a bit of a heuristic, make sure we have at least one register left over for the + // output, which needs to be bound in the actual instruction compilation. + // TODO: make this smarter in the case that we're actually register-starved, i.e. + // prioritize the more important registers. + gpr.PreloadRegisters(op.regsIn & op.gprInReg); + fpr.PreloadRegisters(op.fregsIn & op.fprInXmm); + } CompileInstruction(op); diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp index faee0210ff..1c79fdbf8c 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp @@ -776,6 +776,13 @@ void JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC) js.firstFPInstructionFound = true; } + if (SConfig::GetInstance().bJITRegisterCacheOff) + { + gpr.Flush(FLUSH_ALL); + fpr.Flush(FLUSH_ALL); + FlushCarry(); + } + CompileInstruction(op); if (!CanMergeNextInstructions(1) || js.op[1].opinfo->type != ::OpType::Integer) FlushCarry(); diff --git a/Source/Core/DolphinQt/MenuBar.cpp b/Source/Core/DolphinQt/MenuBar.cpp index 9d76a7c647..e5303e65ae 100644 --- a/Source/Core/DolphinQt/MenuBar.cpp +++ b/Source/Core/DolphinQt/MenuBar.cpp @@ -142,7 +142,7 @@ void MenuBar::OnEmulationStateChanged(Core::State state) {m_jit_off, m_jit_loadstore_off, m_jit_loadstore_lbzx_off, m_jit_loadstore_lxz_off, m_jit_loadstore_lwz_off, m_jit_loadstore_floating_off, m_jit_loadstore_paired_off, m_jit_floatingpoint_off, m_jit_integer_off, m_jit_paired_off, m_jit_systemregisters_off, - m_jit_branch_off}) + m_jit_branch_off, m_jit_register_cache_off}) { action->setEnabled(running && !playing); } @@ -896,6 +896,14 @@ void MenuBar::AddJITMenu() SConfig::GetInstance().bJITBranchOff = 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(SConfig::GetInstance().bJITRegisterCacheOff); + connect(m_jit_register_cache_off, &QAction::toggled, [this](bool enabled) { + SConfig::GetInstance().bJITRegisterCacheOff = enabled; + ClearCache(); + }); } void MenuBar::AddSymbolsMenu() diff --git a/Source/Core/DolphinQt/MenuBar.h b/Source/Core/DolphinQt/MenuBar.h index 7118b2ca82..9875888cbc 100644 --- a/Source/Core/DolphinQt/MenuBar.h +++ b/Source/Core/DolphinQt/MenuBar.h @@ -261,6 +261,7 @@ private: QAction* m_jit_paired_off; QAction* m_jit_systemregisters_off; QAction* m_jit_branch_off; + QAction* m_jit_register_cache_off; bool m_game_selected = false; };