Merge pull request #8472 from degasus/jitsetting

Core/Jits: Adds an option to disable the register cache.
This commit is contained in:
Tilka 2020-02-08 13:49:33 +00:00 committed by GitHub
commit e323f47ceb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 45 additions and 10 deletions

View File

@ -641,6 +641,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));
@ -673,6 +675,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<SettingsItem> sl)

View File

@ -104,6 +104,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";

View File

@ -257,6 +257,7 @@
<string name="debug_jitpairedoff">Jit Paired Disabled</string>
<string name="debug_jitsystemregistersoffr">Jit System Registers Disabled</string>
<string name="debug_jitbranchoff">Jit Branch Disabled</string>
<string name="debug_jitregistercacheoff">Jit Register Cache Disabled</string>
<!-- Miscellaneous -->
<string name="yes">Yes</string>

View File

@ -355,6 +355,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()
@ -647,6 +648,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()
@ -799,6 +801,7 @@ void SConfig::LoadDefaults()
bJITPairedOff = false;
bJITSystemRegistersOff = false;
bJITBranchOff = false;
bJITRegisterCacheOff = false;
ResetRunningGameMetadata();
}

View File

@ -105,6 +105,7 @@ struct SConfig
bool bJITPairedOff = false;
bool bJITSystemRegistersOff = false;
bool bJITBranchOff = false;
bool bJITRegisterCacheOff = false;
bool bFastmem;
bool bFPRF = false;

View File

@ -1002,15 +1002,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);

View File

@ -779,6 +779,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();

View File

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

View File

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