summaryrefslogtreecommitdiff
path: root/src/core/arm/dynarmic
diff options
context:
space:
mode:
authorGravatar Levi2021-01-10 22:09:56 -0700
committerGravatar Levi2021-01-10 22:09:56 -0700
commit7a3c884e39fccfbb498b855080bffabc9ce2e7f1 (patch)
tree5056f9406dec188439cb0deb87603498243a9412 /src/core/arm/dynarmic
parentMore forgetting... duh (diff)
parentMerge pull request #5229 from Morph1984/fullscreen-opt (diff)
downloadyuzu-7a3c884e39fccfbb498b855080bffabc9ce2e7f1.tar.gz
yuzu-7a3c884e39fccfbb498b855080bffabc9ce2e7f1.tar.xz
yuzu-7a3c884e39fccfbb498b855080bffabc9ce2e7f1.zip
Merge remote-tracking branch 'upstream/master' into int-flags
Diffstat (limited to 'src/core/arm/dynarmic')
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp28
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.h2
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp60
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.h4
4 files changed, 51 insertions, 43 deletions
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index b5f28a86e..6c4c8e9e4 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -7,6 +7,7 @@
7#include <dynarmic/A32/a32.h> 7#include <dynarmic/A32/a32.h>
8#include <dynarmic/A32/config.h> 8#include <dynarmic/A32/config.h>
9#include <dynarmic/A32/context.h> 9#include <dynarmic/A32/context.h>
10#include "common/assert.h"
10#include "common/logging/log.h" 11#include "common/logging/log.h"
11#include "common/page_table.h" 12#include "common/page_table.h"
12#include "core/arm/cpu_interrupt_handler.h" 13#include "core/arm/cpu_interrupt_handler.h"
@@ -70,15 +71,8 @@ public:
70 } 71 }
71 72
72 void ExceptionRaised(u32 pc, Dynarmic::A32::Exception exception) override { 73 void ExceptionRaised(u32 pc, Dynarmic::A32::Exception exception) override {
73 switch (exception) {
74 case Dynarmic::A32::Exception::UndefinedInstruction:
75 case Dynarmic::A32::Exception::UnpredictableInstruction:
76 break;
77 case Dynarmic::A32::Exception::Breakpoint:
78 break;
79 }
80 LOG_CRITICAL(Core_ARM, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})", 74 LOG_CRITICAL(Core_ARM, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})",
81 static_cast<std::size_t>(exception), pc, MemoryReadCode(pc)); 75 exception, pc, MemoryReadCode(pc));
82 UNIMPLEMENTED(); 76 UNIMPLEMENTED();
83 } 77 }
84 78
@@ -132,6 +126,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable&
132 config.page_table = reinterpret_cast<std::array<std::uint8_t*, NUM_PAGE_TABLE_ENTRIES>*>( 126 config.page_table = reinterpret_cast<std::array<std::uint8_t*, NUM_PAGE_TABLE_ENTRIES>*>(
133 page_table.pointers.data()); 127 page_table.pointers.data());
134 config.absolute_offset_page_table = true; 128 config.absolute_offset_page_table = true;
129 config.page_table_pointer_mask_bits = Common::PageTable::ATTRIBUTE_BITS;
135 config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128; 130 config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128;
136 config.only_detect_misalignment_via_page_table_on_page_boundary = true; 131 config.only_detect_misalignment_via_page_table_on_page_boundary = true;
137 132
@@ -179,6 +174,9 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable&
179 if (Settings::values.cpuopt_unsafe_reduce_fp_error) { 174 if (Settings::values.cpuopt_unsafe_reduce_fp_error) {
180 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; 175 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP;
181 } 176 }
177 if (Settings::values.cpuopt_unsafe_inaccurate_nan) {
178 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
179 }
182 } 180 }
183 181
184 return std::make_unique<Dynarmic::A32::Jit>(config); 182 return std::make_unique<Dynarmic::A32::Jit>(config);
@@ -188,6 +186,10 @@ void ARM_Dynarmic_32::Run() {
188 jit->Run(); 186 jit->Run();
189} 187}
190 188
189void ARM_Dynarmic_32::ExceptionalExit() {
190 jit->ExceptionalExit();
191}
192
191void ARM_Dynarmic_32::Step() { 193void ARM_Dynarmic_32::Step() {
192 jit->Step(); 194 jit->Step();
193} 195}
@@ -281,7 +283,17 @@ void ARM_Dynarmic_32::ClearInstructionCache() {
281 jit->ClearCache(); 283 jit->ClearCache();
282} 284}
283 285
286void ARM_Dynarmic_32::InvalidateCacheRange(VAddr addr, std::size_t size) {
287 if (!jit) {
288 return;
289 }
290 jit->InvalidateCacheRange(static_cast<u32>(addr), size);
291}
292
284void ARM_Dynarmic_32::ClearExclusiveState() { 293void ARM_Dynarmic_32::ClearExclusiveState() {
294 if (!jit) {
295 return;
296 }
285 jit->ClearExclusiveState(); 297 jit->ClearExclusiveState();
286} 298}
287 299
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.h b/src/core/arm/dynarmic/arm_dynarmic_32.h
index 2bab31b92..35e9ced48 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.h
@@ -42,6 +42,7 @@ public:
42 u32 GetPSTATE() const override; 42 u32 GetPSTATE() const override;
43 void SetPSTATE(u32 pstate) override; 43 void SetPSTATE(u32 pstate) override;
44 void Run() override; 44 void Run() override;
45 void ExceptionalExit() override;
45 void Step() override; 46 void Step() override;
46 VAddr GetTlsAddress() const override; 47 VAddr GetTlsAddress() const override;
47 void SetTlsAddress(VAddr address) override; 48 void SetTlsAddress(VAddr address) override;
@@ -58,6 +59,7 @@ public:
58 void ClearExclusiveState() override; 59 void ClearExclusiveState() override;
59 60
60 void ClearInstructionCache() override; 61 void ClearInstructionCache() override;
62 void InvalidateCacheRange(VAddr addr, std::size_t size) override;
61 void PageTableChanged(Common::PageTable& new_page_table, 63 void PageTableChanged(Common::PageTable& new_page_table,
62 std::size_t new_address_space_size_in_bits) override; 64 std::size_t new_address_space_size_in_bits) override;
63 65
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index ce9968724..4c5ebca22 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -6,6 +6,7 @@
6#include <memory> 6#include <memory>
7#include <dynarmic/A64/a64.h> 7#include <dynarmic/A64/a64.h>
8#include <dynarmic/A64/config.h> 8#include <dynarmic/A64/config.h>
9#include "common/assert.h"
9#include "common/logging/log.h" 10#include "common/logging/log.h"
10#include "common/page_table.h" 11#include "common/page_table.h"
11#include "core/arm/cpu_interrupt_handler.h" 12#include "core/arm/cpu_interrupt_handler.h"
@@ -13,11 +14,9 @@
13#include "core/arm/dynarmic/arm_exclusive_monitor.h" 14#include "core/arm/dynarmic/arm_exclusive_monitor.h"
14#include "core/core.h" 15#include "core/core.h"
15#include "core/core_timing.h" 16#include "core/core_timing.h"
16#include "core/core_timing_util.h"
17#include "core/gdbstub/gdbstub.h"
18#include "core/hardware_properties.h" 17#include "core/hardware_properties.h"
18#include "core/hle/kernel/k_scheduler.h"
19#include "core/hle/kernel/process.h" 19#include "core/hle/kernel/process.h"
20#include "core/hle/kernel/scheduler.h"
21#include "core/hle/kernel/svc.h" 20#include "core/hle/kernel/svc.h"
22#include "core/memory.h" 21#include "core/memory.h"
23#include "core/settings.h" 22#include "core/settings.h"
@@ -82,16 +81,9 @@ public:
82 } 81 }
83 82
84 void InterpreterFallback(u64 pc, std::size_t num_instructions) override { 83 void InterpreterFallback(u64 pc, std::size_t num_instructions) override {
85 LOG_INFO(Core_ARM, "Unicorn fallback @ 0x{:X} for {} instructions (instr = {:08X})", pc, 84 LOG_ERROR(Core_ARM,
86 num_instructions, MemoryReadCode(pc)); 85 "Unimplemented instruction @ 0x{:X} for {} instructions (instr = {:08X})", pc,
87 86 num_instructions, MemoryReadCode(pc));
88 ARM_Interface::ThreadContext64 ctx;
89 parent.SaveContext(ctx);
90 parent.inner_unicorn.LoadContext(ctx);
91 parent.inner_unicorn.ExecuteInstructions(num_instructions);
92 parent.inner_unicorn.SaveContext(ctx);
93 parent.LoadContext(ctx);
94 num_interpreted_instructions += num_instructions;
95 } 87 }
96 88
97 void ExceptionRaised(u64 pc, Dynarmic::A64::Exception exception) override { 89 void ExceptionRaised(u64 pc, Dynarmic::A64::Exception exception) override {
@@ -103,16 +95,6 @@ public:
103 case Dynarmic::A64::Exception::Yield: 95 case Dynarmic::A64::Exception::Yield:
104 return; 96 return;
105 case Dynarmic::A64::Exception::Breakpoint: 97 case Dynarmic::A64::Exception::Breakpoint:
106 if (GDBStub::IsServerEnabled()) {
107 parent.jit->HaltExecution();
108 parent.SetPC(pc);
109 Kernel::Thread* const thread = parent.system.CurrentScheduler().GetCurrentThread();
110 parent.SaveContext(thread->GetContext64());
111 GDBStub::Break();
112 GDBStub::SendTrap(thread, 5);
113 return;
114 }
115 [[fallthrough]];
116 default: 98 default:
117 ASSERT_MSG(false, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})", 99 ASSERT_MSG(false, "ExceptionRaised(exception = {}, pc = {:08X}, code = {:08X})",
118 static_cast<std::size_t>(exception), pc, MemoryReadCode(pc)); 100 static_cast<std::size_t>(exception), pc, MemoryReadCode(pc));
@@ -127,18 +109,17 @@ public:
127 if (parent.uses_wall_clock) { 109 if (parent.uses_wall_clock) {
128 return; 110 return;
129 } 111 }
112
130 // Divide the number of ticks by the amount of CPU cores. TODO(Subv): This yields only a 113 // Divide the number of ticks by the amount of CPU cores. TODO(Subv): This yields only a
131 // rough approximation of the amount of executed ticks in the system, it may be thrown off 114 // rough approximation of the amount of executed ticks in the system, it may be thrown off
132 // if not all cores are doing a similar amount of work. Instead of doing this, we should 115 // if not all cores are doing a similar amount of work. Instead of doing this, we should
133 // device a way so that timing is consistent across all cores without increasing the ticks 4 116 // device a way so that timing is consistent across all cores without increasing the ticks 4
134 // times. 117 // times.
135 u64 amortized_ticks = 118 u64 amortized_ticks = ticks / Core::Hardware::NUM_CPU_CORES;
136 (ticks - num_interpreted_instructions) / Core::Hardware::NUM_CPU_CORES;
137 // Always execute at least one tick. 119 // Always execute at least one tick.
138 amortized_ticks = std::max<u64>(amortized_ticks, 1); 120 amortized_ticks = std::max<u64>(amortized_ticks, 1);
139 121
140 parent.system.CoreTiming().AddTicks(amortized_ticks); 122 parent.system.CoreTiming().AddTicks(amortized_ticks);
141 num_interpreted_instructions = 0;
142 } 123 }
143 124
144 u64 GetTicksRemaining() override { 125 u64 GetTicksRemaining() override {
@@ -156,7 +137,6 @@ public:
156 } 137 }
157 138
158 ARM_Dynarmic_64& parent; 139 ARM_Dynarmic_64& parent;
159 std::size_t num_interpreted_instructions = 0;
160 u64 tpidrro_el0 = 0; 140 u64 tpidrro_el0 = 0;
161 u64 tpidr_el0 = 0; 141 u64 tpidr_el0 = 0;
162 static constexpr u64 minimum_run_cycles = 1000U; 142 static constexpr u64 minimum_run_cycles = 1000U;
@@ -172,6 +152,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable&
172 // Memory 152 // Memory
173 config.page_table = reinterpret_cast<void**>(page_table.pointers.data()); 153 config.page_table = reinterpret_cast<void**>(page_table.pointers.data());
174 config.page_table_address_space_bits = address_space_bits; 154 config.page_table_address_space_bits = address_space_bits;
155 config.page_table_pointer_mask_bits = Common::PageTable::ATTRIBUTE_BITS;
175 config.silently_mirror_page_table = false; 156 config.silently_mirror_page_table = false;
176 config.absolute_offset_page_table = true; 157 config.absolute_offset_page_table = true;
177 config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128; 158 config.detect_misaligned_access_via_page_table = 16 | 32 | 64 | 128;
@@ -231,6 +212,9 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable&
231 if (Settings::values.cpuopt_unsafe_reduce_fp_error) { 212 if (Settings::values.cpuopt_unsafe_reduce_fp_error) {
232 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP; 213 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP;
233 } 214 }
215 if (Settings::values.cpuopt_unsafe_inaccurate_nan) {
216 config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
217 }
234 } 218 }
235 219
236 return std::make_shared<Dynarmic::A64::Jit>(config); 220 return std::make_shared<Dynarmic::A64::Jit>(config);
@@ -240,6 +224,10 @@ void ARM_Dynarmic_64::Run() {
240 jit->Run(); 224 jit->Run();
241} 225}
242 226
227void ARM_Dynarmic_64::ExceptionalExit() {
228 jit->ExceptionalExit();
229}
230
243void ARM_Dynarmic_64::Step() { 231void ARM_Dynarmic_64::Step() {
244 cb->InterpreterFallback(jit->GetPC(), 1); 232 cb->InterpreterFallback(jit->GetPC(), 1);
245} 233}
@@ -248,12 +236,8 @@ ARM_Dynarmic_64::ARM_Dynarmic_64(System& system, CPUInterrupts& interrupt_handle
248 bool uses_wall_clock, ExclusiveMonitor& exclusive_monitor, 236 bool uses_wall_clock, ExclusiveMonitor& exclusive_monitor,
249 std::size_t core_index) 237 std::size_t core_index)
250 : ARM_Interface{system, interrupt_handlers, uses_wall_clock}, 238 : ARM_Interface{system, interrupt_handlers, uses_wall_clock},
251 cb(std::make_unique<DynarmicCallbacks64>(*this)), inner_unicorn{system, interrupt_handlers, 239 cb(std::make_unique<DynarmicCallbacks64>(*this)), core_index{core_index},
252 uses_wall_clock, 240 exclusive_monitor{dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {}
253 ARM_Unicorn::Arch::AArch64,
254 core_index},
255 core_index{core_index}, exclusive_monitor{
256 dynamic_cast<DynarmicExclusiveMonitor&>(exclusive_monitor)} {}
257 241
258ARM_Dynarmic_64::~ARM_Dynarmic_64() = default; 242ARM_Dynarmic_64::~ARM_Dynarmic_64() = default;
259 243
@@ -342,7 +326,17 @@ void ARM_Dynarmic_64::ClearInstructionCache() {
342 jit->ClearCache(); 326 jit->ClearCache();
343} 327}
344 328
329void ARM_Dynarmic_64::InvalidateCacheRange(VAddr addr, std::size_t size) {
330 if (!jit) {
331 return;
332 }
333 jit->InvalidateCacheRange(addr, size);
334}
335
345void ARM_Dynarmic_64::ClearExclusiveState() { 336void ARM_Dynarmic_64::ClearExclusiveState() {
337 if (!jit) {
338 return;
339 }
346 jit->ClearExclusiveState(); 340 jit->ClearExclusiveState();
347} 341}
348 342
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.h b/src/core/arm/dynarmic/arm_dynarmic_64.h
index 403c55961..329b59a32 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.h
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.h
@@ -12,7 +12,6 @@
12#include "common/hash.h" 12#include "common/hash.h"
13#include "core/arm/arm_interface.h" 13#include "core/arm/arm_interface.h"
14#include "core/arm/exclusive_monitor.h" 14#include "core/arm/exclusive_monitor.h"
15#include "core/arm/unicorn/arm_unicorn.h"
16 15
17namespace Core::Memory { 16namespace Core::Memory {
18class Memory; 17class Memory;
@@ -41,6 +40,7 @@ public:
41 void SetPSTATE(u32 pstate) override; 40 void SetPSTATE(u32 pstate) override;
42 void Run() override; 41 void Run() override;
43 void Step() override; 42 void Step() override;
43 void ExceptionalExit() override;
44 VAddr GetTlsAddress() const override; 44 VAddr GetTlsAddress() const override;
45 void SetTlsAddress(VAddr address) override; 45 void SetTlsAddress(VAddr address) override;
46 void SetTPIDR_EL0(u64 value) override; 46 void SetTPIDR_EL0(u64 value) override;
@@ -56,6 +56,7 @@ public:
56 void ClearExclusiveState() override; 56 void ClearExclusiveState() override;
57 57
58 void ClearInstructionCache() override; 58 void ClearInstructionCache() override;
59 void InvalidateCacheRange(VAddr addr, std::size_t size) override;
59 void PageTableChanged(Common::PageTable& new_page_table, 60 void PageTableChanged(Common::PageTable& new_page_table,
60 std::size_t new_address_space_size_in_bits) override; 61 std::size_t new_address_space_size_in_bits) override;
61 62
@@ -71,7 +72,6 @@ private:
71 std::unique_ptr<DynarmicCallbacks64> cb; 72 std::unique_ptr<DynarmicCallbacks64> cb;
72 JitCacheType jit_cache; 73 JitCacheType jit_cache;
73 std::shared_ptr<Dynarmic::A64::Jit> jit; 74 std::shared_ptr<Dynarmic::A64::Jit> jit;
74 ARM_Unicorn inner_unicorn;
75 75
76 std::size_t core_index; 76 std::size_t core_index;
77 DynarmicExclusiveMonitor& exclusive_monitor; 77 DynarmicExclusiveMonitor& exclusive_monitor;