summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/arm/arm_interface.h29
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.cpp19
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.h5
-rw-r--r--src/core/arm/unicorn/arm_unicorn.cpp9
-rw-r--r--src/core/arm/unicorn/arm_unicorn.h4
-rw-r--r--src/core/core.cpp12
-rw-r--r--src/core/core.h4
7 files changed, 41 insertions, 41 deletions
diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index 6667c7dba..32ff3c345 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -25,19 +25,11 @@ public:
25 VAddr tls_address; 25 VAddr tls_address;
26 }; 26 };
27 27
28 /** 28 /// Runs the CPU until an event happens
29 * Runs the CPU for the given number of instructions 29 virtual void Run() = 0;
30 * @param num_instructions Number of instructions to run
31 */
32 void Run(int num_instructions) {
33 ExecuteInstructions(num_instructions);
34 this->num_instructions += num_instructions;
35 }
36 30
37 /// Step CPU by one instruction 31 /// Step CPU by one instruction
38 void Step() { 32 virtual void Step() = 0;
39 Run(1);
40 }
41 33
42 /// Maps a backing memory region for the CPU 34 /// Maps a backing memory region for the CPU
43 virtual void MapBackingMemory(VAddr address, size_t size, u8* memory, 35 virtual void MapBackingMemory(VAddr address, size_t size, u8* memory,
@@ -126,19 +118,4 @@ public:
126 118
127 /// Prepare core for thread reschedule (if needed to correctly handle state) 119 /// Prepare core for thread reschedule (if needed to correctly handle state)
128 virtual void PrepareReschedule() = 0; 120 virtual void PrepareReschedule() = 0;
129
130 /// Getter for num_instructions
131 u64 GetNumInstructions() const {
132 return num_instructions;
133 }
134
135protected:
136 /**
137 * Executes the given number of instructions
138 * @param num_instructions Number of instructions to executes
139 */
140 virtual void ExecuteInstructions(int num_instructions) = 0;
141
142private:
143 u64 num_instructions = 0; ///< Number of instructions executed
144}; 121};
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp
index 0902c6df3..7d83f9717 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic.cpp
@@ -122,11 +122,22 @@ std::unique_ptr<Dynarmic::A64::Jit> MakeJit(const std::unique_ptr<ARM_Dynarmic_C
122 return std::make_unique<Dynarmic::A64::Jit>(config); 122 return std::make_unique<Dynarmic::A64::Jit>(config);
123} 123}
124 124
125void ARM_Dynarmic::Run() {
126 ASSERT(Memory::GetCurrentPageTable() == current_page_table);
127
128 jit->Run();
129}
130
131void ARM_Dynarmic::Step() {
132 cb->InterpreterFallback(jit->GetPC(), 1);
133}
134
125ARM_Dynarmic::ARM_Dynarmic() 135ARM_Dynarmic::ARM_Dynarmic()
126 : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), jit(MakeJit(cb)) { 136 : cb(std::make_unique<ARM_Dynarmic_Callbacks>(*this)), jit(MakeJit(cb)) {
127 ARM_Interface::ThreadContext ctx; 137 ARM_Interface::ThreadContext ctx;
128 inner_unicorn.SaveContext(ctx); 138 inner_unicorn.SaveContext(ctx);
129 LoadContext(ctx); 139 LoadContext(ctx);
140 PageTableChanged();
130} 141}
131 142
132ARM_Dynarmic::~ARM_Dynarmic() = default; 143ARM_Dynarmic::~ARM_Dynarmic() = default;
@@ -189,13 +200,6 @@ void ARM_Dynarmic::SetTlsAddress(u64 address) {
189 cb->tpidrro_el0 = address; 200 cb->tpidrro_el0 = address;
190} 201}
191 202
192void ARM_Dynarmic::ExecuteInstructions(int num_instructions) {
193 cb->ticks_remaining = num_instructions;
194 jit->Run();
195 CoreTiming::AddTicks(num_instructions - cb->num_interpreted_instructions);
196 cb->num_interpreted_instructions = 0;
197}
198
199void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) { 203void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) {
200 ctx.cpu_registers = jit->GetRegisters(); 204 ctx.cpu_registers = jit->GetRegisters();
201 ctx.sp = jit->GetSP(); 205 ctx.sp = jit->GetSP();
@@ -228,4 +232,5 @@ void ARM_Dynarmic::ClearInstructionCache() {
228 232
229void ARM_Dynarmic::PageTableChanged() { 233void ARM_Dynarmic::PageTableChanged() {
230 jit = MakeJit(cb); 234 jit = MakeJit(cb);
235 current_page_table = Memory::GetCurrentPageTable();
231} 236}
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h
index fd1a44802..128669d01 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.h
+++ b/src/core/arm/dynarmic/arm_dynarmic.h
@@ -29,6 +29,8 @@ public:
29 u32 GetVFPReg(int index) const override; 29 u32 GetVFPReg(int index) const override;
30 void SetVFPReg(int index, u32 value) override; 30 void SetVFPReg(int index, u32 value) override;
31 u32 GetCPSR() const override; 31 u32 GetCPSR() const override;
32 void Run() override;
33 void Step() override;
32 void SetCPSR(u32 cpsr) override; 34 void SetCPSR(u32 cpsr) override;
33 VAddr GetTlsAddress() const override; 35 VAddr GetTlsAddress() const override;
34 void SetTlsAddress(VAddr address) override; 36 void SetTlsAddress(VAddr address) override;
@@ -37,7 +39,6 @@ public:
37 void LoadContext(const ThreadContext& ctx) override; 39 void LoadContext(const ThreadContext& ctx) override;
38 40
39 void PrepareReschedule() override; 41 void PrepareReschedule() override;
40 void ExecuteInstructions(int num_instructions) override;
41 42
42 void ClearInstructionCache() override; 43 void ClearInstructionCache() override;
43 void PageTableChanged() override; 44 void PageTableChanged() override;
@@ -47,4 +48,6 @@ private:
47 std::unique_ptr<ARM_Dynarmic_Callbacks> cb; 48 std::unique_ptr<ARM_Dynarmic_Callbacks> cb;
48 std::unique_ptr<Dynarmic::A64::Jit> jit; 49 std::unique_ptr<Dynarmic::A64::Jit> jit;
49 ARM_Unicorn inner_unicorn; 50 ARM_Unicorn inner_unicorn;
51
52 Memory::PageTable* current_page_table = nullptr;
50}; 53};
diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp
index 162c766fd..bd98cb160 100644
--- a/src/core/arm/unicorn/arm_unicorn.cpp
+++ b/src/core/arm/unicorn/arm_unicorn.cpp
@@ -2,6 +2,7 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm>
5#include <unicorn/arm64.h> 6#include <unicorn/arm64.h>
6#include "common/assert.h" 7#include "common/assert.h"
7#include "common/microprofile.h" 8#include "common/microprofile.h"
@@ -153,6 +154,14 @@ void ARM_Unicorn::SetTlsAddress(VAddr base) {
153 CHECKED(uc_reg_write(uc, UC_ARM64_REG_TPIDRRO_EL0, &base)); 154 CHECKED(uc_reg_write(uc, UC_ARM64_REG_TPIDRRO_EL0, &base));
154} 155}
155 156
157void ARM_Unicorn::Run() {
158 ExecuteInstructions(std::max(CoreTiming::GetDowncount(), 0));
159}
160
161void ARM_Unicorn::Step() {
162 ExecuteInstructions(1);
163}
164
156MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64)); 165MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64));
157 166
158void ARM_Unicorn::ExecuteInstructions(int num_instructions) { 167void ARM_Unicorn::ExecuteInstructions(int num_instructions) {
diff --git a/src/core/arm/unicorn/arm_unicorn.h b/src/core/arm/unicorn/arm_unicorn.h
index 00b5b1865..b99b58e4c 100644
--- a/src/core/arm/unicorn/arm_unicorn.h
+++ b/src/core/arm/unicorn/arm_unicorn.h
@@ -30,7 +30,9 @@ public:
30 void SaveContext(ThreadContext& ctx) override; 30 void SaveContext(ThreadContext& ctx) override;
31 void LoadContext(const ThreadContext& ctx) override; 31 void LoadContext(const ThreadContext& ctx) override;
32 void PrepareReschedule() override; 32 void PrepareReschedule() override;
33 void ExecuteInstructions(int num_instructions) override; 33 void ExecuteInstructions(int num_instructions);
34 void Run() override;
35 void Step() override;
34 void ClearInstructionCache() override; 36 void ClearInstructionCache() override;
35 void PageTableChanged() override{}; 37 void PageTableChanged() override{};
36 38
diff --git a/src/core/core.cpp b/src/core/core.cpp
index ac6cb9e6e..183c5109c 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -26,7 +26,7 @@ namespace Core {
26 26
27/*static*/ System System::s_instance; 27/*static*/ System System::s_instance;
28 28
29System::ResultStatus System::RunLoop(int tight_loop) { 29System::ResultStatus System::RunLoop(bool tight_loop) {
30 status = ResultStatus::Success; 30 status = ResultStatus::Success;
31 if (!cpu_core) { 31 if (!cpu_core) {
32 return ResultStatus::ErrorNotInitialized; 32 return ResultStatus::ErrorNotInitialized;
@@ -40,7 +40,7 @@ System::ResultStatus System::RunLoop(int tight_loop) {
40 if (GDBStub::GetCpuHaltFlag()) { 40 if (GDBStub::GetCpuHaltFlag()) {
41 if (GDBStub::GetCpuStepFlag()) { 41 if (GDBStub::GetCpuStepFlag()) {
42 GDBStub::SetCpuStepFlag(false); 42 GDBStub::SetCpuStepFlag(false);
43 tight_loop = 1; 43 tight_loop = false;
44 } else { 44 } else {
45 return ResultStatus::Success; 45 return ResultStatus::Success;
46 } 46 }
@@ -56,7 +56,11 @@ System::ResultStatus System::RunLoop(int tight_loop) {
56 PrepareReschedule(); 56 PrepareReschedule();
57 } else { 57 } else {
58 CoreTiming::Advance(); 58 CoreTiming::Advance();
59 cpu_core->Run(tight_loop); 59 if (tight_loop) {
60 cpu_core->Run();
61 } else {
62 cpu_core->Step();
63 }
60 } 64 }
61 65
62 HW::Update(); 66 HW::Update();
@@ -66,7 +70,7 @@ System::ResultStatus System::RunLoop(int tight_loop) {
66} 70}
67 71
68System::ResultStatus System::SingleStep() { 72System::ResultStatus System::SingleStep() {
69 return RunLoop(1); 73 return RunLoop(false);
70} 74}
71 75
72System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& filepath) { 76System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& filepath) {
diff --git a/src/core/core.h b/src/core/core.h
index 635109b21..552c8f5ee 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -53,10 +53,10 @@ public:
53 * is not required to do a full dispatch with each instruction. NOTE: the number of instructions 53 * is not required to do a full dispatch with each instruction. NOTE: the number of instructions
54 * requested is not guaranteed to run, as this will be interrupted preemptively if a hardware 54 * requested is not guaranteed to run, as this will be interrupted preemptively if a hardware
55 * update is requested (e.g. on a thread switch). 55 * update is requested (e.g. on a thread switch).
56 * @param tight_loop Number of instructions to execute. 56 * @param tight_loop If false, the CPU single-steps.
57 * @return Result status, indicating whether or not the operation succeeded. 57 * @return Result status, indicating whether or not the operation succeeded.
58 */ 58 */
59 ResultStatus RunLoop(int tight_loop = 100000); 59 ResultStatus RunLoop(bool tight_loop = true);
60 60
61 /** 61 /**
62 * Step the CPU one instruction 62 * Step the CPU one instruction