summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar merry2022-02-27 19:40:05 +0000
committerGravatar merry2022-02-27 19:40:05 +0000
commit16784e5bb3dd043f9430401097a4be42ad21eb91 (patch)
treed09e952371f9e7e90aecba4d8b4e9654d10c50a2 /src/core
parentMerge pull request #7955 from bunnei/update-dynarmic (diff)
downloadyuzu-16784e5bb3dd043f9430401097a4be42ad21eb91.tar.gz
yuzu-16784e5bb3dd043f9430401097a4be42ad21eb91.tar.xz
yuzu-16784e5bb3dd043f9430401097a4be42ad21eb91.zip
dynarmic: Inline exclusive memory accesses
Inlines implementation of exclusive instructions into JITted code, improving performance of applications relying heavily on these instructions. We also fastmem these instructions for additional speed, with support for appropriate recompilation on fastmem failure. An unsafe optimization to disable the intercore global_monitor is also provided, should one wish to rely solely on cmpxchg semantics for safety. See also: merryhime/dynarmic#664
Diffstat (limited to 'src/core')
-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
6 files changed, 31 insertions, 6 deletions
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.