Skip to content

Commit 7295ebc

Browse files
committed
Merge @Wunkolo AArch64 backend PR (xenia-project#2259)
1 parent f65f044 commit 7295ebc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+11536
-73
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,6 @@
106106
[submodule "third_party/libusb"]
107107
path = third_party/libusb
108108
url = https://github.com/libusb/libusb.git
109+
[submodule "third_party/oaknut"]
110+
path = third_party/oaknut
111+
url = https://github.com/merryhime/oaknut

premake5.lua

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ filter("configurations:Checked")
6161
"DEBUG",
6262
})
6363

64-
filter({"configurations:Checked", "platforms:Windows"})
64+
filter({"configurations:Checked", "platforms:Windows-*"})
6565
buildoptions({
6666
"/RTCsu", -- Full Run-Time Checks.
6767
})
@@ -182,7 +182,7 @@ filter("platforms:Android-*")
182182
"log",
183183
})
184184

185-
filter("platforms:Windows")
185+
filter("platforms:Windows-*")
186186
system("windows")
187187
toolset("msc")
188188
buildoptions({
@@ -200,8 +200,12 @@ filter("platforms:Windows")
200200
"_CRT_SECURE_NO_WARNINGS",
201201
"WIN32",
202202
"_WIN64=1",
203-
"_AMD64=1",
204203
})
204+
filter("architecture:x86_64")
205+
defines({
206+
"_AMD64=1",
207+
})
208+
filter({})
205209
linkoptions({
206210
"/ignore:4006", -- Ignores complaints about empty obj files.
207211
"/ignore:4221",
@@ -219,7 +223,7 @@ filter("platforms:Windows")
219223
})
220224

221225
-- Embed the manifest for things like dependencies and DPI awareness.
222-
filter({"platforms:Windows", "kind:ConsoleApp or WindowedApp"})
226+
filter({"platforms:Windows-*", "kind:ConsoleApp or WindowedApp"})
223227
files({
224228
"src/xenia/base/app_win32.manifest"
225229
})
@@ -249,7 +253,12 @@ workspace("xenia")
249253
["ARCHS"] = "x86_64"
250254
})
251255
elseif os.istarget("windows") then
252-
platforms({"Windows"})
256+
platforms({"Windows-ARM64", "Windows-x86_64"})
257+
filter("platforms:Windows-ARM64")
258+
architecture("ARM64")
259+
filter("platforms:Windows-x86_64")
260+
architecture("x86_64")
261+
filter({})
253262
-- 10.0.15063.0: ID3D12GraphicsCommandList1::SetSamplePositions.
254263
-- 10.0.19041.0: D3D12_HEAP_FLAG_CREATE_NOT_ZEROED.
255264
-- 10.0.22000.0: DWMWA_WINDOW_CORNER_PREFERENCE.
@@ -311,7 +320,13 @@ workspace("xenia")
311320
include("src/xenia/apu/nop")
312321
include("src/xenia/base")
313322
include("src/xenia/cpu")
314-
include("src/xenia/cpu/backend/x64")
323+
324+
filter("architecture:x86_64")
325+
include("src/xenia/cpu/backend/x64")
326+
filter("architecture:ARM64")
327+
include("src/xenia/cpu/backend/a64")
328+
filter({})
329+
315330
include("src/xenia/debug/ui")
316331
include("src/xenia/gpu")
317332
include("src/xenia/gpu/null")

src/xenia/app/premake5.lua

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ project("xenia-app")
3333
"libavcodec",
3434
"libavutil",
3535
"mspack",
36+
"SDL2",
3637
"snappy",
3738
"xxhash",
3839
})
@@ -75,13 +76,18 @@ project("xenia-app")
7576
"xenia-cpu-backend-x64",
7677
})
7778

79+
filter("architecture:ARM64")
80+
links({
81+
"xenia-cpu-backend-a64",
82+
})
83+
7884
-- TODO(Triang3l): The emulator itself on Android.
7985
filter("platforms:not Android-*")
8086
files({
8187
"xenia_main.cc",
8288
})
8389

84-
filter("platforms:Windows")
90+
filter("platforms:Windows-*")
8591
files({
8692
"main_resources.rc",
8793
})
@@ -107,7 +113,7 @@ project("xenia-app")
107113
"SDL2",
108114
})
109115

110-
filter("platforms:Windows")
116+
filter("platforms:Windows-*")
111117
links({
112118
"xenia-apu-xaudio2",
113119
"xenia-gpu-d3d12",
@@ -117,14 +123,14 @@ project("xenia-app")
117123
})
118124

119125
if enableMiscSubprojects then
120-
filter({"platforms:Windows", SINGLE_LIBRARY_FILTER})
126+
filter({"platforms:Windows-*", SINGLE_LIBRARY_FILTER})
121127
links({
122128
"xenia-gpu-d3d12-trace-viewer",
123129
"xenia-ui-window-d3d12-demo",
124130
})
125131
end
126132

127-
filter("platforms:Windows")
133+
filter("platforms:Windows-*")
128134
-- Only create the .user file if it doesn't already exist.
129135
local user_file = project_root.."/build/xenia-app.vcxproj.user"
130136
if not os.isfile(user_file) then

src/xenia/base/clock.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ DEFINE_bool(clock_no_scaling, false,
2828
"Guest system time is directly pulled from host.",
2929
"CPU");
3030
DEFINE_bool(clock_source_raw, false,
31-
"Use the RDTSC instruction as the time source. "
32-
"Host CPU must support invariant TSC.",
31+
"On x64, Use the RDTSC instruction as the time source. Requires "
32+
"invariant TSC. "
33+
"On a64, Use the CNTVCT_EL0 register as the time source",
3334
"CPU");
3435

3536
namespace xe {

src/xenia/base/clock.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818

1919
#if XE_ARCH_AMD64
2020
#define XE_CLOCK_RAW_AVAILABLE 1
21+
#elif XE_ARCH_ARM64
22+
#define XE_CLOCK_RAW_AVAILABLE 1
2123
#endif
2224

2325
DECLARE_bool(clock_no_scaling);

src/xenia/base/clock_a64.cc

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
******************************************************************************
3+
* Xenia : Xbox 360 Emulator Research Project *
4+
******************************************************************************
5+
* Copyright 2024 Ben Vanik. All rights reserved. *
6+
* Released under the BSD license - see LICENSE in the root for more details. *
7+
******************************************************************************
8+
*/
9+
10+
#include "xenia/base/clock.h"
11+
#include "xenia/base/platform.h"
12+
13+
#if XE_ARCH_ARM64 && XE_CLOCK_RAW_AVAILABLE
14+
15+
#include "xenia/base/logging.h"
16+
17+
#ifdef _MSC_VER
18+
#include <arm64_neon.h>
19+
#include <intrin.h>
20+
#else
21+
#include <arm_neon.h>
22+
#endif
23+
24+
// Wrap all these different cpu compiler intrinsics.
25+
#if XE_COMPILER_MSVC
26+
constexpr int32_t CNTFRQ_EL0 = ARM64_SYSREG(3, 3, 14, 0, 0);
27+
constexpr int32_t CNTVCT_EL0 = ARM64_SYSREG(3, 3, 14, 0, 2);
28+
#define xe_cpu_mrs(reg) _ReadStatusReg(reg)
29+
#elif XE_COMPILER_CLANG || XE_COMPILER_GNUC
30+
constexpr int32_t CNTFRQ_EL0 = 0b11'011'1110'0000'000;
31+
constexpr int32_t CNTVCT_EL0 = 0b11'011'1110'0000'010;
32+
33+
uint64_t xe_cpu_mrs(uint32_t reg) {
34+
uint64_t result;
35+
__asm__ volatile("mrs \t%0," #reg : "=r"(result));
36+
return result;
37+
}
38+
#else
39+
#error \
40+
"No cpu instruction wrappers xe_cpu_mrs(CNTVCT_EL0); for current compiler implemented."
41+
#endif
42+
43+
namespace xe {
44+
45+
uint64_t Clock::host_tick_frequency_raw() { return xe_cpu_mrs(CNTFRQ_EL0); }
46+
uint64_t Clock::host_tick_count_raw() { return xe_cpu_mrs(CNTVCT_EL0); }
47+
48+
} // namespace xe
49+
50+
#endif

src/xenia/base/exception_handler_win.cc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,22 @@ LONG CALLBACK ExceptionHandlerCallback(PEXCEPTION_POINTERS ex_info) {
3636
}
3737

3838
HostThreadContext thread_context;
39+
40+
#if XE_ARCH_AMD64
3941
thread_context.rip = ex_info->ContextRecord->Rip;
4042
thread_context.eflags = ex_info->ContextRecord->EFlags;
4143
std::memcpy(thread_context.int_registers, &ex_info->ContextRecord->Rax,
4244
sizeof(thread_context.int_registers));
4345
std::memcpy(thread_context.xmm_registers, &ex_info->ContextRecord->Xmm0,
4446
sizeof(thread_context.xmm_registers));
47+
#elif XE_ARCH_ARM64
48+
thread_context.pc = ex_info->ContextRecord->Pc;
49+
thread_context.cpsr = ex_info->ContextRecord->Cpsr;
50+
std::memcpy(thread_context.x, &ex_info->ContextRecord->X,
51+
sizeof(thread_context.x));
52+
std::memcpy(thread_context.v, &ex_info->ContextRecord->V,
53+
sizeof(thread_context.v));
54+
#endif
4555

4656
// https://msdn.microsoft.com/en-us/library/ms679331(v=vs.85).aspx
4757
// https://msdn.microsoft.com/en-us/library/aa363082(v=vs.85).aspx
@@ -78,6 +88,7 @@ LONG CALLBACK ExceptionHandlerCallback(PEXCEPTION_POINTERS ex_info) {
7888
for (size_t i = 0; i < xe::countof(handlers_) && handlers_[i].first; ++i) {
7989
if (handlers_[i].first(&ex, handlers_[i].second)) {
8090
// Exception handled.
91+
#if XE_ARCH_AMD64
8192
ex_info->ContextRecord->Rip = thread_context.rip;
8293
ex_info->ContextRecord->EFlags = thread_context.eflags;
8394
uint32_t modified_register_index;
@@ -98,6 +109,28 @@ LONG CALLBACK ExceptionHandlerCallback(PEXCEPTION_POINTERS ex_info) {
98109
&thread_context.xmm_registers[modified_register_index],
99110
sizeof(vec128_t));
100111
}
112+
#elif XE_ARCH_ARM64
113+
ex_info->ContextRecord->Pc = thread_context.pc;
114+
ex_info->ContextRecord->Cpsr = thread_context.cpsr;
115+
uint32_t modified_register_index;
116+
uint16_t modified_int_registers_remaining = ex.modified_x_registers();
117+
while (xe::bit_scan_forward(modified_int_registers_remaining,
118+
&modified_register_index)) {
119+
modified_int_registers_remaining &=
120+
~(UINT16_C(1) << modified_register_index);
121+
ex_info->ContextRecord->X[modified_register_index] =
122+
thread_context.x[modified_register_index];
123+
}
124+
uint16_t modified_xmm_registers_remaining = ex.modified_v_registers();
125+
while (xe::bit_scan_forward(modified_xmm_registers_remaining,
126+
&modified_register_index)) {
127+
modified_xmm_registers_remaining &=
128+
~(UINT16_C(1) << modified_register_index);
129+
std::memcpy(&ex_info->ContextRecord->V + modified_register_index,
130+
&thread_context.v[modified_register_index],
131+
sizeof(vec128_t));
132+
}
133+
#endif
101134
return EXCEPTION_CONTINUE_EXECUTION;
102135
}
103136
}

src/xenia/base/host_thread_context.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ std::string HostThreadContext::GetStringFromValue(HostRegister reg,
6767
case Arm64Register::kPc:
6868
return hex ? string_util::to_hex_string(pc) : std::to_string(pc);
6969
case Arm64Register::kPstate:
70-
return hex ? string_util::to_hex_string(pstate) : std::to_string(pstate);
70+
return hex ? string_util::to_hex_string(cpsr) : std::to_string(cpsr);
7171
case Arm64Register::kFpsr:
7272
return hex ? string_util::to_hex_string(fpsr) : std::to_string(fpsr);
7373
case Arm64Register::kFpcr:

src/xenia/base/host_thread_context.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ class HostThreadContext {
202202
uint64_t x[31];
203203
uint64_t sp;
204204
uint64_t pc;
205-
uint64_t pstate;
205+
uint32_t cpsr;
206206
uint32_t fpsr;
207207
uint32_t fpcr;
208208
vec128_t v[32];

src/xenia/base/main_init_win.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
#include <cstdlib>
1313

14+
#if XE_ARCH_AMD64
15+
1416
// Includes Windows headers, so it goes after platform_win.h.
1517
#include "third_party/xbyak/xbyak/xbyak_util.h"
1618

@@ -43,4 +45,6 @@ class StartupCpuFeatureCheck {
4345
// https://docs.microsoft.com/en-us/cpp/preprocessor/init-seg
4446
#pragma warning(suppress : 4073)
4547
#pragma init_seg(lib)
46-
static StartupCpuFeatureCheck gStartupAvxCheck;
48+
static StartupCpuFeatureCheck gStartupAvxCheck;
49+
50+
#endif

0 commit comments

Comments
 (0)