[ARM64] Initial commit for arm64 backend

Based entirely off existing xbyak x86 implementation and available
tests. Still needs a lot of optimization and testing on non-Windows
platforms.

So far passes all tests and boots at least some games on Windows.
This commit is contained in:
Herman S.
2026-03-21 01:17:18 +09:00
parent c6e112bcd8
commit 883c2030d0
44 changed files with 13428 additions and 140 deletions

View File

@@ -29,9 +29,11 @@ target_link_libraries(xenia-cpu-ppc-tests PRIVATE
capstone fmt imgui mspack
)
# x64 backend
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64")
# Architecture-specific backend
if(XE_TARGET_X86_64)
target_link_libraries(xenia-cpu-ppc-tests PRIVATE xenia-cpu-backend-x64)
elseif(XE_TARGET_AARCH64)
target_link_libraries(xenia-cpu-ppc-tests PRIVATE xenia-cpu-backend-a64)
endif()
xe_target_defaults(xenia-cpu-ppc-tests)

View File

@@ -29,6 +29,8 @@
#if XE_ARCH_AMD64
#include "xenia/cpu/backend/x64/x64_backend.h"
#elif XE_ARCH_ARM64
#include "xenia/cpu/backend/a64/a64_backend.h"
#endif // XE_ARCH
#if XE_COMPILER_MSVC
@@ -248,11 +250,17 @@ class TestRunner {
if (cvars::cpu == "x64") {
backend.reset(new xe::cpu::backend::x64::X64Backend());
}
#elif XE_ARCH_ARM64
if (cvars::cpu == "a64") {
backend.reset(new xe::cpu::backend::a64::A64Backend());
}
#endif // XE_ARCH
if (cvars::cpu == "any") {
if (!backend) {
#if XE_ARCH_AMD64
backend.reset(new xe::cpu::backend::x64::X64Backend());
#elif XE_ARCH_ARM64
backend.reset(new xe::cpu::backend::a64::A64Backend());
#endif // XE_ARCH
}
}
@@ -310,6 +318,21 @@ class TestRunner {
x64_backend->BackendContextForGuestContext(thread_state_->context());
bctx->flags &= ~(1U << xe::cpu::backend::x64::kX64BackendMXCSRModeBit);
}
#elif XE_ARCH_ARM64
// Reset FPCR and backend flags to default FPU state before each test.
{
auto* a64_backend = static_cast<xe::cpu::backend::a64::A64Backend*>(
processor_->backend());
auto* bctx =
a64_backend->BackendContextForGuestContext(thread_state_->context());
bctx->flags &= ~(1U << xe::cpu::backend::a64::kA64BackendFPCRModeBit);
// Explicitly reset the hardware FPCR to default FPU mode (0 = round
// nearest, no flush-to-zero, no default-NaN). Without this, a previous
// test that set VMX mode (FZ|DN) leaves the hardware FPCR dirty, and
// subsequent scalar FP tests produce wrong NaN results because DN=1
// causes ARM64 to return the default NaN instead of propagating inputs.
a64_backend->SetGuestRoundingMode(thread_state_->context(), 0);
}
#endif
// Execute test.