summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/CMakeLists.txt6
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.cpp176
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.h51
3 files changed, 233 insertions, 0 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 174e9dc79..4a9c6fd2f 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -1,6 +1,7 @@
1set(SRCS 1set(SRCS
2 arm/disassembler/arm_disasm.cpp 2 arm/disassembler/arm_disasm.cpp
3 arm/disassembler/load_symbol_map.cpp 3 arm/disassembler/load_symbol_map.cpp
4 arm/dynarmic/arm_dynarmic.cpp
4 arm/dyncom/arm_dyncom.cpp 5 arm/dyncom/arm_dyncom.cpp
5 arm/dyncom/arm_dyncom_dec.cpp 6 arm/dyncom/arm_dyncom_dec.cpp
6 arm/dyncom/arm_dyncom_interpreter.cpp 7 arm/dyncom/arm_dyncom_interpreter.cpp
@@ -141,6 +142,7 @@ set(HEADERS
141 arm/arm_interface.h 142 arm/arm_interface.h
142 arm/disassembler/arm_disasm.h 143 arm/disassembler/arm_disasm.h
143 arm/disassembler/load_symbol_map.h 144 arm/disassembler/load_symbol_map.h
145 arm/dynarmic/arm_dynarmic.h
144 arm/dyncom/arm_dyncom.h 146 arm/dyncom/arm_dyncom.h
145 arm/dyncom/arm_dyncom_dec.h 147 arm/dyncom/arm_dyncom_dec.h
146 arm/dyncom/arm_dyncom_interpreter.h 148 arm/dyncom/arm_dyncom_interpreter.h
@@ -285,6 +287,10 @@ set(HEADERS
285 system.h 287 system.h
286 ) 288 )
287 289
290include_directories(../../externals/dynarmic/include)
291
288create_directory_groups(${SRCS} ${HEADERS}) 292create_directory_groups(${SRCS} ${HEADERS})
289 293
290add_library(core STATIC ${SRCS} ${HEADERS}) 294add_library(core STATIC ${SRCS} ${HEADERS})
295
296target_link_libraries(core dynarmic)
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp
new file mode 100644
index 000000000..46b4d6103
--- /dev/null
+++ b/src/core/arm/dynarmic/arm_dynarmic.cpp
@@ -0,0 +1,176 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/assert.h"
6#include "common/microprofile.h"
7
8#include <dynarmic/dynarmic.h>
9
10#include "core/arm/dynarmic/arm_dynarmic.h"
11#include "core/arm/dyncom/arm_dyncom_interpreter.h"
12#include "core/core.h"
13#include "core/core_timing.h"
14#include "core/hle/svc.h"
15#include "core/memory.h"
16
17static void InterpreterFallback(u32 pc, Dynarmic::Jit* jit, void* user_arg) {
18 ARMul_State* state = static_cast<ARMul_State*>(user_arg);
19
20 state->Reg = jit->Regs();
21 state->Cpsr = jit->Cpsr();
22 state->Reg[15] = pc;
23 state->ExtReg = jit->ExtRegs();
24 state->VFP[VFP_FPSCR] = jit->Fpscr();
25 state->NumInstrsToExecute = 1;
26
27 InterpreterMainLoop(state);
28
29 bool is_thumb = (state->Cpsr & (1 << 5)) != 0;
30 state->Reg[15] &= (is_thumb ? 0xFFFFFFFE : 0xFFFFFFFC);
31
32 jit->Regs() = state->Reg;
33 jit->Cpsr() = state->Cpsr;
34 jit->ExtRegs() = state->ExtReg;
35 jit->SetFpscr(state->VFP[VFP_FPSCR]);
36}
37
38static bool IsReadOnlyMemory(u32 vaddr) {
39 // TODO(bunnei): ImplementMe
40 return false;
41}
42
43static Dynarmic::UserCallbacks GetUserCallbacks(ARMul_State* interpeter_state) {
44 Dynarmic::UserCallbacks user_callbacks{};
45 user_callbacks.InterpreterFallback = &InterpreterFallback;
46 user_callbacks.user_arg = static_cast<void*>(interpeter_state);
47 user_callbacks.CallSVC = &SVC::CallSVC;
48 user_callbacks.IsReadOnlyMemory = &IsReadOnlyMemory;
49 user_callbacks.MemoryRead8 = &Memory::Read8;
50 user_callbacks.MemoryRead16 = &Memory::Read16;
51 user_callbacks.MemoryRead32 = &Memory::Read32;
52 user_callbacks.MemoryRead64 = &Memory::Read64;
53 user_callbacks.MemoryWrite8 = &Memory::Write8;
54 user_callbacks.MemoryWrite16 = &Memory::Write16;
55 user_callbacks.MemoryWrite32 = &Memory::Write32;
56 user_callbacks.MemoryWrite64 = &Memory::Write64;
57 return user_callbacks;
58}
59
60ARM_Dynarmic::ARM_Dynarmic(PrivilegeMode initial_mode) {
61 interpreter_state = std::make_unique<ARMul_State>(initial_mode);
62 jit = std::make_unique<Dynarmic::Jit>(GetUserCallbacks(interpreter_state.get()));
63}
64
65void ARM_Dynarmic::SetPC(u32 pc) {
66 jit->Regs()[15] = pc;
67}
68
69u32 ARM_Dynarmic::GetPC() const {
70 return jit->Regs()[15];
71}
72
73u32 ARM_Dynarmic::GetReg(int index) const {
74 return jit->Regs()[index];
75}
76
77void ARM_Dynarmic::SetReg(int index, u32 value) {
78 jit->Regs()[index] = value;
79}
80
81u32 ARM_Dynarmic::GetVFPReg(int index) const {
82 return jit->ExtRegs()[index];
83}
84
85void ARM_Dynarmic::SetVFPReg(int index, u32 value) {
86 jit->ExtRegs()[index] = value;
87}
88
89u32 ARM_Dynarmic::GetVFPSystemReg(VFPSystemRegister reg) const {
90 // TODO(bunnei): ImplementMe
91 UNIMPLEMENTED();
92 return 0;
93}
94
95void ARM_Dynarmic::SetVFPSystemReg(VFPSystemRegister reg, u32 value) {
96 // TODO(bunnei): ImplementMe
97 UNIMPLEMENTED();
98}
99
100u32 ARM_Dynarmic::GetCPSR() const {
101 return jit->Cpsr();
102}
103
104void ARM_Dynarmic::SetCPSR(u32 cpsr) {
105 jit->Cpsr() = cpsr;
106}
107
108u32 ARM_Dynarmic::GetCP15Register(CP15Register reg) {
109 return interpreter_state->CP15[reg];
110}
111
112void ARM_Dynarmic::SetCP15Register(CP15Register reg, u32 value) {
113 interpreter_state->CP15[reg] = value;
114}
115
116void ARM_Dynarmic::AddTicks(u64 ticks) {
117 down_count -= ticks;
118 if (down_count < 0) {
119 CoreTiming::Advance();
120 }
121}
122
123MICROPROFILE_DEFINE(ARM_Jit, "ARM JIT", "ARM JIT", MP_RGB(255, 64, 64));
124
125void ARM_Dynarmic::ExecuteInstructions(int num_instructions) {
126 MICROPROFILE_SCOPE(ARM_Jit);
127
128 jit->Run(static_cast<unsigned>(num_instructions));
129
130 AddTicks(num_instructions);
131}
132
133void ARM_Dynarmic::ResetContext(Core::ThreadContext& context, u32 stack_top, u32 entry_point, u32 arg) {
134 memset(&context, 0, sizeof(Core::ThreadContext));
135
136 context.cpu_registers[0] = arg;
137 context.pc = entry_point;
138 context.sp = stack_top;
139 context.cpsr = USER32MODE | ((entry_point & 1) << 5); // Usermode and THUMB mode
140}
141
142void ARM_Dynarmic::SaveContext(Core::ThreadContext& ctx) {
143 memcpy(ctx.cpu_registers, jit->Regs().data(), sizeof(ctx.cpu_registers));
144 memcpy(ctx.fpu_registers, jit->ExtRegs().data(), sizeof(ctx.fpu_registers));
145
146 ctx.sp = jit->Regs()[13];
147 ctx.lr = jit->Regs()[14];
148 ctx.pc = jit->Regs()[15];
149 ctx.cpsr = jit->Cpsr();
150
151 ctx.fpscr = jit->Fpscr();
152 ctx.fpexc = interpreter_state->VFP[VFP_FPEXC];
153}
154
155void ARM_Dynarmic::LoadContext(const Core::ThreadContext& ctx) {
156 memcpy(jit->Regs().data(), ctx.cpu_registers, sizeof(ctx.cpu_registers));
157 memcpy(jit->ExtRegs().data(), ctx.fpu_registers, sizeof(ctx.fpu_registers));
158
159 jit->Regs()[13] = ctx.sp;
160 jit->Regs()[14] = ctx.lr;
161 jit->Regs()[15] = ctx.pc;
162 jit->Cpsr() = ctx.cpsr;
163
164 jit->SetFpscr(ctx.fpscr);
165 interpreter_state->VFP[VFP_FPEXC] = ctx.fpexc;
166}
167
168void ARM_Dynarmic::PrepareReschedule() {
169 if (jit->IsExecuting()) {
170 jit->HaltExecution();
171 }
172}
173
174void ARM_Dynarmic::ClearInstructionCache() {
175 jit->ClearCache();
176}
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h
new file mode 100644
index 000000000..6cae56737
--- /dev/null
+++ b/src/core/arm/dynarmic/arm_dynarmic.h
@@ -0,0 +1,51 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8
9#include <dynarmic/dynarmic.h>
10
11#include "common/common_types.h"
12
13#include "core/arm/arm_interface.h"
14#include "core/arm/skyeye_common/armstate.h"
15
16namespace Core {
17struct ThreadContext;
18}
19
20class ARM_Dynarmic final : virtual public ARM_Interface {
21public:
22 ARM_Dynarmic(PrivilegeMode initial_mode);
23
24 void SetPC(u32 pc) override;
25 u32 GetPC() const override;
26 u32 GetReg(int index) const override;
27 void SetReg(int index, u32 value) override;
28 u32 GetVFPReg(int index) const override;
29 void SetVFPReg(int index, u32 value) override;
30 u32 GetVFPSystemReg(VFPSystemRegister reg) const override;
31 void SetVFPSystemReg(VFPSystemRegister reg, u32 value) override;
32 u32 GetCPSR() const override;
33 void SetCPSR(u32 cpsr) override;
34 u32 GetCP15Register(CP15Register reg) override;
35 void SetCP15Register(CP15Register reg, u32 value) override;
36
37 void AddTicks(u64 ticks) override;
38
39 void ResetContext(Core::ThreadContext& context, u32 stack_top, u32 entry_point, u32 arg) override;
40 void SaveContext(Core::ThreadContext& ctx) override;
41 void LoadContext(const Core::ThreadContext& ctx) override;
42
43 void PrepareReschedule() override;
44 void ExecuteInstructions(int num_instructions) override;
45
46 void ClearInstructionCache() override;
47
48private:
49 std::unique_ptr<Dynarmic::Jit> jit;
50 std::unique_ptr<ARMul_State> interpreter_state;
51};