summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
m---------externals/dynarmic0
-rw-r--r--src/common/settings.cpp1
-rw-r--r--src/common/settings.h3
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp12
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp13
-rw-r--r--src/core/arm/dynarmic/arm_exclusive_monitor.cpp4
-rw-r--r--src/core/arm/dynarmic/arm_exclusive_monitor.h2
-rw-r--r--src/core/arm/exclusive_monitor.h2
-rw-r--r--src/core/hle/kernel/k_address_arbiter.cpp4
-rw-r--r--src/yuzu/configuration/config.cpp4
-rw-r--r--src/yuzu/configuration/configure_cpu.cpp9
-rw-r--r--src/yuzu/configuration/configure_cpu.h1
-rw-r--r--src/yuzu/configuration/configure_cpu.ui12
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.cpp8
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.ui29
-rw-r--r--src/yuzu_cmd/config.cpp3
-rw-r--r--src/yuzu_cmd/default_ini.h13
17 files changed, 113 insertions, 7 deletions
diff --git a/externals/dynarmic b/externals/dynarmic
Subproject 19a423034e1abcaf1a61fa61ceffffebf45a024 Subproject 0fd32c5fa4a57738b0b390a597257b4be39a7a9
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index 2810cec15..877e0faa4 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -176,6 +176,7 @@ void RestoreGlobalState(bool is_powered_on) {
176 values.cpuopt_unsafe_ignore_standard_fpcr.SetGlobal(true); 176 values.cpuopt_unsafe_ignore_standard_fpcr.SetGlobal(true);
177 values.cpuopt_unsafe_inaccurate_nan.SetGlobal(true); 177 values.cpuopt_unsafe_inaccurate_nan.SetGlobal(true);
178 values.cpuopt_unsafe_fastmem_check.SetGlobal(true); 178 values.cpuopt_unsafe_fastmem_check.SetGlobal(true);
179 values.cpuopt_unsafe_ignore_global_monitor.SetGlobal(true);
179 180
180 // Renderer 181 // Renderer
181 values.renderer_backend.SetGlobal(true); 182 values.renderer_backend.SetGlobal(true);
diff --git a/src/common/settings.h b/src/common/settings.h
index d06b23a14..a37d83fb3 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -484,12 +484,15 @@ struct Values {
484 BasicSetting<bool> cpuopt_misc_ir{true, "cpuopt_misc_ir"}; 484 BasicSetting<bool> cpuopt_misc_ir{true, "cpuopt_misc_ir"};
485 BasicSetting<bool> cpuopt_reduce_misalign_checks{true, "cpuopt_reduce_misalign_checks"}; 485 BasicSetting<bool> cpuopt_reduce_misalign_checks{true, "cpuopt_reduce_misalign_checks"};
486 BasicSetting<bool> cpuopt_fastmem{true, "cpuopt_fastmem"}; 486 BasicSetting<bool> cpuopt_fastmem{true, "cpuopt_fastmem"};
487 BasicSetting<bool> cpuopt_fastmem_exclusives{true, "cpuopt_fastmem_exclusives"};
488 BasicSetting<bool> cpuopt_recompile_exclusives{true, "cpuopt_recompile_exclusives"};
487 489
488 Setting<bool> cpuopt_unsafe_unfuse_fma{true, "cpuopt_unsafe_unfuse_fma"}; 490 Setting<bool> cpuopt_unsafe_unfuse_fma{true, "cpuopt_unsafe_unfuse_fma"};
489 Setting<bool> cpuopt_unsafe_reduce_fp_error{true, "cpuopt_unsafe_reduce_fp_error"}; 491 Setting<bool> cpuopt_unsafe_reduce_fp_error{true, "cpuopt_unsafe_reduce_fp_error"};
490 Setting<bool> cpuopt_unsafe_ignore_standard_fpcr{true, "cpuopt_unsafe_ignore_standard_fpcr"}; 492 Setting<bool> cpuopt_unsafe_ignore_standard_fpcr{true, "cpuopt_unsafe_ignore_standard_fpcr"};
491 Setting<bool> cpuopt_unsafe_inaccurate_nan{true, "cpuopt_unsafe_inaccurate_nan"}; 493 Setting<bool> cpuopt_unsafe_inaccurate_nan{true, "cpuopt_unsafe_inaccurate_nan"};
492 Setting<bool> cpuopt_unsafe_fastmem_check{true, "cpuopt_unsafe_fastmem_check"}; 494 Setting<bool> cpuopt_unsafe_fastmem_check{true, "cpuopt_unsafe_fastmem_check"};
495 Setting<bool> cpuopt_unsafe_ignore_global_monitor{true, "cpuopt_unsafe_ignore_global_monitor"};
493 496
494 // Renderer 497 // Renderer
495 RangedSetting<RendererBackend> renderer_backend{ 498 RangedSetting<RendererBackend> renderer_backend{
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index b0d89c539..286976623 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -137,6 +137,8 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
137 config.page_table_pointer_mask_bits = Common::PageTable::ATTRIBUTE_BITS; 137 config.page_table_pointer_mask_bits = Common::PageTable::ATTRIBUTE_BITS;
138 config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128; 138 config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128;
139 config.only_detect_misalignment_via_page_table_on_page_boundary = true; 139 config.only_detect_misalignment_via_page_table_on_page_boundary = true;
140 config.fastmem_exclusive_access = true;
141 config.recompile_on_exclusive_fastmem_failure = true;
140 142
141 // Multi-process state 143 // Multi-process state
142 config.processor_id = core_index; 144 config.processor_id = core_index;
@@ -178,6 +180,12 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
178 if (!Settings::values.cpuopt_fastmem) { 180 if (!Settings::values.cpuopt_fastmem) {
179 config.fastmem_pointer = nullptr; 181 config.fastmem_pointer = nullptr;
180 } 182 }
183 if (!Settings::values.cpuopt_fastmem_exclusives) {
184 config.fastmem_exclusive_access = false;
185 }
186 if (!Settings::values.cpuopt_recompile_exclusives) {
187 config.recompile_on_exclusive_fastmem_failure = false;
188 }
181 } 189 }
182 190
183 // Unsafe optimizations 191 // Unsafe optimizations
@@ -195,6 +203,9 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
195 if (Settings::values.cpuopt_unsafe_inaccurate_nan) { 203 if (Settings::values.cpuopt_unsafe_inaccurate_nan) {
196 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; 204 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
197 } 205 }
206 if (Settings::values.cpuopt_unsafe_ignore_global_monitor) {
207 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor;
208 }
198 } 209 }
199 210
200 // Curated optimizations 211 // Curated optimizations
@@ -203,6 +214,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
203 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; 214 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
204 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue; 215 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue;
205 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; 216 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
217 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor;
206 } 218 }
207 219
208 return std::make_unique<Dynarmic::A32::Jit>(config); 220 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 56836bd05..d96226c41 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -185,6 +185,9 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
185 config.fastmem_pointer = page_table->fastmem_arena; 185 config.fastmem_pointer = page_table->fastmem_arena;
186 config.fastmem_address_space_bits = address_space_bits; 186 config.fastmem_address_space_bits = address_space_bits;
187 config.silently_mirror_fastmem = false; 187 config.silently_mirror_fastmem = false;
188
189 config.fastmem_exclusive_access = true;
190 config.recompile_on_exclusive_fastmem_failure = true;
188 } 191 }
189 192
190 // Multi-process state 193 // Multi-process state
@@ -237,6 +240,12 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
237 if (!Settings::values.cpuopt_fastmem) { 240 if (!Settings::values.cpuopt_fastmem) {
238 config.fastmem_pointer = nullptr; 241 config.fastmem_pointer = nullptr;
239 } 242 }
243 if (!Settings::values.cpuopt_fastmem_exclusives) {
244 config.fastmem_exclusive_access = false;
245 }
246 if (!Settings::values.cpuopt_recompile_exclusives) {
247 config.recompile_on_exclusive_fastmem_failure = false;
248 }
240 } 249 }
241 250
242 // Unsafe optimizations 251 // Unsafe optimizations
@@ -254,6 +263,9 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
254 if (Settings::values.cpuopt_unsafe_fastmem_check) { 263 if (Settings::values.cpuopt_unsafe_fastmem_check) {
255 config.fastmem_address_space_bits = 64; 264 config.fastmem_address_space_bits = 64;
256 } 265 }
266 if (Settings::values.cpuopt_unsafe_ignore_global_monitor) {
267 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor;
268 }
257 } 269 }
258 270
259 // Curated optimizations 271 // Curated optimizations
@@ -262,6 +274,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
262 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA; 274 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
263 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN; 275 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
264 config.fastmem_address_space_bits = 64; 276 config.fastmem_address_space_bits = 64;
277 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreGlobalMonitor;
265 } 278 }
266 279
267 return std::make_shared<Dynarmic::A64::Jit>(config); 280 return std::make_shared<Dynarmic::A64::Jit>(config);
diff --git a/src/core/arm/dynarmic/arm_exclusive_monitor.cpp b/src/core/arm/dynarmic/arm_exclusive_monitor.cpp
index 397d054a8..ea6b224e0 100644
--- a/src/core/arm/dynarmic/arm_exclusive_monitor.cpp
+++ b/src/core/arm/dynarmic/arm_exclusive_monitor.cpp
@@ -37,8 +37,8 @@ u128 DynarmicExclusiveMonitor::ExclusiveRead128(std::size_t core_index, VAddr ad
37 }); 37 });
38} 38}
39 39
40void DynarmicExclusiveMonitor::ClearExclusive() { 40void DynarmicExclusiveMonitor::ClearExclusive(std::size_t core_index) {
41 monitor.Clear(); 41 monitor.ClearProcessor(core_index);
42} 42}
43 43
44bool DynarmicExclusiveMonitor::ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) { 44bool DynarmicExclusiveMonitor::ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) {
diff --git a/src/core/arm/dynarmic/arm_exclusive_monitor.h b/src/core/arm/dynarmic/arm_exclusive_monitor.h
index 265c4ecef..5a15b43ef 100644
--- a/src/core/arm/dynarmic/arm_exclusive_monitor.h
+++ b/src/core/arm/dynarmic/arm_exclusive_monitor.h
@@ -29,7 +29,7 @@ public:
29 u32 ExclusiveRead32(std::size_t core_index, VAddr addr) override; 29 u32 ExclusiveRead32(std::size_t core_index, VAddr addr) override;
30 u64 ExclusiveRead64(std::size_t core_index, VAddr addr) override; 30 u64 ExclusiveRead64(std::size_t core_index, VAddr addr) override;
31 u128 ExclusiveRead128(std::size_t core_index, VAddr addr) override; 31 u128 ExclusiveRead128(std::size_t core_index, VAddr addr) override;
32 void ClearExclusive() override; 32 void ClearExclusive(std::size_t core_index) override;
33 33
34 bool ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) override; 34 bool ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) override;
35 bool ExclusiveWrite16(std::size_t core_index, VAddr vaddr, u16 value) override; 35 bool ExclusiveWrite16(std::size_t core_index, VAddr vaddr, u16 value) override;
diff --git a/src/core/arm/exclusive_monitor.h b/src/core/arm/exclusive_monitor.h
index 62f6e6023..9914ca3da 100644
--- a/src/core/arm/exclusive_monitor.h
+++ b/src/core/arm/exclusive_monitor.h
@@ -23,7 +23,7 @@ public:
23 virtual u32 ExclusiveRead32(std::size_t core_index, VAddr addr) = 0; 23 virtual u32 ExclusiveRead32(std::size_t core_index, VAddr addr) = 0;
24 virtual u64 ExclusiveRead64(std::size_t core_index, VAddr addr) = 0; 24 virtual u64 ExclusiveRead64(std::size_t core_index, VAddr addr) = 0;
25 virtual u128 ExclusiveRead128(std::size_t core_index, VAddr addr) = 0; 25 virtual u128 ExclusiveRead128(std::size_t core_index, VAddr addr) = 0;
26 virtual void ClearExclusive() = 0; 26 virtual void ClearExclusive(std::size_t core_index) = 0;
27 27
28 virtual bool ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) = 0; 28 virtual bool ExclusiveWrite8(std::size_t core_index, VAddr vaddr, u8 value) = 0;
29 virtual bool ExclusiveWrite16(std::size_t core_index, VAddr vaddr, u16 value) = 0; 29 virtual bool ExclusiveWrite16(std::size_t core_index, VAddr vaddr, u16 value) = 0;
diff --git a/src/core/hle/kernel/k_address_arbiter.cpp b/src/core/hle/kernel/k_address_arbiter.cpp
index 783c69858..1d1f5e5f8 100644
--- a/src/core/hle/kernel/k_address_arbiter.cpp
+++ b/src/core/hle/kernel/k_address_arbiter.cpp
@@ -49,7 +49,7 @@ bool DecrementIfLessThan(Core::System& system, s32* out, VAddr address, s32 valu
49 } 49 }
50 } else { 50 } else {
51 // Otherwise, clear our exclusive hold and finish 51 // Otherwise, clear our exclusive hold and finish
52 monitor.ClearExclusive(); 52 monitor.ClearExclusive(current_core);
53 } 53 }
54 54
55 // We're done. 55 // We're done.
@@ -78,7 +78,7 @@ bool UpdateIfEqual(Core::System& system, s32* out, VAddr address, s32 value, s32
78 } 78 }
79 } else { 79 } else {
80 // Otherwise, clear our exclusive hold and finish. 80 // Otherwise, clear our exclusive hold and finish.
81 monitor.ClearExclusive(); 81 monitor.ClearExclusive(current_core);
82 } 82 }
83 83
84 // We're done. 84 // We're done.
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index f915bd856..c2b66ff14 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -609,6 +609,7 @@ void Config::ReadCpuValues() {
609 ReadGlobalSetting(Settings::values.cpuopt_unsafe_ignore_standard_fpcr); 609 ReadGlobalSetting(Settings::values.cpuopt_unsafe_ignore_standard_fpcr);
610 ReadGlobalSetting(Settings::values.cpuopt_unsafe_inaccurate_nan); 610 ReadGlobalSetting(Settings::values.cpuopt_unsafe_inaccurate_nan);
611 ReadGlobalSetting(Settings::values.cpuopt_unsafe_fastmem_check); 611 ReadGlobalSetting(Settings::values.cpuopt_unsafe_fastmem_check);
612 ReadGlobalSetting(Settings::values.cpuopt_unsafe_ignore_global_monitor);
612 613
613 if (global) { 614 if (global) {
614 ReadBasicSetting(Settings::values.cpu_debug_mode); 615 ReadBasicSetting(Settings::values.cpu_debug_mode);
@@ -621,6 +622,8 @@ void Config::ReadCpuValues() {
621 ReadBasicSetting(Settings::values.cpuopt_misc_ir); 622 ReadBasicSetting(Settings::values.cpuopt_misc_ir);
622 ReadBasicSetting(Settings::values.cpuopt_reduce_misalign_checks); 623 ReadBasicSetting(Settings::values.cpuopt_reduce_misalign_checks);
623 ReadBasicSetting(Settings::values.cpuopt_fastmem); 624 ReadBasicSetting(Settings::values.cpuopt_fastmem);
625 ReadBasicSetting(Settings::values.cpuopt_fastmem_exclusives);
626 ReadBasicSetting(Settings::values.cpuopt_recompile_exclusives);
624 } 627 }
625 628
626 qt_config->endGroup(); 629 qt_config->endGroup();
@@ -1139,6 +1142,7 @@ void Config::SaveCpuValues() {
1139 WriteGlobalSetting(Settings::values.cpuopt_unsafe_ignore_standard_fpcr); 1142 WriteGlobalSetting(Settings::values.cpuopt_unsafe_ignore_standard_fpcr);
1140 WriteGlobalSetting(Settings::values.cpuopt_unsafe_inaccurate_nan); 1143 WriteGlobalSetting(Settings::values.cpuopt_unsafe_inaccurate_nan);
1141 WriteGlobalSetting(Settings::values.cpuopt_unsafe_fastmem_check); 1144 WriteGlobalSetting(Settings::values.cpuopt_unsafe_fastmem_check);
1145 WriteGlobalSetting(Settings::values.cpuopt_unsafe_ignore_global_monitor);
1142 1146
1143 if (global) { 1147 if (global) {
1144 WriteBasicSetting(Settings::values.cpu_debug_mode); 1148 WriteBasicSetting(Settings::values.cpu_debug_mode);
diff --git a/src/yuzu/configuration/configure_cpu.cpp b/src/yuzu/configuration/configure_cpu.cpp
index f66cab5d4..bf74ccc7c 100644
--- a/src/yuzu/configuration/configure_cpu.cpp
+++ b/src/yuzu/configuration/configure_cpu.cpp
@@ -36,6 +36,7 @@ void ConfigureCpu::SetConfiguration() {
36 ui->cpuopt_unsafe_ignore_standard_fpcr->setEnabled(runtime_lock); 36 ui->cpuopt_unsafe_ignore_standard_fpcr->setEnabled(runtime_lock);
37 ui->cpuopt_unsafe_inaccurate_nan->setEnabled(runtime_lock); 37 ui->cpuopt_unsafe_inaccurate_nan->setEnabled(runtime_lock);
38 ui->cpuopt_unsafe_fastmem_check->setEnabled(runtime_lock); 38 ui->cpuopt_unsafe_fastmem_check->setEnabled(runtime_lock);
39 ui->cpuopt_unsafe_ignore_global_monitor->setEnabled(runtime_lock);
39 40
40 ui->cpuopt_unsafe_unfuse_fma->setChecked(Settings::values.cpuopt_unsafe_unfuse_fma.GetValue()); 41 ui->cpuopt_unsafe_unfuse_fma->setChecked(Settings::values.cpuopt_unsafe_unfuse_fma.GetValue());
41 ui->cpuopt_unsafe_reduce_fp_error->setChecked( 42 ui->cpuopt_unsafe_reduce_fp_error->setChecked(
@@ -46,6 +47,8 @@ void ConfigureCpu::SetConfiguration() {
46 Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue()); 47 Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue());
47 ui->cpuopt_unsafe_fastmem_check->setChecked( 48 ui->cpuopt_unsafe_fastmem_check->setChecked(
48 Settings::values.cpuopt_unsafe_fastmem_check.GetValue()); 49 Settings::values.cpuopt_unsafe_fastmem_check.GetValue());
50 ui->cpuopt_unsafe_ignore_global_monitor->setChecked(
51 Settings::values.cpuopt_unsafe_ignore_global_monitor.GetValue());
49 52
50 if (Settings::IsConfiguringGlobal()) { 53 if (Settings::IsConfiguringGlobal()) {
51 ui->accuracy->setCurrentIndex(static_cast<int>(Settings::values.cpu_accuracy.GetValue())); 54 ui->accuracy->setCurrentIndex(static_cast<int>(Settings::values.cpu_accuracy.GetValue()));
@@ -82,6 +85,9 @@ void ConfigureCpu::ApplyConfiguration() {
82 ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_fastmem_check, 85 ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_fastmem_check,
83 ui->cpuopt_unsafe_fastmem_check, 86 ui->cpuopt_unsafe_fastmem_check,
84 cpuopt_unsafe_fastmem_check); 87 cpuopt_unsafe_fastmem_check);
88 ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_ignore_global_monitor,
89 ui->cpuopt_unsafe_ignore_global_monitor,
90 cpuopt_unsafe_ignore_global_monitor);
85} 91}
86 92
87void ConfigureCpu::changeEvent(QEvent* event) { 93void ConfigureCpu::changeEvent(QEvent* event) {
@@ -120,4 +126,7 @@ void ConfigureCpu::SetupPerGameUI() {
120 ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_fastmem_check, 126 ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_fastmem_check,
121 Settings::values.cpuopt_unsafe_fastmem_check, 127 Settings::values.cpuopt_unsafe_fastmem_check,
122 cpuopt_unsafe_fastmem_check); 128 cpuopt_unsafe_fastmem_check);
129 ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_ignore_global_monitor,
130 Settings::values.cpuopt_unsafe_ignore_global_monitor,
131 cpuopt_unsafe_ignore_global_monitor);
123} 132}
diff --git a/src/yuzu/configuration/configure_cpu.h b/src/yuzu/configuration/configure_cpu.h
index ed9af0e9f..733e38be4 100644
--- a/src/yuzu/configuration/configure_cpu.h
+++ b/src/yuzu/configuration/configure_cpu.h
@@ -45,6 +45,7 @@ private:
45 ConfigurationShared::CheckState cpuopt_unsafe_ignore_standard_fpcr; 45 ConfigurationShared::CheckState cpuopt_unsafe_ignore_standard_fpcr;
46 ConfigurationShared::CheckState cpuopt_unsafe_inaccurate_nan; 46 ConfigurationShared::CheckState cpuopt_unsafe_inaccurate_nan;
47 ConfigurationShared::CheckState cpuopt_unsafe_fastmem_check; 47 ConfigurationShared::CheckState cpuopt_unsafe_fastmem_check;
48 ConfigurationShared::CheckState cpuopt_unsafe_ignore_global_monitor;
48 49
49 const Core::System& system; 50 const Core::System& system;
50}; 51};
diff --git a/src/yuzu/configuration/configure_cpu.ui b/src/yuzu/configuration/configure_cpu.ui
index d8064db24..5d80a8c91 100644
--- a/src/yuzu/configuration/configure_cpu.ui
+++ b/src/yuzu/configuration/configure_cpu.ui
@@ -150,6 +150,18 @@
150 </property> 150 </property>
151 </widget> 151 </widget>
152 </item> 152 </item>
153 <item>
154 <widget class="QCheckBox" name="cpuopt_unsafe_ignore_global_monitor">
155 <property name="toolTip">
156 <string>
157 &lt;div&gt;This option improves speed by relying only on the semantics of cmpxchg to ensure safety of exclusive access instructions. Please note this may result in deadlocks and other race conditions.&lt;/div&gt;
158 </string>
159 </property>
160 <property name="text">
161 <string>Ignore global monitor</string>
162 </property>
163 </widget>
164 </item>
153 </layout> 165 </layout>
154 </widget> 166 </widget>
155 </item> 167 </item>
diff --git a/src/yuzu/configuration/configure_cpu_debug.cpp b/src/yuzu/configuration/configure_cpu_debug.cpp
index 05a90963d..616a0be75 100644
--- a/src/yuzu/configuration/configure_cpu_debug.cpp
+++ b/src/yuzu/configuration/configure_cpu_debug.cpp
@@ -44,6 +44,12 @@ void ConfigureCpuDebug::SetConfiguration() {
44 Settings::values.cpuopt_reduce_misalign_checks.GetValue()); 44 Settings::values.cpuopt_reduce_misalign_checks.GetValue());
45 ui->cpuopt_fastmem->setEnabled(runtime_lock); 45 ui->cpuopt_fastmem->setEnabled(runtime_lock);
46 ui->cpuopt_fastmem->setChecked(Settings::values.cpuopt_fastmem.GetValue()); 46 ui->cpuopt_fastmem->setChecked(Settings::values.cpuopt_fastmem.GetValue());
47 ui->cpuopt_fastmem_exclusives->setEnabled(runtime_lock);
48 ui->cpuopt_fastmem_exclusives->setChecked(
49 Settings::values.cpuopt_fastmem_exclusives.GetValue());
50 ui->cpuopt_recompile_exclusives->setEnabled(runtime_lock);
51 ui->cpuopt_recompile_exclusives->setChecked(
52 Settings::values.cpuopt_recompile_exclusives.GetValue());
47} 53}
48 54
49void ConfigureCpuDebug::ApplyConfiguration() { 55void ConfigureCpuDebug::ApplyConfiguration() {
@@ -56,6 +62,8 @@ void ConfigureCpuDebug::ApplyConfiguration() {
56 Settings::values.cpuopt_misc_ir = ui->cpuopt_misc_ir->isChecked(); 62 Settings::values.cpuopt_misc_ir = ui->cpuopt_misc_ir->isChecked();
57 Settings::values.cpuopt_reduce_misalign_checks = ui->cpuopt_reduce_misalign_checks->isChecked(); 63 Settings::values.cpuopt_reduce_misalign_checks = ui->cpuopt_reduce_misalign_checks->isChecked();
58 Settings::values.cpuopt_fastmem = ui->cpuopt_fastmem->isChecked(); 64 Settings::values.cpuopt_fastmem = ui->cpuopt_fastmem->isChecked();
65 Settings::values.cpuopt_fastmem_exclusives = ui->cpuopt_fastmem_exclusives->isChecked();
66 Settings::values.cpuopt_recompile_exclusives = ui->cpuopt_recompile_exclusives->isChecked();
59} 67}
60 68
61void ConfigureCpuDebug::changeEvent(QEvent* event) { 69void ConfigureCpuDebug::changeEvent(QEvent* event) {
diff --git a/src/yuzu/configuration/configure_cpu_debug.ui b/src/yuzu/configuration/configure_cpu_debug.ui
index 6e635bb2f..2bc268810 100644
--- a/src/yuzu/configuration/configure_cpu_debug.ui
+++ b/src/yuzu/configuration/configure_cpu_debug.ui
@@ -144,7 +144,34 @@
144 </string> 144 </string>
145 </property> 145 </property>
146 <property name="text"> 146 <property name="text">
147 <string>Enable Host MMU Emulation</string> 147 <string>Enable Host MMU Emulation (general memory instructions)</string>
148 </property>
149 </widget>
150 </item>
151 <item>
152 <widget class="QCheckBox" name="cpuopt_fastmem_exclusives">
153 <property name="toolTip">
154 <string>
155 &lt;div style=&quot;white-space: nowrap&quot;&gt;This optimization speeds up exclusive memory accesses by the guest program.&lt;/div&gt;
156 &lt;div style=&quot;white-space: nowrap&quot;&gt;Enabling it causes guest exclusive memory reads/writes to be done directly into memory and make use of Host's MMU.&lt;/div&gt;
157 &lt;div style=&quot;white-space: nowrap&quot;&gt;Disabling this forces all exclusive memory accesses to use Software MMU Emulation.&lt;/div&gt;
158 </string>
159 </property>
160 <property name="text">
161 <string>Enable Host MMU Emulation (exclusive memory instructions)</string>
162 </property>
163 </widget>
164 </item>
165 <item>
166 <widget class="QCheckBox" name="cpuopt_recompile_exclusives">
167 <property name="toolTip">
168 <string>
169 &lt;div style=&quot;white-space: nowrap&quot;&gt;This optimization speeds up exclusive memory accesses by the guest program.&lt;/div&gt;
170 &lt;div style=&quot;white-space: nowrap&quot;&gt;Enabling it reduces the overhead of fastmem failure of exclusive memory accesses.&lt;/div&gt;
171 </string>
172 </property>
173 <property name="text">
174 <string>Enable recompilation of exclusive memory instructions</string>
148 </property> 175 </property>
149 </widget> 176 </widget>
150 </item> 177 </item>
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 30963a8bb..b74411c84 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -280,11 +280,14 @@ void Config::ReadValues() {
280 ReadSetting("Cpu", Settings::values.cpuopt_misc_ir); 280 ReadSetting("Cpu", Settings::values.cpuopt_misc_ir);
281 ReadSetting("Cpu", Settings::values.cpuopt_reduce_misalign_checks); 281 ReadSetting("Cpu", Settings::values.cpuopt_reduce_misalign_checks);
282 ReadSetting("Cpu", Settings::values.cpuopt_fastmem); 282 ReadSetting("Cpu", Settings::values.cpuopt_fastmem);
283 ReadSetting("Cpu", Settings::values.cpuopt_fastmem_exclusives);
284 ReadSetting("Cpu", Settings::values.cpuopt_recompile_exclusives);
283 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_unfuse_fma); 285 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_unfuse_fma);
284 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_reduce_fp_error); 286 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_reduce_fp_error);
285 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_ignore_standard_fpcr); 287 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_ignore_standard_fpcr);
286 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_inaccurate_nan); 288 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_inaccurate_nan);
287 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_fastmem_check); 289 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_fastmem_check);
290 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_ignore_global_monitor);
288 291
289 // Renderer 292 // Renderer
290 ReadSetting("Renderer", Settings::values.renderer_backend); 293 ReadSetting("Renderer", Settings::values.renderer_backend);
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index 6d613bf7a..3ac1440c9 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -174,6 +174,14 @@ cpuopt_reduce_misalign_checks =
174# 0: Disabled, 1 (default): Enabled 174# 0: Disabled, 1 (default): Enabled
175cpuopt_fastmem = 175cpuopt_fastmem =
176 176
177# Enable Host MMU Emulation for exclusive memory instructions (faster guest memory access)
178# 0: Disabled, 1 (default): Enabled
179cpuopt_fastmem_exclusives =
180
181# Enable fallback on failure of fastmem of exclusive memory instructions (faster guest memory access)
182# 0: Disabled, 1 (default): Enabled
183cpuopt_recompile_exclusives =
184
177# Enable unfuse FMA (improve performance on CPUs without FMA) 185# Enable unfuse FMA (improve performance on CPUs without FMA)
178# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select. 186# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
179# 0: Disabled, 1 (default): Enabled 187# 0: Disabled, 1 (default): Enabled
@@ -199,6 +207,11 @@ cpuopt_unsafe_inaccurate_nan =
199# 0: Disabled, 1 (default): Enabled 207# 0: Disabled, 1 (default): Enabled
200cpuopt_unsafe_fastmem_check = 208cpuopt_unsafe_fastmem_check =
201 209
210# Enable faster exclusive instructions
211# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
212# 0: Disabled, 1 (default): Enabled
213cpuopt_unsafe_ignore_global_monitor =
214
202[Renderer] 215[Renderer]
203# Which backend API to use. 216# Which backend API to use.
204# 0 (default): OpenGL, 1: Vulkan 217# 0 (default): OpenGL, 1: Vulkan