From 0193202964449ba7a6ae46d614a63bf5caa589a7 Mon Sep 17 00:00:00 2001
From: MerryMage <MerryMage@users.noreply.github.com>
Date: Sat, 11 Jul 2020 14:26:36 +0100
Subject: [PATCH 1/4] configuration: Add settings to enable/disable specific
 CPU optimizations

---
 externals/dynarmic                          |   2 +-
 src/core/arm/dynarmic/arm_dynarmic_32.cpp   |  28 ++++-
 src/core/arm/dynarmic/arm_dynarmic_64.cpp   |  32 ++++--
 src/core/settings.h                         |  11 +-
 src/yuzu/CMakeLists.txt                     |   3 +
 src/yuzu/configuration/config.cpp           |  53 ++++++++-
 src/yuzu/configuration/config.h             |   2 +
 src/yuzu/configuration/configure.ui         |  11 ++
 src/yuzu/configuration/configure_cpu.cpp    |  64 +++++++++++
 src/yuzu/configuration/configure_cpu.h      |  31 ++++++
 src/yuzu/configuration/configure_cpu.ui     | 113 ++++++++++++++++++++
 src/yuzu/configuration/configure_debug.cpp  |   2 -
 src/yuzu/configuration/configure_debug.ui   |   7 --
 src/yuzu/configuration/configure_dialog.cpp |   5 +-
 src/yuzu_cmd/config.cpp                     |   2 -
 src/yuzu_cmd/default_ini.h                  |  36 ++++++-
 src/yuzu_tester/default_ini.h               |  33 ++++++
 17 files changed, 405 insertions(+), 30 deletions(-)
 create mode 100644 src/yuzu/configuration/configure_cpu.cpp
 create mode 100644 src/yuzu/configuration/configure_cpu.h
 create mode 100644 src/yuzu/configuration/configure_cpu.ui

diff --git a/externals/dynarmic b/externals/dynarmic
index 4f967387c..82417da78 160000
--- a/externals/dynarmic
+++ b/externals/dynarmic
@@ -1 +1 @@
-Subproject commit 4f967387c07365b7ea35d2fa3e19b7df8872a09b
+Subproject commit 82417da7803e2cf18efc28a1cd3f3d0a4b6045ae
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index 0d4ab95b7..369a081cd 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -142,10 +142,30 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable&
     // Timing
     config.wall_clock_cntpct = uses_wall_clock;
 
-    // Optimizations
-    if (Settings::values.disable_cpu_opt) {
-        config.enable_optimizations = false;
-        config.enable_fast_dispatch = false;
+    // Safe optimizations
+    if (!Settings::values.cpuopt_page_tables) {
+        config.page_table = nullptr;
+    }
+    if (!Settings::values.cpuopt_block_linking) {
+        config.optimizations &= ~Dynarmic::OptimizationFlag::BlockLinking;
+    }
+    if (!Settings::values.cpuopt_return_stack_buffer) {
+        config.optimizations &= ~Dynarmic::OptimizationFlag::ReturnStackBuffer;
+    }
+    if (!Settings::values.cpuopt_fast_dispatcher) {
+        config.optimizations &= ~Dynarmic::OptimizationFlag::FastDispatch;
+    }
+    if (!Settings::values.cpuopt_context_elimination) {
+        config.optimizations &= ~Dynarmic::OptimizationFlag::GetSetElimination;
+    }
+    if (!Settings::values.cpuopt_const_prop) {
+        config.optimizations &= ~Dynarmic::OptimizationFlag::ConstProp;
+    }
+    if (!Settings::values.cpuopt_misc_ir) {
+        config.optimizations &= ~Dynarmic::OptimizationFlag::MiscIROpt;
+    }
+    if (!Settings::values.cpuopt_reduce_misalign_checks) {
+        config.only_detect_misalignment_via_page_table_on_page_boundary = false;
     }
 
     return std::make_unique<Dynarmic::A32::Jit>(config);
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index 790981034..e208a4aa7 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -191,15 +191,35 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable&
     // Unpredictable instructions
     config.define_unpredictable_behaviour = true;
 
-    // Optimizations
-    if (Settings::values.disable_cpu_opt) {
-        config.enable_optimizations = false;
-        config.enable_fast_dispatch = false;
-    }
-
     // Timing
     config.wall_clock_cntpct = uses_wall_clock;
 
+    // Safe optimizations
+    if (!Settings::values.cpuopt_page_tables) {
+        config.page_table = nullptr;
+    }
+    if (!Settings::values.cpuopt_block_linking) {
+        config.optimizations &= ~Dynarmic::OptimizationFlag::BlockLinking;
+    }
+    if (!Settings::values.cpuopt_return_stack_buffer) {
+        config.optimizations &= ~Dynarmic::OptimizationFlag::ReturnStackBuffer;
+    }
+    if (!Settings::values.cpuopt_fast_dispatcher) {
+        config.optimizations &= ~Dynarmic::OptimizationFlag::FastDispatch;
+    }
+    if (!Settings::values.cpuopt_context_elimination) {
+        config.optimizations &= ~Dynarmic::OptimizationFlag::GetSetElimination;
+    }
+    if (!Settings::values.cpuopt_const_prop) {
+        config.optimizations &= ~Dynarmic::OptimizationFlag::ConstProp;
+    }
+    if (!Settings::values.cpuopt_misc_ir) {
+        config.optimizations &= ~Dynarmic::OptimizationFlag::MiscIROpt;
+    }
+    if (!Settings::values.cpuopt_reduce_misalign_checks) {
+        config.only_detect_misalignment_via_page_table_on_page_boundary = false;
+    }
+
     return std::make_shared<Dynarmic::A64::Jit>(config);
 }
 
diff --git a/src/core/settings.h b/src/core/settings.h
index 850ca4072..c081c083f 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -427,6 +427,16 @@ struct Values {
     // Core
     Setting<bool> use_multi_core;
 
+    // Cpu
+    bool cpuopt_page_tables;
+    bool cpuopt_block_linking;
+    bool cpuopt_return_stack_buffer;
+    bool cpuopt_fast_dispatcher;
+    bool cpuopt_context_elimination;
+    bool cpuopt_const_prop;
+    bool cpuopt_misc_ir;
+    bool cpuopt_reduce_misalign_checks;
+
     // Renderer
     Setting<RendererBackend> renderer_backend;
     bool renderer_debug;
@@ -505,7 +515,6 @@ struct Values {
     bool dump_nso;
     bool reporting_services;
     bool quest_flag;
-    bool disable_cpu_opt;
     bool disable_macro_jit;
 
     // Misceallaneous
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 6b25a7fa0..39efa962b 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -30,6 +30,9 @@ add_executable(yuzu
     configuration/configure_audio.cpp
     configuration/configure_audio.h
     configuration/configure_audio.ui
+    configuration/configure_cpu.cpp
+    configuration/configure_cpu.h
+    configuration/configure_cpu.ui
     configuration/configure_debug.cpp
     configuration/configure_debug.h
     configuration/configure_debug.ui
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 1b2b1b2bb..f28e345a5 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -540,8 +540,6 @@ void Config::ReadDebuggingValues() {
     Settings::values.reporting_services =
         ReadSetting(QStringLiteral("reporting_services"), false).toBool();
     Settings::values.quest_flag = ReadSetting(QStringLiteral("quest_flag"), false).toBool();
-    Settings::values.disable_cpu_opt =
-        ReadSetting(QStringLiteral("disable_cpu_opt"), false).toBool();
     Settings::values.disable_macro_jit =
         ReadSetting(QStringLiteral("disable_macro_jit"), false).toBool();
 
@@ -633,6 +631,31 @@ void Config::ReadPathValues() {
     qt_config->endGroup();
 }
 
+void Config::ReadCpuValues() {
+    qt_config->beginGroup(QStringLiteral("Cpu"));
+
+    if (global) {
+        Settings::values.cpuopt_page_tables =
+            ReadSetting(QStringLiteral("cpuopt_page_tables"), true).toBool();
+        Settings::values.cpuopt_block_linking =
+            ReadSetting(QStringLiteral("cpuopt_block_linking"), true).toBool();
+        Settings::values.cpuopt_return_stack_buffer =
+            ReadSetting(QStringLiteral("cpuopt_return_stack_buffer"), true).toBool();
+        Settings::values.cpuopt_fast_dispatcher =
+            ReadSetting(QStringLiteral("cpuopt_fast_dispatcher"), true).toBool();
+        Settings::values.cpuopt_context_elimination =
+            ReadSetting(QStringLiteral("cpuopt_context_elimination"), true).toBool();
+        Settings::values.cpuopt_const_prop =
+            ReadSetting(QStringLiteral("cpuopt_const_prop"), true).toBool();
+        Settings::values.cpuopt_misc_ir =
+            ReadSetting(QStringLiteral("cpuopt_misc_ir"), true).toBool();
+        Settings::values.cpuopt_reduce_misalign_checks =
+            ReadSetting(QStringLiteral("cpuopt_reduce_misalign_checks"), true).toBool();
+    }
+
+    qt_config->endGroup();
+}
+
 void Config::ReadRendererValues() {
     qt_config->beginGroup(QStringLiteral("Renderer"));
 
@@ -829,6 +852,7 @@ void Config::ReadValues() {
         ReadMiscellaneousValues();
     }
     ReadCoreValues();
+    ReadCpuValues();
     ReadRendererValues();
     ReadAudioValues();
     ReadSystemValues();
@@ -929,6 +953,7 @@ void Config::SaveValues() {
         SaveMiscellaneousValues();
     }
     SaveCoreValues();
+    SaveCpuValues();
     SaveRendererValues();
     SaveAudioValues();
     SaveSystemValues();
@@ -1033,7 +1058,6 @@ void Config::SaveDebuggingValues() {
     WriteSetting(QStringLiteral("dump_exefs"), Settings::values.dump_exefs, false);
     WriteSetting(QStringLiteral("dump_nso"), Settings::values.dump_nso, false);
     WriteSetting(QStringLiteral("quest_flag"), Settings::values.quest_flag, false);
-    WriteSetting(QStringLiteral("disable_cpu_opt"), Settings::values.disable_cpu_opt, false);
     WriteSetting(QStringLiteral("disable_macro_jit"), Settings::values.disable_macro_jit, false);
 
     qt_config->endGroup();
@@ -1097,6 +1121,29 @@ void Config::SavePathValues() {
     qt_config->endGroup();
 }
 
+void Config::SaveCpuValues() {
+    qt_config->beginGroup(QStringLiteral("Cpu"));
+
+    if (global) {
+        WriteSetting(QStringLiteral("cpuopt_page_tables"), Settings::values.cpuopt_page_tables,
+                     true);
+        WriteSetting(QStringLiteral("cpuopt_block_linking"), Settings::values.cpuopt_block_linking,
+                     true);
+        WriteSetting(QStringLiteral("cpuopt_return_stack_buffer"),
+                     Settings::values.cpuopt_return_stack_buffer, true);
+        WriteSetting(QStringLiteral("cpuopt_fast_dispatcher"),
+                     Settings::values.cpuopt_fast_dispatcher, true);
+        WriteSetting(QStringLiteral("cpuopt_context_elimination"),
+                     Settings::values.cpuopt_context_elimination, true);
+        WriteSetting(QStringLiteral("cpuopt_const_prop"), Settings::values.cpuopt_const_prop, true);
+        WriteSetting(QStringLiteral("cpuopt_misc_ir"), Settings::values.cpuopt_misc_ir, true);
+        WriteSetting(QStringLiteral("cpuopt_reduce_misalign_checks"),
+                     Settings::values.cpuopt_reduce_misalign_checks, true);
+    }
+
+    qt_config->endGroup();
+}
+
 void Config::SaveRendererValues() {
     qt_config->beginGroup(QStringLiteral("Renderer"));
 
diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h
index 681f0bca5..8e815f829 100644
--- a/src/yuzu/configuration/config.h
+++ b/src/yuzu/configuration/config.h
@@ -49,6 +49,7 @@ private:
     void ReadDisabledAddOnValues();
     void ReadMiscellaneousValues();
     void ReadPathValues();
+    void ReadCpuValues();
     void ReadRendererValues();
     void ReadShortcutValues();
     void ReadSystemValues();
@@ -73,6 +74,7 @@ private:
     void SaveDisabledAddOnValues();
     void SaveMiscellaneousValues();
     void SavePathValues();
+    void SaveCpuValues();
     void SaveRendererValues();
     void SaveShortcutValues();
     void SaveSystemValues();
diff --git a/src/yuzu/configuration/configure.ui b/src/yuzu/configuration/configure.ui
index 9aec1bd09..a23fd9435 100644
--- a/src/yuzu/configuration/configure.ui
+++ b/src/yuzu/configuration/configure.ui
@@ -78,6 +78,11 @@
          <string>Hotkeys</string>
         </attribute>
        </widget>
+       <widget class="ConfigureCpu" name="cpuTab">
+        <attribute name="title">
+         <string>CPU</string>
+        </attribute>
+       </widget>
        <widget class="ConfigureGraphics" name="graphicsTab">
         <attribute name="title">
          <string>Graphics</string>
@@ -158,6 +163,12 @@
    <header>configuration/configure_debug.h</header>
    <container>1</container>
   </customwidget>
+  <customwidget>
+   <class>ConfigureCpu</class>
+   <extends>QWidget</extends>
+   <header>configuration/configure_cpu.h</header>
+   <container>1</container>
+  </customwidget>
   <customwidget>
    <class>ConfigureGraphics</class>
    <extends>QWidget</extends>
diff --git a/src/yuzu/configuration/configure_cpu.cpp b/src/yuzu/configuration/configure_cpu.cpp
new file mode 100644
index 000000000..28e010b6b
--- /dev/null
+++ b/src/yuzu/configuration/configure_cpu.cpp
@@ -0,0 +1,64 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <QComboBox>
+
+#include "common/common_types.h"
+#include "common/logging/log.h"
+#include "core/core.h"
+#include "core/settings.h"
+#include "ui_configure_cpu.h"
+#include "yuzu/configuration/configure_cpu.h"
+
+ConfigureCpu::ConfigureCpu(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureCpu) {
+    ui->setupUi(this);
+
+    SetConfiguration();
+}
+
+ConfigureCpu::~ConfigureCpu() = default;
+
+void ConfigureCpu::SetConfiguration() {
+    const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
+
+    ui->cpuopt_page_tables->setEnabled(runtime_lock);
+    ui->cpuopt_page_tables->setChecked(Settings::values.cpuopt_page_tables);
+    ui->cpuopt_block_linking->setEnabled(runtime_lock);
+    ui->cpuopt_block_linking->setChecked(Settings::values.cpuopt_block_linking);
+    ui->cpuopt_return_stack_buffer->setEnabled(runtime_lock);
+    ui->cpuopt_return_stack_buffer->setChecked(Settings::values.cpuopt_return_stack_buffer);
+    ui->cpuopt_fast_dispatcher->setEnabled(runtime_lock);
+    ui->cpuopt_fast_dispatcher->setChecked(Settings::values.cpuopt_fast_dispatcher);
+    ui->cpuopt_context_elimination->setEnabled(runtime_lock);
+    ui->cpuopt_context_elimination->setChecked(Settings::values.cpuopt_context_elimination);
+    ui->cpuopt_const_prop->setEnabled(runtime_lock);
+    ui->cpuopt_const_prop->setChecked(Settings::values.cpuopt_const_prop);
+    ui->cpuopt_misc_ir->setEnabled(runtime_lock);
+    ui->cpuopt_misc_ir->setChecked(Settings::values.cpuopt_misc_ir);
+    ui->cpuopt_reduce_misalign_checks->setEnabled(runtime_lock);
+    ui->cpuopt_reduce_misalign_checks->setChecked(Settings::values.cpuopt_reduce_misalign_checks);
+}
+
+void ConfigureCpu::ApplyConfiguration() {
+    Settings::values.cpuopt_page_tables = ui->cpuopt_page_tables->isChecked();
+    Settings::values.cpuopt_block_linking = ui->cpuopt_block_linking->isChecked();
+    Settings::values.cpuopt_return_stack_buffer = ui->cpuopt_return_stack_buffer->isChecked();
+    Settings::values.cpuopt_fast_dispatcher = ui->cpuopt_fast_dispatcher->isChecked();
+    Settings::values.cpuopt_context_elimination = ui->cpuopt_context_elimination->isChecked();
+    Settings::values.cpuopt_const_prop = ui->cpuopt_const_prop->isChecked();
+    Settings::values.cpuopt_misc_ir = ui->cpuopt_misc_ir->isChecked();
+    Settings::values.cpuopt_reduce_misalign_checks = ui->cpuopt_reduce_misalign_checks->isChecked();
+}
+
+void ConfigureCpu::changeEvent(QEvent* event) {
+    if (event->type() == QEvent::LanguageChange) {
+        RetranslateUI();
+    }
+
+    QWidget::changeEvent(event);
+}
+
+void ConfigureCpu::RetranslateUI() {
+    ui->retranslateUi(this);
+}
diff --git a/src/yuzu/configuration/configure_cpu.h b/src/yuzu/configuration/configure_cpu.h
new file mode 100644
index 000000000..a4c6e5f20
--- /dev/null
+++ b/src/yuzu/configuration/configure_cpu.h
@@ -0,0 +1,31 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <QWidget>
+#include "core/settings.h"
+
+namespace Ui {
+class ConfigureCpu;
+}
+
+class ConfigureCpu : public QWidget {
+    Q_OBJECT
+
+public:
+    explicit ConfigureCpu(QWidget* parent = nullptr);
+    ~ConfigureCpu() override;
+
+    void ApplyConfiguration();
+
+private:
+    void changeEvent(QEvent* event) override;
+    void RetranslateUI();
+
+    void SetConfiguration();
+
+    std::unique_ptr<Ui::ConfigureCpu> ui;
+};
diff --git a/src/yuzu/configuration/configure_cpu.ui b/src/yuzu/configuration/configure_cpu.ui
new file mode 100644
index 000000000..d04cfb2d5
--- /dev/null
+++ b/src/yuzu/configuration/configure_cpu.ui
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ConfigureCpu</class>
+ <widget class="QWidget" name="ConfigureCpu">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>321</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout">
+   <item>
+    <layout class="QVBoxLayout">
+     <item>
+      <widget class="QGroupBox">
+       <property name="title">
+        <string>Safe CPU Optimizations</string>
+       </property>
+       <layout class="QVBoxLayout">
+        <item>
+         <widget class="QLabel">
+          <property name="wordWrap">
+            <bool>1</bool>
+          </property>
+          <property name="text">
+           <string>Keep these enabled. For debugging only.</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="cpuopt_page_tables">
+          <property name="text">
+           <string>Enable inline page tables</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="cpuopt_block_linking">
+          <property name="text">
+           <string>Enable block linking</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="cpuopt_return_stack_buffer">
+          <property name="text">
+           <string>Enable return stack buffer</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="cpuopt_fast_dispatcher">
+          <property name="text">
+           <string>Enable fast dispatcher</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="cpuopt_context_elimination">
+          <property name="text">
+           <string>Enable context elimination</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="cpuopt_const_prop">
+          <property name="text">
+           <string>Enable constant propagation</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="cpuopt_misc_ir">
+          <property name="text">
+           <string>Enable miscellaneous optimizations</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="cpuopt_reduce_misalign_checks">
+          <property name="text">
+           <string>Enable misalignment check reduction</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>40</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp
index 2c77441fd..d0e71dd60 100644
--- a/src/yuzu/configuration/configure_debug.cpp
+++ b/src/yuzu/configuration/configure_debug.cpp
@@ -36,7 +36,6 @@ void ConfigureDebug::SetConfiguration() {
     ui->homebrew_args_edit->setText(QString::fromStdString(Settings::values.program_args));
     ui->reporting_services->setChecked(Settings::values.reporting_services);
     ui->quest_flag->setChecked(Settings::values.quest_flag);
-    ui->disable_cpu_opt->setChecked(Settings::values.disable_cpu_opt);
     ui->enable_graphics_debugging->setEnabled(!Core::System::GetInstance().IsPoweredOn());
     ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug);
     ui->disable_macro_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn());
@@ -51,7 +50,6 @@ void ConfigureDebug::ApplyConfiguration() {
     Settings::values.program_args = ui->homebrew_args_edit->text().toStdString();
     Settings::values.reporting_services = ui->reporting_services->isChecked();
     Settings::values.quest_flag = ui->quest_flag->isChecked();
-    Settings::values.disable_cpu_opt = ui->disable_cpu_opt->isChecked();
     Settings::values.renderer_debug = ui->enable_graphics_debugging->isChecked();
     Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked();
     Debugger::ToggleConsole();
diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui
index 46f0208c6..272bdd6b8 100644
--- a/src/yuzu/configuration/configure_debug.ui
+++ b/src/yuzu/configuration/configure_debug.ui
@@ -228,13 +228,6 @@
         </property>
        </widget>
       </item>
-      <item>
-       <widget class="QCheckBox" name="disable_cpu_opt">
-        <property name="text">
-         <string>Disable CPU JIT optimizations</string>
-        </property>
-       </widget>
-      </item>
      </layout>
     </widget>
    </item>
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp
index 5918e9972..a0f49c282 100644
--- a/src/yuzu/configuration/configure_dialog.cpp
+++ b/src/yuzu/configuration/configure_dialog.cpp
@@ -42,6 +42,7 @@ void ConfigureDialog::ApplyConfiguration() {
     ui->filesystemTab->applyConfiguration();
     ui->inputTab->ApplyConfiguration();
     ui->hotkeysTab->ApplyConfiguration(registry);
+    ui->cpuTab->ApplyConfiguration();
     ui->graphicsTab->ApplyConfiguration();
     ui->graphicsAdvancedTab->ApplyConfiguration();
     ui->audioTab->ApplyConfiguration();
@@ -76,9 +77,10 @@ void ConfigureDialog::RetranslateUI() {
 Q_DECLARE_METATYPE(QList<QWidget*>);
 
 void ConfigureDialog::PopulateSelectionList() {
-    const std::array<std::pair<QString, QList<QWidget*>>, 5> items{
+    const std::array<std::pair<QString, QList<QWidget*>>, 6> items{
         {{tr("General"), {ui->generalTab, ui->webTab, ui->debugTab, ui->uiTab}},
          {tr("System"), {ui->systemTab, ui->profileManagerTab, ui->serviceTab, ui->filesystemTab}},
+         {tr("CPU"), {ui->cpuTab}},
          {tr("Graphics"), {ui->graphicsTab, ui->graphicsAdvancedTab}},
          {tr("Audio"), {ui->audioTab}},
          {tr("Controls"), {ui->inputTab, ui->hotkeysTab}}},
@@ -107,6 +109,7 @@ void ConfigureDialog::UpdateVisibleTabs() {
         {ui->profileManagerTab, tr("Profiles")},
         {ui->inputTab, tr("Input")},
         {ui->hotkeysTab, tr("Hotkeys")},
+        {ui->cpuTab, tr("CPU")},
         {ui->graphicsTab, tr("Graphics")},
         {ui->graphicsAdvancedTab, tr("Advanced")},
         {ui->audioTab, tr("Audio")},
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 23763144f..441d8e8f7 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -437,8 +437,6 @@ void Config::ReadValues() {
     Settings::values.reporting_services =
         sdl2_config->GetBoolean("Debugging", "reporting_services", false);
     Settings::values.quest_flag = sdl2_config->GetBoolean("Debugging", "quest_flag", false);
-    Settings::values.disable_cpu_opt =
-        sdl2_config->GetBoolean("Debugging", "disable_cpu_opt", false);
     Settings::values.disable_macro_jit =
         sdl2_config->GetBoolean("Debugging", "disable_macro_jit", false);
 
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index 45c07ed5d..5bed47fd7 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -97,6 +97,39 @@ udp_pad_index=
 # 0 (default): Disabled, 1: Enabled
 use_multi_core=
 
+[Cpu]
+# Enable inline page tables optimization (faster guest memory access)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_page_tables =
+
+# Enable block linking CPU optimization (reduce block dispatcher use during predictable jumps)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_block_linking =
+
+# Enable return stack buffer CPU optimization (reduce block dispatcher use during predictable returns)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_return_stack_buffer =
+
+# Enable fast dispatcher CPU optimization (use a two-tiered dispatcher architecture)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_fast_dispatcher =
+
+# Enable context elimination CPU Optimization (reduce host memory use for guest context)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_context_elimination =
+
+# Enable constant propagation CPU optimization (basic IR optimization)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_const_prop =
+
+# Enable miscellaneous CPU optimizations (basic IR optimization)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_misc_ir =
+
+# Enable reduction of memory misalignment checks (reduce memory fallbacks for misaligned access)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_reduce_misalign_checks =
+
 [Renderer]
 # Which backend API to use.
 # 0 (default): OpenGL, 1: Vulkan
@@ -283,9 +316,6 @@ dump_nso=false
 # Determines whether or not yuzu will report to the game that the emulated console is in Kiosk Mode
 # false: Retail/Normal Mode (default), true: Kiosk Mode
 quest_flag =
-# Determines whether or not JIT CPU optimizations are enabled
-# false: Optimizations Enabled, true: Optimizations Disabled
-disable_cpu_opt =
 # Enables/Disables the macro JIT compiler
 disable_macro_jit=false
 
diff --git a/src/yuzu_tester/default_ini.h b/src/yuzu_tester/default_ini.h
index 41bbbbf60..3eb64e9d7 100644
--- a/src/yuzu_tester/default_ini.h
+++ b/src/yuzu_tester/default_ini.h
@@ -12,6 +12,39 @@ const char* sdl2_config_file = R"(
 # 0 (default): Disabled, 1: Enabled
 use_multi_core=
 
+[Cpu]
+# Enable inline page tables optimization (faster guest memory access)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_page_tables =
+
+# Enable block linking CPU optimization (reduce block dispatcher use during predictable jumps)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_block_linking =
+
+# Enable return stack buffer CPU optimization (reduce block dispatcher use during predictable returns)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_return_stack_buffer =
+
+# Enable fast dispatcher CPU optimization (use a two-tiered dispatcher architecture)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_fast_dispatcher =
+
+# Enable context elimination CPU Optimization (reduce host memory use for guest context)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_context_elimination =
+
+# Enable constant propagation CPU optimization (basic IR optimization)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_const_prop =
+
+# Enable miscellaneous CPU optimizations (basic IR optimization)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_misc_ir =
+
+# Enable reduction of memory misalignment checks (reduce memory fallbacks for misaligned access)
+# 0: Disabled, 1 (default): Enabled
+cpuopt_reduce_misalign_checks =
+
 [Renderer]
 # Whether to use software or hardware rendering.
 # 0: Software, 1 (default): Hardware

From 505aa3a4c1eb2384ab5a46aecf6431db239b74e3 Mon Sep 17 00:00:00 2001
From: MerryMage <MerryMage@users.noreply.github.com>
Date: Sat, 11 Jul 2020 16:25:49 +0100
Subject: [PATCH 2/4] configure_cpu: Show/Hide debugging options

---
 src/core/arm/dynarmic/arm_dynarmic_32.cpp | 48 ++++++++++++-----------
 src/core/arm/dynarmic/arm_dynarmic_64.cpp | 48 ++++++++++++-----------
 src/core/settings.h                       |  7 ++++
 src/yuzu/configuration/config.cpp         |  6 +++
 src/yuzu/configuration/configure_cpu.cpp  | 22 +++++++++++
 src/yuzu/configuration/configure_cpu.h    |  2 +
 src/yuzu/configuration/configure_cpu.ui   | 48 +++++++++++++++++++++++
 7 files changed, 135 insertions(+), 46 deletions(-)

diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index 369a081cd..443ca72eb 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -143,29 +143,31 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable&
     config.wall_clock_cntpct = uses_wall_clock;
 
     // Safe optimizations
-    if (!Settings::values.cpuopt_page_tables) {
-        config.page_table = nullptr;
-    }
-    if (!Settings::values.cpuopt_block_linking) {
-        config.optimizations &= ~Dynarmic::OptimizationFlag::BlockLinking;
-    }
-    if (!Settings::values.cpuopt_return_stack_buffer) {
-        config.optimizations &= ~Dynarmic::OptimizationFlag::ReturnStackBuffer;
-    }
-    if (!Settings::values.cpuopt_fast_dispatcher) {
-        config.optimizations &= ~Dynarmic::OptimizationFlag::FastDispatch;
-    }
-    if (!Settings::values.cpuopt_context_elimination) {
-        config.optimizations &= ~Dynarmic::OptimizationFlag::GetSetElimination;
-    }
-    if (!Settings::values.cpuopt_const_prop) {
-        config.optimizations &= ~Dynarmic::OptimizationFlag::ConstProp;
-    }
-    if (!Settings::values.cpuopt_misc_ir) {
-        config.optimizations &= ~Dynarmic::OptimizationFlag::MiscIROpt;
-    }
-    if (!Settings::values.cpuopt_reduce_misalign_checks) {
-        config.only_detect_misalignment_via_page_table_on_page_boundary = false;
+    if (Settings::values.cpu_accuracy != Settings::CPUAccuracy::Accurate) {
+        if (!Settings::values.cpuopt_page_tables) {
+            config.page_table = nullptr;
+        }
+        if (!Settings::values.cpuopt_block_linking) {
+            config.optimizations &= ~Dynarmic::OptimizationFlag::BlockLinking;
+        }
+        if (!Settings::values.cpuopt_return_stack_buffer) {
+            config.optimizations &= ~Dynarmic::OptimizationFlag::ReturnStackBuffer;
+        }
+        if (!Settings::values.cpuopt_fast_dispatcher) {
+            config.optimizations &= ~Dynarmic::OptimizationFlag::FastDispatch;
+        }
+        if (!Settings::values.cpuopt_context_elimination) {
+            config.optimizations &= ~Dynarmic::OptimizationFlag::GetSetElimination;
+        }
+        if (!Settings::values.cpuopt_const_prop) {
+            config.optimizations &= ~Dynarmic::OptimizationFlag::ConstProp;
+        }
+        if (!Settings::values.cpuopt_misc_ir) {
+            config.optimizations &= ~Dynarmic::OptimizationFlag::MiscIROpt;
+        }
+        if (!Settings::values.cpuopt_reduce_misalign_checks) {
+            config.only_detect_misalignment_via_page_table_on_page_boundary = false;
+        }
     }
 
     return std::make_unique<Dynarmic::A32::Jit>(config);
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index e208a4aa7..a63a04a25 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -195,29 +195,31 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable&
     config.wall_clock_cntpct = uses_wall_clock;
 
     // Safe optimizations
-    if (!Settings::values.cpuopt_page_tables) {
-        config.page_table = nullptr;
-    }
-    if (!Settings::values.cpuopt_block_linking) {
-        config.optimizations &= ~Dynarmic::OptimizationFlag::BlockLinking;
-    }
-    if (!Settings::values.cpuopt_return_stack_buffer) {
-        config.optimizations &= ~Dynarmic::OptimizationFlag::ReturnStackBuffer;
-    }
-    if (!Settings::values.cpuopt_fast_dispatcher) {
-        config.optimizations &= ~Dynarmic::OptimizationFlag::FastDispatch;
-    }
-    if (!Settings::values.cpuopt_context_elimination) {
-        config.optimizations &= ~Dynarmic::OptimizationFlag::GetSetElimination;
-    }
-    if (!Settings::values.cpuopt_const_prop) {
-        config.optimizations &= ~Dynarmic::OptimizationFlag::ConstProp;
-    }
-    if (!Settings::values.cpuopt_misc_ir) {
-        config.optimizations &= ~Dynarmic::OptimizationFlag::MiscIROpt;
-    }
-    if (!Settings::values.cpuopt_reduce_misalign_checks) {
-        config.only_detect_misalignment_via_page_table_on_page_boundary = false;
+    if (Settings::values.cpu_accuracy != Settings::CPUAccuracy::Accurate) {
+        if (!Settings::values.cpuopt_page_tables) {
+            config.page_table = nullptr;
+        }
+        if (!Settings::values.cpuopt_block_linking) {
+            config.optimizations &= ~Dynarmic::OptimizationFlag::BlockLinking;
+        }
+        if (!Settings::values.cpuopt_return_stack_buffer) {
+            config.optimizations &= ~Dynarmic::OptimizationFlag::ReturnStackBuffer;
+        }
+        if (!Settings::values.cpuopt_fast_dispatcher) {
+            config.optimizations &= ~Dynarmic::OptimizationFlag::FastDispatch;
+        }
+        if (!Settings::values.cpuopt_context_elimination) {
+            config.optimizations &= ~Dynarmic::OptimizationFlag::GetSetElimination;
+        }
+        if (!Settings::values.cpuopt_const_prop) {
+            config.optimizations &= ~Dynarmic::OptimizationFlag::ConstProp;
+        }
+        if (!Settings::values.cpuopt_misc_ir) {
+            config.optimizations &= ~Dynarmic::OptimizationFlag::MiscIROpt;
+        }
+        if (!Settings::values.cpuopt_reduce_misalign_checks) {
+            config.only_detect_misalignment_via_page_table_on_page_boundary = false;
+        }
     }
 
     return std::make_shared<Dynarmic::A64::Jit>(config);
diff --git a/src/core/settings.h b/src/core/settings.h
index c081c083f..b3451a704 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -382,6 +382,11 @@ enum class GPUAccuracy : u32 {
     Extreme = 2,
 };
 
+enum class CPUAccuracy {
+    Accurate = 0,
+    DebugMode = 1,
+};
+
 extern bool configuring_global;
 
 template <typename Type>
@@ -428,6 +433,8 @@ struct Values {
     Setting<bool> use_multi_core;
 
     // Cpu
+    CPUAccuracy cpu_accuracy;
+
     bool cpuopt_page_tables;
     bool cpuopt_block_linking;
     bool cpuopt_return_stack_buffer;
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index f28e345a5..430e78e5f 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -635,6 +635,9 @@ void Config::ReadCpuValues() {
     qt_config->beginGroup(QStringLiteral("Cpu"));
 
     if (global) {
+        Settings::values.cpu_accuracy = static_cast<Settings::CPUAccuracy>(
+            ReadSetting(QStringLiteral("cpu_accuracy"), 0).toInt());
+
         Settings::values.cpuopt_page_tables =
             ReadSetting(QStringLiteral("cpuopt_page_tables"), true).toBool();
         Settings::values.cpuopt_block_linking =
@@ -1125,6 +1128,9 @@ void Config::SaveCpuValues() {
     qt_config->beginGroup(QStringLiteral("Cpu"));
 
     if (global) {
+        WriteSetting(QStringLiteral("cpu_accuracy"),
+                     static_cast<int>(Settings::values.cpu_accuracy), 0);
+
         WriteSetting(QStringLiteral("cpuopt_page_tables"), Settings::values.cpuopt_page_tables,
                      true);
         WriteSetting(QStringLiteral("cpuopt_block_linking"), Settings::values.cpuopt_block_linking,
diff --git a/src/yuzu/configuration/configure_cpu.cpp b/src/yuzu/configuration/configure_cpu.cpp
index 28e010b6b..4fc392a7e 100644
--- a/src/yuzu/configuration/configure_cpu.cpp
+++ b/src/yuzu/configuration/configure_cpu.cpp
@@ -15,6 +15,9 @@ ConfigureCpu::ConfigureCpu(QWidget* parent) : QWidget(parent), ui(new Ui::Config
     ui->setupUi(this);
 
     SetConfiguration();
+
+    connect(ui->accuracy, qOverload<int>(&QComboBox::currentIndexChanged), this,
+            &ConfigureCpu::UpdateGroups);
 }
 
 ConfigureCpu::~ConfigureCpu() = default;
@@ -22,6 +25,10 @@ ConfigureCpu::~ConfigureCpu() = default;
 void ConfigureCpu::SetConfiguration() {
     const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
 
+    ui->accuracy->setEnabled(runtime_lock);
+    ui->accuracy->setCurrentIndex(static_cast<int>(Settings::values.cpu_accuracy));
+    UpdateGroups(static_cast<int>(Settings::values.cpu_accuracy));
+
     ui->cpuopt_page_tables->setEnabled(runtime_lock);
     ui->cpuopt_page_tables->setChecked(Settings::values.cpuopt_page_tables);
     ui->cpuopt_block_linking->setEnabled(runtime_lock);
@@ -40,7 +47,22 @@ void ConfigureCpu::SetConfiguration() {
     ui->cpuopt_reduce_misalign_checks->setChecked(Settings::values.cpuopt_reduce_misalign_checks);
 }
 
+void ConfigureCpu::UpdateGroups(int index) {
+    switch (index) {
+    case 0:
+    default:
+        ui->group_safe->setVisible(false);
+        break;
+    case 1:
+        ui->group_safe->setVisible(true);
+        break;
+    }
+}
+
 void ConfigureCpu::ApplyConfiguration() {
+    Settings::values.cpu_accuracy =
+        static_cast<Settings::CPUAccuracy>(ui->accuracy->currentIndex());
+
     Settings::values.cpuopt_page_tables = ui->cpuopt_page_tables->isChecked();
     Settings::values.cpuopt_block_linking = ui->cpuopt_block_linking->isChecked();
     Settings::values.cpuopt_return_stack_buffer = ui->cpuopt_return_stack_buffer->isChecked();
diff --git a/src/yuzu/configuration/configure_cpu.h b/src/yuzu/configuration/configure_cpu.h
index a4c6e5f20..cf55980b0 100644
--- a/src/yuzu/configuration/configure_cpu.h
+++ b/src/yuzu/configuration/configure_cpu.h
@@ -25,6 +25,8 @@ private:
     void changeEvent(QEvent* event) override;
     void RetranslateUI();
 
+    void UpdateGroups(int index);
+
     void SetConfiguration();
 
     std::unique_ptr<Ui::ConfigureCpu> ui;
diff --git a/src/yuzu/configuration/configure_cpu.ui b/src/yuzu/configuration/configure_cpu.ui
index d04cfb2d5..27bd4aa42 100644
--- a/src/yuzu/configuration/configure_cpu.ui
+++ b/src/yuzu/configuration/configure_cpu.ui
@@ -18,6 +18,54 @@
     <layout class="QVBoxLayout">
      <item>
       <widget class="QGroupBox">
+       <property name="title">
+        <string>General</string>
+       </property>
+       <layout class="QVBoxLayout">
+        <item>
+         <layout class="QHBoxLayout">
+          <item>
+           <widget class="QLabel">
+            <property name="text">
+             <string>Accuracy:</string>
+            </property>
+           </widget>
+          </item>
+          <item>
+           <widget class="QComboBox" name="accuracy">
+            <item>
+             <property name="text">
+              <string>Accurate</string>
+             </property>
+            </item>
+            <item>
+             <property name="text">
+              <string>Debugging Mode (Debugging ONLY)</string>
+             </property>
+            </item>
+           </widget>
+          </item>
+         </layout>
+        </item>
+        <item>
+         <widget class="QLabel">
+          <property name="wordWrap">
+            <bool>1</bool>
+          </property>
+          <property name="text">
+           <string>We recommend setting accuracy to "Accurate".</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <layout class="QVBoxLayout">
+     <item>
+      <widget class="QGroupBox" name="group_safe">
        <property name="title">
         <string>Safe CPU Optimizations</string>
        </property>

From da11a27f42f25a7f24c0b7cece8e499f34880fc8 Mon Sep 17 00:00:00 2001
From: MerryMage <MerryMage@users.noreply.github.com>
Date: Sat, 11 Jul 2020 16:26:06 +0100
Subject: [PATCH 3/4] configure_cpu: Add tooltips

---
 src/yuzu/configuration/configure_cpu.ui | 55 ++++++++++++++++++++++++-
 1 file changed, 54 insertions(+), 1 deletion(-)

diff --git a/src/yuzu/configuration/configure_cpu.ui b/src/yuzu/configuration/configure_cpu.ui
index 27bd4aa42..308e70356 100644
--- a/src/yuzu/configuration/configure_cpu.ui
+++ b/src/yuzu/configuration/configure_cpu.ui
@@ -76,7 +76,7 @@
             <bool>1</bool>
           </property>
           <property name="text">
-           <string>Keep these enabled. For debugging only.</string>
+           <string>Keep all of these enabled. For debugging only.</string>
           </property>
          </widget>
         </item>
@@ -85,6 +85,13 @@
           <property name="text">
            <string>Enable inline page tables</string>
           </property>
+          <property name="toolTip">
+           <string>
+            &lt;div style="white-space: nowrap"&gt;This optimization speeds up memory accesses by the guest program.&lt;/div&gt;
+            &lt;div style="white-space: nowrap"&gt;Enabling it inlines accesses to PageTable::pointers into emitted code.&lt;/div&gt;
+            &lt;div style="white-space: nowrap"&gt;Disabling this forces all memory accesses to go through the Memory::Read/Memory::Write functions.&lt;/div&gt;
+           </string>
+          </property>
          </widget>
         </item>
         <item>
@@ -92,6 +99,11 @@
           <property name="text">
            <string>Enable block linking</string>
           </property>
+          <property name="toolTip">
+           <string>
+            &lt;div&gt;This optimization avoids dispatcher lookups by allowing emitted basic blocks to jump directly to other basic blocks if the destination PC is static.&lt;/div&gt;
+           </string>
+          </property>
          </widget>
         </item>
         <item>
@@ -99,6 +111,11 @@
           <property name="text">
            <string>Enable return stack buffer</string>
           </property>
+          <property name="toolTip">
+           <string>
+            &lt;div&gt;This optimization avoids dispatcher lookups by keeping track potential return addresses of BL instructions. This approximates what happens with a return stack buffer on a real CPU.&lt;/div&gt;
+           </string>
+          </property>
          </widget>
         </item>
         <item>
@@ -106,6 +123,11 @@
           <property name="text">
            <string>Enable fast dispatcher</string>
           </property>
+          <property name="toolTip">
+           <string>
+            &lt;div&gt;Enable a two-tiered dispatch system. A faster dispatcher written in assembly has a small MRU cache of jump destinations is used first. If that fails, dispatch falls back to the slower C++ dispatcher.&lt;/div&gt;
+           </string>
+          </property>
          </widget>
         </item>
         <item>
@@ -113,6 +135,11 @@
           <property name="text">
            <string>Enable context elimination</string>
           </property>
+          <property name="toolTip">
+           <string>
+            &lt;div&gt;Enables an IR optimization that reduces unnecessary accesses to the CPU context structure.&lt;/div&gt;
+           </string>
+          </property>
          </widget>
         </item>
         <item>
@@ -120,6 +147,11 @@
           <property name="text">
            <string>Enable constant propagation</string>
           </property>
+          <property name="toolTip">
+           <string>
+            &lt;div&gt;Enables IR optimizations that involve constant propagation.&lt;/div&gt;
+           </string>
+          </property>
          </widget>
         </item>
         <item>
@@ -127,6 +159,11 @@
           <property name="text">
            <string>Enable miscellaneous optimizations</string>
           </property>
+          <property name="toolTip">
+           <string>
+            &lt;div&gt;Enables miscellaneous IR optimizations.&lt;/div&gt;
+           </string>
+          </property>
          </widget>
         </item>
         <item>
@@ -134,6 +171,12 @@
           <property name="text">
            <string>Enable misalignment check reduction</string>
           </property>
+          <property name="toolTip">
+           <string>
+            &lt;div style="white-space: nowrap"&gt;When enabled, a misalignment is only triggered when an access crosses a page boundary.&lt;/div&gt;
+            &lt;div style="white-space: nowrap"&gt;When disabled, a misalignment is triggered on all misaligned accesses.&lt;/div&gt;
+           </string>
+          </property>
          </widget>
         </item>
        </layout>
@@ -154,6 +197,16 @@
      </property>
     </spacer>
    </item>
+   <item>
+    <widget class="QLabel" name="label_disable_info">
+     <property name="text">
+      <string>CPU settings are available only when game is not running.</string>
+     </property>
+     <property name="wordWrap">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
   </layout>
  </widget>
  <resources/>

From a67d00ef31aba1c45dde956b48844f91427963a1 Mon Sep 17 00:00:00 2001
From: MerryMage <MerryMage@users.noreply.github.com>
Date: Sun, 12 Jul 2020 12:06:04 +0100
Subject: [PATCH 4/4] configure_cpu: Split optimization settings off into Debug
 tab

---
 src/yuzu/CMakeLists.txt                       |   3 +
 src/yuzu/configuration/configure.ui           |  11 ++
 src/yuzu/configuration/configure_cpu.cpp      |  51 ++---
 src/yuzu/configuration/configure_cpu.h        |   2 +-
 src/yuzu/configuration/configure_cpu.ui       | 124 +------------
 .../configuration/configure_cpu_debug.cpp     |  65 +++++++
 src/yuzu/configuration/configure_cpu_debug.h  |  31 ++++
 src/yuzu/configuration/configure_cpu_debug.ui | 174 ++++++++++++++++++
 src/yuzu/configuration/configure_dialog.cpp   |   4 +-
 9 files changed, 302 insertions(+), 163 deletions(-)
 create mode 100644 src/yuzu/configuration/configure_cpu_debug.cpp
 create mode 100644 src/yuzu/configuration/configure_cpu_debug.h
 create mode 100644 src/yuzu/configuration/configure_cpu_debug.ui

diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 39efa962b..5f175b989 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -33,6 +33,9 @@ add_executable(yuzu
     configuration/configure_cpu.cpp
     configuration/configure_cpu.h
     configuration/configure_cpu.ui
+    configuration/configure_cpu_debug.cpp
+    configuration/configure_cpu_debug.h
+    configuration/configure_cpu_debug.ui
     configuration/configure_debug.cpp
     configuration/configure_debug.h
     configuration/configure_debug.ui
diff --git a/src/yuzu/configuration/configure.ui b/src/yuzu/configuration/configure.ui
index a23fd9435..5f5d8e571 100644
--- a/src/yuzu/configuration/configure.ui
+++ b/src/yuzu/configuration/configure.ui
@@ -83,6 +83,11 @@
          <string>CPU</string>
         </attribute>
        </widget>
+       <widget class="ConfigureCpuDebug" name="cpuDebugTab">
+        <attribute name="title">
+         <string>Debug</string>
+        </attribute>
+       </widget>
        <widget class="ConfigureGraphics" name="graphicsTab">
         <attribute name="title">
          <string>Graphics</string>
@@ -169,6 +174,12 @@
    <header>configuration/configure_cpu.h</header>
    <container>1</container>
   </customwidget>
+  <customwidget>
+   <class>ConfigureCpuDebug</class>
+   <extends>QWidget</extends>
+   <header>configuration/configure_cpu_debug.h</header>
+   <container>1</container>
+  </customwidget>
   <customwidget>
    <class>ConfigureGraphics</class>
    <extends>QWidget</extends>
diff --git a/src/yuzu/configuration/configure_cpu.cpp b/src/yuzu/configuration/configure_cpu.cpp
index 4fc392a7e..7493e5ffb 100644
--- a/src/yuzu/configuration/configure_cpu.cpp
+++ b/src/yuzu/configuration/configure_cpu.cpp
@@ -3,6 +3,7 @@
 // Refer to the license.txt file included.
 
 #include <QComboBox>
+#include <QMessageBox>
 
 #include "common/common_types.h"
 #include "common/logging/log.h"
@@ -16,8 +17,8 @@ ConfigureCpu::ConfigureCpu(QWidget* parent) : QWidget(parent), ui(new Ui::Config
 
     SetConfiguration();
 
-    connect(ui->accuracy, qOverload<int>(&QComboBox::currentIndexChanged), this,
-            &ConfigureCpu::UpdateGroups);
+    connect(ui->accuracy, qOverload<int>(&QComboBox::activated), this,
+            &ConfigureCpu::AccuracyUpdated);
 }
 
 ConfigureCpu::~ConfigureCpu() = default;
@@ -27,50 +28,24 @@ void ConfigureCpu::SetConfiguration() {
 
     ui->accuracy->setEnabled(runtime_lock);
     ui->accuracy->setCurrentIndex(static_cast<int>(Settings::values.cpu_accuracy));
-    UpdateGroups(static_cast<int>(Settings::values.cpu_accuracy));
-
-    ui->cpuopt_page_tables->setEnabled(runtime_lock);
-    ui->cpuopt_page_tables->setChecked(Settings::values.cpuopt_page_tables);
-    ui->cpuopt_block_linking->setEnabled(runtime_lock);
-    ui->cpuopt_block_linking->setChecked(Settings::values.cpuopt_block_linking);
-    ui->cpuopt_return_stack_buffer->setEnabled(runtime_lock);
-    ui->cpuopt_return_stack_buffer->setChecked(Settings::values.cpuopt_return_stack_buffer);
-    ui->cpuopt_fast_dispatcher->setEnabled(runtime_lock);
-    ui->cpuopt_fast_dispatcher->setChecked(Settings::values.cpuopt_fast_dispatcher);
-    ui->cpuopt_context_elimination->setEnabled(runtime_lock);
-    ui->cpuopt_context_elimination->setChecked(Settings::values.cpuopt_context_elimination);
-    ui->cpuopt_const_prop->setEnabled(runtime_lock);
-    ui->cpuopt_const_prop->setChecked(Settings::values.cpuopt_const_prop);
-    ui->cpuopt_misc_ir->setEnabled(runtime_lock);
-    ui->cpuopt_misc_ir->setChecked(Settings::values.cpuopt_misc_ir);
-    ui->cpuopt_reduce_misalign_checks->setEnabled(runtime_lock);
-    ui->cpuopt_reduce_misalign_checks->setChecked(Settings::values.cpuopt_reduce_misalign_checks);
 }
 
-void ConfigureCpu::UpdateGroups(int index) {
-    switch (index) {
-    case 0:
-    default:
-        ui->group_safe->setVisible(false);
-        break;
-    case 1:
-        ui->group_safe->setVisible(true);
-        break;
+void ConfigureCpu::AccuracyUpdated(int index) {
+    if (static_cast<Settings::CPUAccuracy>(index) == Settings::CPUAccuracy::DebugMode) {
+        const auto result = QMessageBox::warning(this, tr("Setting CPU to Debug Mode"),
+                                                 tr("CPU Debug Mode is only intended for developer "
+                                                    "use. Are you sure you want to enable this?"),
+                                                 QMessageBox::Yes | QMessageBox::No);
+        if (result == QMessageBox::No) {
+            ui->accuracy->setCurrentIndex(static_cast<int>(Settings::CPUAccuracy::Accurate));
+            return;
+        }
     }
 }
 
 void ConfigureCpu::ApplyConfiguration() {
     Settings::values.cpu_accuracy =
         static_cast<Settings::CPUAccuracy>(ui->accuracy->currentIndex());
-
-    Settings::values.cpuopt_page_tables = ui->cpuopt_page_tables->isChecked();
-    Settings::values.cpuopt_block_linking = ui->cpuopt_block_linking->isChecked();
-    Settings::values.cpuopt_return_stack_buffer = ui->cpuopt_return_stack_buffer->isChecked();
-    Settings::values.cpuopt_fast_dispatcher = ui->cpuopt_fast_dispatcher->isChecked();
-    Settings::values.cpuopt_context_elimination = ui->cpuopt_context_elimination->isChecked();
-    Settings::values.cpuopt_const_prop = ui->cpuopt_const_prop->isChecked();
-    Settings::values.cpuopt_misc_ir = ui->cpuopt_misc_ir->isChecked();
-    Settings::values.cpuopt_reduce_misalign_checks = ui->cpuopt_reduce_misalign_checks->isChecked();
 }
 
 void ConfigureCpu::changeEvent(QEvent* event) {
diff --git a/src/yuzu/configuration/configure_cpu.h b/src/yuzu/configuration/configure_cpu.h
index cf55980b0..e4741d3a4 100644
--- a/src/yuzu/configuration/configure_cpu.h
+++ b/src/yuzu/configuration/configure_cpu.h
@@ -25,7 +25,7 @@ private:
     void changeEvent(QEvent* event) override;
     void RetranslateUI();
 
-    void UpdateGroups(int index);
+    void AccuracyUpdated(int index);
 
     void SetConfiguration();
 
diff --git a/src/yuzu/configuration/configure_cpu.ui b/src/yuzu/configuration/configure_cpu.ui
index 308e70356..bf6ea79bb 100644
--- a/src/yuzu/configuration/configure_cpu.ui
+++ b/src/yuzu/configuration/configure_cpu.ui
@@ -40,7 +40,7 @@
             </item>
             <item>
              <property name="text">
-              <string>Debugging Mode (Debugging ONLY)</string>
+              <string>Enable Debug Mode</string>
              </property>
             </item>
            </widget>
@@ -62,128 +62,6 @@
      </item>
     </layout>
    </item>
-   <item>
-    <layout class="QVBoxLayout">
-     <item>
-      <widget class="QGroupBox" name="group_safe">
-       <property name="title">
-        <string>Safe CPU Optimizations</string>
-       </property>
-       <layout class="QVBoxLayout">
-        <item>
-         <widget class="QLabel">
-          <property name="wordWrap">
-            <bool>1</bool>
-          </property>
-          <property name="text">
-           <string>Keep all of these enabled. For debugging only.</string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QCheckBox" name="cpuopt_page_tables">
-          <property name="text">
-           <string>Enable inline page tables</string>
-          </property>
-          <property name="toolTip">
-           <string>
-            &lt;div style="white-space: nowrap"&gt;This optimization speeds up memory accesses by the guest program.&lt;/div&gt;
-            &lt;div style="white-space: nowrap"&gt;Enabling it inlines accesses to PageTable::pointers into emitted code.&lt;/div&gt;
-            &lt;div style="white-space: nowrap"&gt;Disabling this forces all memory accesses to go through the Memory::Read/Memory::Write functions.&lt;/div&gt;
-           </string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QCheckBox" name="cpuopt_block_linking">
-          <property name="text">
-           <string>Enable block linking</string>
-          </property>
-          <property name="toolTip">
-           <string>
-            &lt;div&gt;This optimization avoids dispatcher lookups by allowing emitted basic blocks to jump directly to other basic blocks if the destination PC is static.&lt;/div&gt;
-           </string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QCheckBox" name="cpuopt_return_stack_buffer">
-          <property name="text">
-           <string>Enable return stack buffer</string>
-          </property>
-          <property name="toolTip">
-           <string>
-            &lt;div&gt;This optimization avoids dispatcher lookups by keeping track potential return addresses of BL instructions. This approximates what happens with a return stack buffer on a real CPU.&lt;/div&gt;
-           </string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QCheckBox" name="cpuopt_fast_dispatcher">
-          <property name="text">
-           <string>Enable fast dispatcher</string>
-          </property>
-          <property name="toolTip">
-           <string>
-            &lt;div&gt;Enable a two-tiered dispatch system. A faster dispatcher written in assembly has a small MRU cache of jump destinations is used first. If that fails, dispatch falls back to the slower C++ dispatcher.&lt;/div&gt;
-           </string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QCheckBox" name="cpuopt_context_elimination">
-          <property name="text">
-           <string>Enable context elimination</string>
-          </property>
-          <property name="toolTip">
-           <string>
-            &lt;div&gt;Enables an IR optimization that reduces unnecessary accesses to the CPU context structure.&lt;/div&gt;
-           </string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QCheckBox" name="cpuopt_const_prop">
-          <property name="text">
-           <string>Enable constant propagation</string>
-          </property>
-          <property name="toolTip">
-           <string>
-            &lt;div&gt;Enables IR optimizations that involve constant propagation.&lt;/div&gt;
-           </string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QCheckBox" name="cpuopt_misc_ir">
-          <property name="text">
-           <string>Enable miscellaneous optimizations</string>
-          </property>
-          <property name="toolTip">
-           <string>
-            &lt;div&gt;Enables miscellaneous IR optimizations.&lt;/div&gt;
-           </string>
-          </property>
-         </widget>
-        </item>
-        <item>
-         <widget class="QCheckBox" name="cpuopt_reduce_misalign_checks">
-          <property name="text">
-           <string>Enable misalignment check reduction</string>
-          </property>
-          <property name="toolTip">
-           <string>
-            &lt;div style="white-space: nowrap"&gt;When enabled, a misalignment is only triggered when an access crosses a page boundary.&lt;/div&gt;
-            &lt;div style="white-space: nowrap"&gt;When disabled, a misalignment is triggered on all misaligned accesses.&lt;/div&gt;
-           </string>
-          </property>
-         </widget>
-        </item>
-       </layout>
-      </widget>
-     </item>
-    </layout>
-   </item>
    <item>
     <spacer name="verticalSpacer">
      <property name="orientation">
diff --git a/src/yuzu/configuration/configure_cpu_debug.cpp b/src/yuzu/configuration/configure_cpu_debug.cpp
new file mode 100644
index 000000000..3385b2cf6
--- /dev/null
+++ b/src/yuzu/configuration/configure_cpu_debug.cpp
@@ -0,0 +1,65 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <QComboBox>
+
+#include "common/common_types.h"
+#include "common/logging/log.h"
+#include "core/core.h"
+#include "core/settings.h"
+#include "ui_configure_cpu_debug.h"
+#include "yuzu/configuration/configure_cpu_debug.h"
+
+ConfigureCpuDebug::ConfigureCpuDebug(QWidget* parent)
+    : QWidget(parent), ui(new Ui::ConfigureCpuDebug) {
+    ui->setupUi(this);
+
+    SetConfiguration();
+}
+
+ConfigureCpuDebug::~ConfigureCpuDebug() = default;
+
+void ConfigureCpuDebug::SetConfiguration() {
+    const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
+
+    ui->cpuopt_page_tables->setEnabled(runtime_lock);
+    ui->cpuopt_page_tables->setChecked(Settings::values.cpuopt_page_tables);
+    ui->cpuopt_block_linking->setEnabled(runtime_lock);
+    ui->cpuopt_block_linking->setChecked(Settings::values.cpuopt_block_linking);
+    ui->cpuopt_return_stack_buffer->setEnabled(runtime_lock);
+    ui->cpuopt_return_stack_buffer->setChecked(Settings::values.cpuopt_return_stack_buffer);
+    ui->cpuopt_fast_dispatcher->setEnabled(runtime_lock);
+    ui->cpuopt_fast_dispatcher->setChecked(Settings::values.cpuopt_fast_dispatcher);
+    ui->cpuopt_context_elimination->setEnabled(runtime_lock);
+    ui->cpuopt_context_elimination->setChecked(Settings::values.cpuopt_context_elimination);
+    ui->cpuopt_const_prop->setEnabled(runtime_lock);
+    ui->cpuopt_const_prop->setChecked(Settings::values.cpuopt_const_prop);
+    ui->cpuopt_misc_ir->setEnabled(runtime_lock);
+    ui->cpuopt_misc_ir->setChecked(Settings::values.cpuopt_misc_ir);
+    ui->cpuopt_reduce_misalign_checks->setEnabled(runtime_lock);
+    ui->cpuopt_reduce_misalign_checks->setChecked(Settings::values.cpuopt_reduce_misalign_checks);
+}
+
+void ConfigureCpuDebug::ApplyConfiguration() {
+    Settings::values.cpuopt_page_tables = ui->cpuopt_page_tables->isChecked();
+    Settings::values.cpuopt_block_linking = ui->cpuopt_block_linking->isChecked();
+    Settings::values.cpuopt_return_stack_buffer = ui->cpuopt_return_stack_buffer->isChecked();
+    Settings::values.cpuopt_fast_dispatcher = ui->cpuopt_fast_dispatcher->isChecked();
+    Settings::values.cpuopt_context_elimination = ui->cpuopt_context_elimination->isChecked();
+    Settings::values.cpuopt_const_prop = ui->cpuopt_const_prop->isChecked();
+    Settings::values.cpuopt_misc_ir = ui->cpuopt_misc_ir->isChecked();
+    Settings::values.cpuopt_reduce_misalign_checks = ui->cpuopt_reduce_misalign_checks->isChecked();
+}
+
+void ConfigureCpuDebug::changeEvent(QEvent* event) {
+    if (event->type() == QEvent::LanguageChange) {
+        RetranslateUI();
+    }
+
+    QWidget::changeEvent(event);
+}
+
+void ConfigureCpuDebug::RetranslateUI() {
+    ui->retranslateUi(this);
+}
diff --git a/src/yuzu/configuration/configure_cpu_debug.h b/src/yuzu/configuration/configure_cpu_debug.h
new file mode 100644
index 000000000..c9941ef3b
--- /dev/null
+++ b/src/yuzu/configuration/configure_cpu_debug.h
@@ -0,0 +1,31 @@
+// Copyright 2020 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <QWidget>
+#include "core/settings.h"
+
+namespace Ui {
+class ConfigureCpuDebug;
+}
+
+class ConfigureCpuDebug : public QWidget {
+    Q_OBJECT
+
+public:
+    explicit ConfigureCpuDebug(QWidget* parent = nullptr);
+    ~ConfigureCpuDebug() override;
+
+    void ApplyConfiguration();
+
+private:
+    void changeEvent(QEvent* event) override;
+    void RetranslateUI();
+
+    void SetConfiguration();
+
+    std::unique_ptr<Ui::ConfigureCpuDebug> ui;
+};
diff --git a/src/yuzu/configuration/configure_cpu_debug.ui b/src/yuzu/configuration/configure_cpu_debug.ui
new file mode 100644
index 000000000..a90dc64fe
--- /dev/null
+++ b/src/yuzu/configuration/configure_cpu_debug.ui
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ConfigureCpuDebug</class>
+ <widget class="QWidget" name="ConfigureCpuDebug">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>321</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Form</string>
+  </property>
+  <layout class="QVBoxLayout">
+   <item>
+    <layout class="QVBoxLayout">
+     <item>
+      <widget class="QGroupBox">
+       <property name="title">
+        <string>Toggle CPU Optimizations</string>
+       </property>
+       <layout class="QVBoxLayout">
+        <item>
+         <widget class="QLabel">
+          <property name="wordWrap">
+            <bool>1</bool>
+          </property>
+          <property name="text">
+           <string>
+            &lt;div&gt;
+            &lt;b&gt;For debugging only.&lt;/b&gt;
+            &lt;br&gt;
+            If you're not sure what these do, keep all of these enabled.
+            &lt;br&gt;
+            These settings only take effect when CPU Accuracy is "Debug Mode".
+            &lt;/div&gt;
+           </string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="cpuopt_page_tables">
+          <property name="text">
+           <string>Enable inline page tables</string>
+          </property>
+          <property name="toolTip">
+           <string>
+            &lt;div style="white-space: nowrap"&gt;This optimization speeds up memory accesses by the guest program.&lt;/div&gt;
+            &lt;div style="white-space: nowrap"&gt;Enabling it inlines accesses to PageTable::pointers into emitted code.&lt;/div&gt;
+            &lt;div style="white-space: nowrap"&gt;Disabling this forces all memory accesses to go through the Memory::Read/Memory::Write functions.&lt;/div&gt;
+           </string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="cpuopt_block_linking">
+          <property name="text">
+           <string>Enable block linking</string>
+          </property>
+          <property name="toolTip">
+           <string>
+            &lt;div&gt;This optimization avoids dispatcher lookups by allowing emitted basic blocks to jump directly to other basic blocks if the destination PC is static.&lt;/div&gt;
+           </string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="cpuopt_return_stack_buffer">
+          <property name="text">
+           <string>Enable return stack buffer</string>
+          </property>
+          <property name="toolTip">
+           <string>
+            &lt;div&gt;This optimization avoids dispatcher lookups by keeping track potential return addresses of BL instructions. This approximates what happens with a return stack buffer on a real CPU.&lt;/div&gt;
+           </string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="cpuopt_fast_dispatcher">
+          <property name="text">
+           <string>Enable fast dispatcher</string>
+          </property>
+          <property name="toolTip">
+           <string>
+            &lt;div&gt;Enable a two-tiered dispatch system. A faster dispatcher written in assembly has a small MRU cache of jump destinations is used first. If that fails, dispatch falls back to the slower C++ dispatcher.&lt;/div&gt;
+           </string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="cpuopt_context_elimination">
+          <property name="text">
+           <string>Enable context elimination</string>
+          </property>
+          <property name="toolTip">
+           <string>
+            &lt;div&gt;Enables an IR optimization that reduces unnecessary accesses to the CPU context structure.&lt;/div&gt;
+           </string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="cpuopt_const_prop">
+          <property name="text">
+           <string>Enable constant propagation</string>
+          </property>
+          <property name="toolTip">
+           <string>
+            &lt;div&gt;Enables IR optimizations that involve constant propagation.&lt;/div&gt;
+           </string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="cpuopt_misc_ir">
+          <property name="text">
+           <string>Enable miscellaneous optimizations</string>
+          </property>
+          <property name="toolTip">
+           <string>
+            &lt;div&gt;Enables miscellaneous IR optimizations.&lt;/div&gt;
+           </string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QCheckBox" name="cpuopt_reduce_misalign_checks">
+          <property name="text">
+           <string>Enable misalignment check reduction</string>
+          </property>
+          <property name="toolTip">
+           <string>
+            &lt;div style="white-space: nowrap"&gt;When enabled, a misalignment is only triggered when an access crosses a page boundary.&lt;/div&gt;
+            &lt;div style="white-space: nowrap"&gt;When disabled, a misalignment is triggered on all misaligned accesses.&lt;/div&gt;
+           </string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </widget>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <spacer name="verticalSpacer">
+     <property name="orientation">
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>20</width>
+       <height>40</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item>
+    <widget class="QLabel" name="label_disable_info">
+     <property name="text">
+      <string>CPU settings are available only when game is not running.</string>
+     </property>
+     <property name="wordWrap">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp
index a0f49c282..a5afb354f 100644
--- a/src/yuzu/configuration/configure_dialog.cpp
+++ b/src/yuzu/configuration/configure_dialog.cpp
@@ -43,6 +43,7 @@ void ConfigureDialog::ApplyConfiguration() {
     ui->inputTab->ApplyConfiguration();
     ui->hotkeysTab->ApplyConfiguration(registry);
     ui->cpuTab->ApplyConfiguration();
+    ui->cpuDebugTab->ApplyConfiguration();
     ui->graphicsTab->ApplyConfiguration();
     ui->graphicsAdvancedTab->ApplyConfiguration();
     ui->audioTab->ApplyConfiguration();
@@ -80,7 +81,7 @@ void ConfigureDialog::PopulateSelectionList() {
     const std::array<std::pair<QString, QList<QWidget*>>, 6> items{
         {{tr("General"), {ui->generalTab, ui->webTab, ui->debugTab, ui->uiTab}},
          {tr("System"), {ui->systemTab, ui->profileManagerTab, ui->serviceTab, ui->filesystemTab}},
-         {tr("CPU"), {ui->cpuTab}},
+         {tr("CPU"), {ui->cpuTab, ui->cpuDebugTab}},
          {tr("Graphics"), {ui->graphicsTab, ui->graphicsAdvancedTab}},
          {tr("Audio"), {ui->audioTab}},
          {tr("Controls"), {ui->inputTab, ui->hotkeysTab}}},
@@ -110,6 +111,7 @@ void ConfigureDialog::UpdateVisibleTabs() {
         {ui->inputTab, tr("Input")},
         {ui->hotkeysTab, tr("Hotkeys")},
         {ui->cpuTab, tr("CPU")},
+        {ui->cpuDebugTab, tr("Debug")},
         {ui->graphicsTab, tr("Graphics")},
         {ui->graphicsAdvancedTab, tr("Advanced")},
         {ui->audioTab, tr("Audio")},