summaryrefslogtreecommitdiff
path: root/src/core/arm/dynarmic
diff options
context:
space:
mode:
authorGravatar bunnei2017-10-09 23:56:20 -0400
committerGravatar bunnei2017-10-09 23:56:20 -0400
commitb1d5db1cf60344b6b081c9d03cb6ccc3264326cd (patch)
treefde377c4ba3c0f92c032e6f5ec8627aae37270ef /src/core/arm/dynarmic
parentloader: Various improvements for NSO/NRO loaders. (diff)
parentMerge pull request #2996 from MerryMage/split-travis (diff)
downloadyuzu-b1d5db1cf60344b6b081c9d03cb6ccc3264326cd.tar.gz
yuzu-b1d5db1cf60344b6b081c9d03cb6ccc3264326cd.tar.xz
yuzu-b1d5db1cf60344b6b081c9d03cb6ccc3264326cd.zip
Merge remote-tracking branch 'upstream/master' into nx
# Conflicts: # src/core/CMakeLists.txt # src/core/arm/dynarmic/arm_dynarmic.cpp # src/core/arm/dyncom/arm_dyncom.cpp # src/core/hle/kernel/process.cpp # src/core/hle/kernel/thread.cpp # src/core/hle/kernel/thread.h # src/core/hle/kernel/vm_manager.cpp # src/core/loader/3dsx.cpp # src/core/loader/elf.cpp # src/core/loader/ncch.cpp # src/core/memory.cpp # src/core/memory.h # src/core/memory_setup.h
Diffstat (limited to 'src/core/arm/dynarmic')
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.cpp93
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.h17
2 files changed, 48 insertions, 62 deletions
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp
index 0ea1d76e4..6dcab5bab 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic.cpp
@@ -16,24 +16,6 @@
16 16
17static void InterpreterFallback(u64 pc, Dynarmic::Jit* jit, void* user_arg) { 17static void InterpreterFallback(u64 pc, Dynarmic::Jit* jit, void* user_arg) {
18 UNIMPLEMENTED_MSG("InterpreterFallback for ARM64 JIT does not exist!"); 18 UNIMPLEMENTED_MSG("InterpreterFallback for ARM64 JIT does not exist!");
19 //ARMul_State* state = static_cast<ARMul_State*>(user_arg);
20
21 //state->Reg = jit->Regs();
22 //state->Cpsr = jit->Cpsr();
23 //state->Reg[15] = static_cast<u32>(pc);
24 //state->ExtReg = jit->ExtRegs();
25 //state->VFP[VFP_FPSCR] = jit->Fpscr();
26 //state->NumInstrsToExecute = 1;
27
28 //InterpreterMainLoop(state);
29
30 //bool is_thumb = (state->Cpsr & (1 << 5)) != 0;
31 //state->Reg[15] &= (is_thumb ? 0xFFFFFFFE : 0xFFFFFFFC);
32
33 //jit->Regs() = state->Reg;
34 //jit->Cpsr() = state->Cpsr;
35 //jit->ExtRegs() = state->ExtReg;
36 //jit->SetFpscr(state->VFP[VFP_FPSCR]);
37} 19}
38 20
39static bool IsReadOnlyMemory(u64 vaddr) { 21static bool IsReadOnlyMemory(u64 vaddr) {
@@ -73,11 +55,10 @@ void MemoryWrite64(const u64 addr, const u64 data) {
73 Memory::Write64(static_cast<VAddr>(addr), data); 55 Memory::Write64(static_cast<VAddr>(addr), data);
74} 56}
75 57
76static Dynarmic::UserCallbacks GetUserCallbacks( 58static Dynarmic::UserCallbacks GetUserCallbacks(ARM_Dynarmic* this_) {
77 const std::shared_ptr<ARMul_State>& interpeter_state) {
78 Dynarmic::UserCallbacks user_callbacks{}; 59 Dynarmic::UserCallbacks user_callbacks{};
79 //user_callbacks.InterpreterFallback = &InterpreterFallback; 60 user_callbacks.InterpreterFallback = &InterpreterFallback;
80 //user_callbacks.user_arg = static_cast<void*>(interpeter_state.get()); 61 user_callbacks.user_arg = static_cast<void*>(this_);
81 user_callbacks.CallSVC = &SVC::CallSVC; 62 user_callbacks.CallSVC = &SVC::CallSVC;
82 user_callbacks.memory.IsReadOnlyMemory = &IsReadOnlyMemory; 63 user_callbacks.memory.IsReadOnlyMemory = &IsReadOnlyMemory;
83 user_callbacks.memory.ReadCode = &MemoryRead32; 64 user_callbacks.memory.ReadCode = &MemoryRead32;
@@ -90,13 +71,13 @@ static Dynarmic::UserCallbacks GetUserCallbacks(
90 user_callbacks.memory.Write32 = &MemoryWrite32; 71 user_callbacks.memory.Write32 = &MemoryWrite32;
91 user_callbacks.memory.Write64 = &MemoryWrite64; 72 user_callbacks.memory.Write64 = &MemoryWrite64;
92 //user_callbacks.page_table = Memory::GetCurrentPageTablePointers(); 73 //user_callbacks.page_table = Memory::GetCurrentPageTablePointers();
93 user_callbacks.coprocessors[15] = std::make_shared<DynarmicCP15>(interpeter_state);
94 return user_callbacks; 74 return user_callbacks;
95} 75}
96 76
97ARM_Dynarmic::ARM_Dynarmic(PrivilegeMode initial_mode) { 77ARM_Dynarmic::ARM_Dynarmic(PrivilegeMode initial_mode) {
98 interpreter_state = std::make_shared<ARMul_State>(initial_mode); 78}
99 jit = std::make_unique<Dynarmic::Jit>(GetUserCallbacks(interpreter_state), Dynarmic::Arch::ARM64); 79
80void ARM_Dynarmic::MapBackingMemory(VAddr address, size_t size, u8* memory, Kernel::VMAPermission perms) {
100} 81}
101 82
102void ARM_Dynarmic::SetPC(u64 pc) { 83void ARM_Dynarmic::SetPC(u64 pc) {
@@ -115,30 +96,26 @@ void ARM_Dynarmic::SetReg(int index, u64 value) {
115 jit->Regs64()[index] = value; 96 jit->Regs64()[index] = value;
116} 97}
117 98
99const u128& ARM_Dynarmic::GetExtReg(int index) const {
100 return jit->ExtRegs64()[index];
101}
102
103void ARM_Dynarmic::SetExtReg(int index, u128& value) {
104 jit->ExtRegs64()[index] = value;
105}
106
118u32 ARM_Dynarmic::GetVFPReg(int index) const { 107u32 ARM_Dynarmic::GetVFPReg(int index) const {
119 return jit->ExtRegs()[index]; 108 return {};
120} 109}
121 110
122void ARM_Dynarmic::SetVFPReg(int index, u32 value) { 111void ARM_Dynarmic::SetVFPReg(int index, u32 value) {
123 jit->ExtRegs()[index] = value;
124} 112}
125 113
126u32 ARM_Dynarmic::GetVFPSystemReg(VFPSystemRegister reg) const { 114u32 ARM_Dynarmic::GetVFPSystemReg(VFPSystemRegister reg) const {
127 if (reg == VFP_FPSCR) { 115 return {};
128 return jit->Fpscr();
129 }
130
131 // Dynarmic does not implement and/or expose other VFP registers, fallback to interpreter state
132 return interpreter_state->VFP[reg];
133} 116}
134 117
135void ARM_Dynarmic::SetVFPSystemReg(VFPSystemRegister reg, u32 value) { 118void ARM_Dynarmic::SetVFPSystemReg(VFPSystemRegister reg, u32 value) {
136 if (reg == VFP_FPSCR) {
137 jit->SetFpscr(value);
138 }
139
140 // Dynarmic does not implement and/or expose other VFP registers, fallback to interpreter state
141 interpreter_state->VFP[reg] = value;
142} 119}
143 120
144u32 ARM_Dynarmic::GetCPSR() const { 121u32 ARM_Dynarmic::GetCPSR() const {
@@ -150,11 +127,10 @@ void ARM_Dynarmic::SetCPSR(u32 cpsr) {
150} 127}
151 128
152u32 ARM_Dynarmic::GetCP15Register(CP15Register reg) { 129u32 ARM_Dynarmic::GetCP15Register(CP15Register reg) {
153 return interpreter_state->CP15[reg]; 130 return {};
154} 131}
155 132
156void ARM_Dynarmic::SetCP15Register(CP15Register reg, u32 value) { 133void ARM_Dynarmic::SetCP15Register(CP15Register reg, u32 value) {
157 interpreter_state->CP15[reg] = value;
158} 134}
159 135
160VAddr ARM_Dynarmic::GetTlsAddress() const { 136VAddr ARM_Dynarmic::GetTlsAddress() const {
@@ -165,51 +141,39 @@ void ARM_Dynarmic::SetTlsAddress(VAddr address) {
165 jit->TlsAddr() = address; 141 jit->TlsAddr() = address;
166} 142}
167 143
168void ARM_Dynarmic::AddTicks(u64 ticks) {
169 down_count -= ticks;
170 if (down_count < 0) {
171 CoreTiming::Advance();
172 }
173}
174
175MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64)); 144MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64));
176 145
177void ARM_Dynarmic::ExecuteInstructions(int num_instructions) { 146void ARM_Dynarmic::ExecuteInstructions(int num_instructions) {
147 ASSERT(Memory::GetCurrentPageTable() == current_page_table);
178 MICROPROFILE_SCOPE(ARM_Jit); 148 MICROPROFILE_SCOPE(ARM_Jit);
179 149
180 unsigned ticks_executed = jit->Run(1 /*static_cast<unsigned>(num_instructions)*/); 150 std::size_t ticks_executed = jit->Run(static_cast<unsigned>(num_instructions));
181 151
182 AddTicks(ticks_executed); 152 CoreTiming::AddTicks(ticks_executed);
183} 153}
184 154
185void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) { 155void ARM_Dynarmic::SaveContext(ARM_Interface::ThreadContext& ctx) {
186 memcpy(ctx.cpu_registers, jit->Regs64().data(), sizeof(ctx.cpu_registers)); 156 memcpy(ctx.cpu_registers, jit->Regs64().data(), sizeof(ctx.cpu_registers));
187 //memcpy(ctx.fpu_registers, jit->ExtRegs().data(), sizeof(ctx.fpu_registers)); 157 memcpy(ctx.fpu_registers, jit->ExtRegs64().data(), sizeof(ctx.fpu_registers));
188 158
189 ctx.lr = jit->Regs64()[30]; 159 ctx.lr = jit->Regs64()[30];
190 ctx.sp = jit->Regs64()[31]; 160 ctx.sp = jit->Regs64()[31];
191 ctx.pc = jit->Regs64()[32]; 161 ctx.pc = jit->Regs64()[32];
192 ctx.cpsr = jit->Cpsr(); 162 ctx.cpsr = jit->Cpsr();
193 163
194 ctx.fpscr = jit->Fpscr();
195 ctx.fpexc = interpreter_state->VFP[VFP_FPEXC];
196
197 // TODO(bunnei): Fix once we have proper support for tpidrro_el0, etc. in the JIT 164 // TODO(bunnei): Fix once we have proper support for tpidrro_el0, etc. in the JIT
198 ctx.tls_address = jit->TlsAddr(); 165 ctx.tls_address = jit->TlsAddr();
199} 166}
200 167
201void ARM_Dynarmic::LoadContext(const ARM_Interface::ThreadContext& ctx) { 168void ARM_Dynarmic::LoadContext(const ARM_Interface::ThreadContext& ctx) {
202 memcpy(jit->Regs64().data(), ctx.cpu_registers, sizeof(ctx.cpu_registers)); 169 memcpy(jit->Regs64().data(), ctx.cpu_registers, sizeof(ctx.cpu_registers));
203 //memcpy(jit->ExtRegs().data(), ctx.fpu_registers, sizeof(ctx.fpu_registers)); 170 memcpy(jit->ExtRegs64().data(), ctx.fpu_registers, sizeof(ctx.fpu_registers));
204 171
205 jit->Regs64()[30] = ctx.lr; 172 jit->Regs64()[30] = ctx.lr;
206 jit->Regs64()[31] = ctx.sp; 173 jit->Regs64()[31] = ctx.sp;
207 jit->Regs64()[32] = ctx.pc; 174 jit->Regs64()[32] = ctx.pc;
208 jit->Cpsr() = ctx.cpsr; 175 jit->Cpsr() = ctx.cpsr;
209 176
210 jit->SetFpscr(ctx.fpscr);
211 interpreter_state->VFP[VFP_FPEXC] = ctx.fpexc;
212
213 // TODO(bunnei): Fix once we have proper support for tpidrro_el0, etc. in the JIT 177 // TODO(bunnei): Fix once we have proper support for tpidrro_el0, etc. in the JIT
214 jit->TlsAddr() = ctx.tls_address; 178 jit->TlsAddr() = ctx.tls_address;
215} 179}
@@ -223,3 +187,16 @@ void ARM_Dynarmic::PrepareReschedule() {
223void ARM_Dynarmic::ClearInstructionCache() { 187void ARM_Dynarmic::ClearInstructionCache() {
224 jit->ClearCache(); 188 jit->ClearCache();
225} 189}
190
191void ARM_Dynarmic::PageTableChanged() {
192 current_page_table = Memory::GetCurrentPageTable();
193
194 auto iter = jits.find(current_page_table);
195 if (iter != jits.end()) {
196 jit = iter->second.get();
197 return;
198 }
199
200 jit = new Dynarmic::Jit(GetUserCallbacks(this), Dynarmic::Arch::ARM64);
201 jits.emplace(current_page_table, std::unique_ptr<Dynarmic::Jit>(jit));
202}
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h
index fcdc1c0e0..6567359b0 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.h
+++ b/src/core/arm/dynarmic/arm_dynarmic.h
@@ -4,20 +4,29 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <map>
7#include <memory> 8#include <memory>
8#include <dynarmic/dynarmic.h> 9#include <dynarmic/dynarmic.h>
9#include "common/common_types.h" 10#include "common/common_types.h"
10#include "core/arm/arm_interface.h" 11#include "core/arm/arm_interface.h"
11#include "core/arm/skyeye_common/armstate.h" 12#include "core/arm/skyeye_common/armstate.h"
12 13
14namespace Memory {
15struct PageTable;
16} // namespace Memory
17
13class ARM_Dynarmic final : public ARM_Interface { 18class ARM_Dynarmic final : public ARM_Interface {
14public: 19public:
15 ARM_Dynarmic(PrivilegeMode initial_mode); 20 ARM_Dynarmic(PrivilegeMode initial_mode);
16 21
22 void MapBackingMemory(VAddr address, size_t size, u8* memory, Kernel::VMAPermission perms) override;
23
17 void SetPC(u64 pc) override; 24 void SetPC(u64 pc) override;
18 u64 GetPC() const override; 25 u64 GetPC() const override;
19 u64 GetReg(int index) const override; 26 u64 GetReg(int index) const override;
20 void SetReg(int index, u64 value) override; 27 void SetReg(int index, u64 value) override;
28 const u128& GetExtReg(int index) const override;
29 void SetExtReg(int index, u128& value) override;
21 u32 GetVFPReg(int index) const override; 30 u32 GetVFPReg(int index) const override;
22 void SetVFPReg(int index, u32 value) override; 31 void SetVFPReg(int index, u32 value) override;
23 u32 GetVFPSystemReg(VFPSystemRegister reg) const override; 32 u32 GetVFPSystemReg(VFPSystemRegister reg) const override;
@@ -29,8 +38,6 @@ public:
29 VAddr GetTlsAddress() const override; 38 VAddr GetTlsAddress() const override;
30 void SetTlsAddress(VAddr address) override; 39 void SetTlsAddress(VAddr address) override;
31 40
32 void AddTicks(u64 ticks) override;
33
34 void SaveContext(ThreadContext& ctx) override; 41 void SaveContext(ThreadContext& ctx) override;
35 void LoadContext(const ThreadContext& ctx) override; 42 void LoadContext(const ThreadContext& ctx) override;
36 43
@@ -38,8 +45,10 @@ public:
38 void ExecuteInstructions(int num_instructions) override; 45 void ExecuteInstructions(int num_instructions) override;
39 46
40 void ClearInstructionCache() override; 47 void ClearInstructionCache() override;
48 void PageTableChanged() override;
41 49
42private: 50private:
43 std::unique_ptr<Dynarmic::Jit> jit; 51 Dynarmic::Jit* jit = nullptr;
44 std::shared_ptr<ARMul_State> interpreter_state; 52 Memory::PageTable* current_page_table = nullptr;
53 std::map<Memory::PageTable*, std::unique_ptr<Dynarmic::Jit>> jits;
45}; 54};