aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlizzie <lizzie@eden-emu.dev>2025-09-24 02:40:07 +0200
committercrueter <crueter@eden-emu.dev>2025-09-24 02:40:07 +0200
commit3e299dc0f5dee2b56e5cb27ff4279cd05f54e717 (patch)
tree0e79e4b53f5d343144a64cbec3e8ca9d2a8a1f4e
parent3ac9d65cdd7b5a6f7a24051d268c7038c03a81ff (diff)
[dynarmic] remove frontend options; fixup exception handler code to support other OSes, do not use mcl macros for arch in EH (#2540)
Signed-off-by: lizzie <lizzie@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2540 Reviewed-by: MaranBr <maranbr@eden-emu.dev> Reviewed-by: crueter <crueter@eden-emu.dev> Co-authored-by: lizzie <lizzie@eden-emu.dev> Co-committed-by: lizzie <lizzie@eden-emu.dev>
-rw-r--r--src/dynarmic/CMakeLists.txt3
-rw-r--r--src/dynarmic/src/dynarmic/CMakeLists.txt194
-rw-r--r--src/dynarmic/src/dynarmic/backend/exception_handler_generic.cpp9
-rw-r--r--src/dynarmic/src/dynarmic/backend/exception_handler_macos.cpp12
-rw-r--r--src/dynarmic/src/dynarmic/backend/exception_handler_macos_mig.c4
-rw-r--r--src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp100
-rw-r--r--src/dynarmic/src/dynarmic/backend/exception_handler_windows.cpp7
-rw-r--r--src/dynarmic/src/dynarmic/common/context.h120
-rw-r--r--src/dynarmic/tests/CMakeLists.txt168
9 files changed, 314 insertions, 303 deletions
diff --git a/src/dynarmic/CMakeLists.txt b/src/dynarmic/CMakeLists.txt
index a9808391ae..331f42afba 100644
--- a/src/dynarmic/CMakeLists.txt
+++ b/src/dynarmic/CMakeLists.txt
@@ -39,9 +39,6 @@ option(DYNARMIC_INSTALL "Install dynarmic headers and CMake files" OFF)
option(DYNARMIC_USE_BUNDLED_EXTERNALS "Use all bundled externals (useful when e.g. cross-compiling)" OFF)
option(DYNARMIC_WARNINGS_AS_ERRORS "Warnings as errors" ${MASTER_PROJECT})
option(DYNARMIC_ENABLE_LTO "Enable LTO" OFF)
-if (NOT DEFINED DYNARMIC_FRONTENDS)
- set(DYNARMIC_FRONTENDS "A32;A64" CACHE STRING "Selects which frontends to enable")
-endif()
# Default to a Release build
if (NOT CMAKE_BUILD_TYPE)
diff --git a/src/dynarmic/src/dynarmic/CMakeLists.txt b/src/dynarmic/src/dynarmic/CMakeLists.txt
index e8f8a6a767..a5234609cf 100644
--- a/src/dynarmic/src/dynarmic/CMakeLists.txt
+++ b/src/dynarmic/src/dynarmic/CMakeLists.txt
@@ -1,6 +1,5 @@
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
-
include(TargetArchitectureSpecificSources)
add_library(dynarmic
@@ -103,65 +102,57 @@ add_library(dynarmic
ir/type.h
ir/value.cpp
ir/value.h
+ # A32
+ frontend/A32/a32_ir_emitter.cpp
+ frontend/A32/a32_ir_emitter.h
+ frontend/A32/a32_location_descriptor.cpp
+ frontend/A32/a32_location_descriptor.h
+ frontend/A32/decoder/arm.h
+ frontend/A32/decoder/arm.inc
+ frontend/A32/decoder/asimd.h
+ frontend/A32/decoder/asimd.inc
+ frontend/A32/decoder/thumb16.h
+ frontend/A32/decoder/thumb16.inc
+ frontend/A32/decoder/thumb32.h
+ frontend/A32/decoder/thumb32.inc
+ frontend/A32/decoder/vfp.h
+ frontend/A32/decoder/vfp.inc
+ frontend/A32/disassembler/disassembler.h
+ frontend/A32/disassembler/disassembler_arm.cpp
+ frontend/A32/disassembler/disassembler_thumb.cpp
+ frontend/A32/FPSCR.h
+ frontend/A32/ITState.h
+ frontend/A32/PSR.h
+ frontend/A32/translate/a32_translate.cpp
+ frontend/A32/translate/a32_translate.h
+ frontend/A32/translate/conditional_state.cpp
+ frontend/A32/translate/conditional_state.h
+ frontend/A32/translate/translate_arm.cpp
+ frontend/A32/translate/translate_thumb.cpp
+ interface/A32/a32.h
+ interface/A32/arch_version.h
+ interface/A32/config.h
+ interface/A32/coprocessor.h
+ interface/A32/coprocessor_util.h
+ interface/A32/disassembler.h
+ ir/opt/a32_constant_memory_reads_pass.cpp
+ ir/opt/a32_get_set_elimination_pass.cpp
+ # A64
+ frontend/A64/a64_ir_emitter.cpp
+ frontend/A64/a64_ir_emitter.h
+ frontend/A64/a64_location_descriptor.cpp
+ frontend/A64/a64_location_descriptor.h
+ frontend/A64/decoder/a64.h
+ frontend/A64/decoder/a64.inc
+ frontend/A64/translate/a64_translate.cpp
+ frontend/A64/translate/a64_translate.h
+ interface/A64/a64.h
+ interface/A64/config.h
+ ir/opt/a64_callback_config_pass.cpp
+ ir/opt/a64_get_set_elimination_pass.cpp
+ ir/opt/a64_merge_interpret_blocks.cpp
)
-if ("A32" IN_LIST DYNARMIC_FRONTENDS)
- target_sources(dynarmic PRIVATE
- frontend/A32/a32_ir_emitter.cpp
- frontend/A32/a32_ir_emitter.h
- frontend/A32/a32_location_descriptor.cpp
- frontend/A32/a32_location_descriptor.h
- frontend/A32/decoder/arm.h
- frontend/A32/decoder/arm.inc
- frontend/A32/decoder/asimd.h
- frontend/A32/decoder/asimd.inc
- frontend/A32/decoder/thumb16.h
- frontend/A32/decoder/thumb16.inc
- frontend/A32/decoder/thumb32.h
- frontend/A32/decoder/thumb32.inc
- frontend/A32/decoder/vfp.h
- frontend/A32/decoder/vfp.inc
- frontend/A32/disassembler/disassembler.h
- frontend/A32/disassembler/disassembler_arm.cpp
- frontend/A32/disassembler/disassembler_thumb.cpp
- frontend/A32/FPSCR.h
- frontend/A32/ITState.h
- frontend/A32/PSR.h
- frontend/A32/translate/a32_translate.cpp
- frontend/A32/translate/a32_translate.h
- frontend/A32/translate/conditional_state.cpp
- frontend/A32/translate/conditional_state.h
- frontend/A32/translate/translate_arm.cpp
- frontend/A32/translate/translate_thumb.cpp
- interface/A32/a32.h
- interface/A32/arch_version.h
- interface/A32/config.h
- interface/A32/coprocessor.h
- interface/A32/coprocessor_util.h
- interface/A32/disassembler.h
- ir/opt/a32_constant_memory_reads_pass.cpp
- ir/opt/a32_get_set_elimination_pass.cpp
- )
-endif()
-
-if ("A64" IN_LIST DYNARMIC_FRONTENDS)
- target_sources(dynarmic PRIVATE
- frontend/A64/a64_ir_emitter.cpp
- frontend/A64/a64_ir_emitter.h
- frontend/A64/a64_location_descriptor.cpp
- frontend/A64/a64_location_descriptor.h
- frontend/A64/decoder/a64.h
- frontend/A64/decoder/a64.inc
- frontend/A64/translate/a64_translate.cpp
- frontend/A64/translate/a64_translate.h
- interface/A64/a64.h
- interface/A64/config.h
- ir/opt/a64_callback_config_pass.cpp
- ir/opt/a64_get_set_elimination_pass.cpp
- ir/opt/a64_merge_interpret_blocks.cpp
- )
-endif()
-
if ("x86_64" IN_LIST ARCHITECTURE)
# Newer versions of xbyak (>= 7.25.0) have stricter checks that currently
# fail in dynarmic
@@ -218,29 +209,21 @@ if ("x86_64" IN_LIST ARCHITECTURE)
common/spin_lock_x64.h
common/x64_disassemble.cpp
common/x64_disassemble.h
+ # A32
+ backend/x64/a32_emit_x64.cpp
+ backend/x64/a32_emit_x64.h
+ backend/x64/a32_emit_x64_memory.cpp
+ backend/x64/a32_interface.cpp
+ backend/x64/a32_jitstate.cpp
+ backend/x64/a32_jitstate.h
+ # A64
+ backend/x64/a64_emit_x64.cpp
+ backend/x64/a64_emit_x64.h
+ backend/x64/a64_emit_x64_memory.cpp
+ backend/x64/a64_interface.cpp
+ backend/x64/a64_jitstate.cpp
+ backend/x64/a64_jitstate.h
)
-
- if ("A32" IN_LIST DYNARMIC_FRONTENDS)
- target_architecture_specific_sources(dynarmic "x86_64"
- backend/x64/a32_emit_x64.cpp
- backend/x64/a32_emit_x64.h
- backend/x64/a32_emit_x64_memory.cpp
- backend/x64/a32_interface.cpp
- backend/x64/a32_jitstate.cpp
- backend/x64/a32_jitstate.h
- )
- endif()
-
- if ("A64" IN_LIST DYNARMIC_FRONTENDS)
- target_architecture_specific_sources(dynarmic "x86_64"
- backend/x64/a64_emit_x64.cpp
- backend/x64/a64_emit_x64.h
- backend/x64/a64_emit_x64_memory.cpp
- backend/x64/a64_interface.cpp
- backend/x64/a64_jitstate.cpp
- backend/x64/a64_jitstate.h
- )
- endif()
endif()
if ("arm64" IN_LIST ARCHITECTURE)
@@ -284,25 +267,17 @@ if ("arm64" IN_LIST ARCHITECTURE)
backend/arm64/verbose_debugging_output.h
common/spin_lock_arm64.cpp
common/spin_lock_arm64.h
+ # A32
+ backend/arm64/a32_address_space.cpp
+ backend/arm64/a32_address_space.h
+ backend/arm64/a32_core.h
+ backend/arm64/a32_interface.cpp
+ # A64
+ backend/arm64/a64_address_space.cpp
+ backend/arm64/a64_address_space.h
+ backend/arm64/a64_core.h
+ backend/arm64/a64_interface.cpp
)
-
- if ("A32" IN_LIST DYNARMIC_FRONTENDS)
- target_architecture_specific_sources(dynarmic "arm64"
- backend/arm64/a32_address_space.cpp
- backend/arm64/a32_address_space.h
- backend/arm64/a32_core.h
- backend/arm64/a32_interface.cpp
- )
- endif()
-
- if ("A64" IN_LIST DYNARMIC_FRONTENDS)
- target_architecture_specific_sources(dynarmic "arm64"
- backend/arm64/a64_address_space.cpp
- backend/arm64/a64_address_space.h
- backend/arm64/a64_core.h
- backend/arm64/a64_interface.cpp
- )
- endif()
endif()
if ("riscv" IN_LIST ARCHITECTURE)
@@ -331,21 +306,14 @@ if ("riscv" IN_LIST ARCHITECTURE)
backend/riscv64/reg_alloc.cpp
backend/riscv64/reg_alloc.h
backend/riscv64/stack_layout.h
+ # A32
+ backend/riscv64/a32_address_space.cpp
+ backend/riscv64/a32_address_space.h
+ backend/riscv64/a32_core.h
+ backend/riscv64/a32_interface.cpp
+ backend/riscv64/code_block.h
)
-
- if ("A32" IN_LIST DYNARMIC_FRONTENDS)
- target_sources(dynarmic PRIVATE
- backend/riscv64/a32_address_space.cpp
- backend/riscv64/a32_address_space.h
- backend/riscv64/a32_core.h
- backend/riscv64/a32_interface.cpp
- backend/riscv64/code_block.h
- )
- endif()
-
- if ("A64" IN_LIST DYNARMIC_FRONTENDS)
- message(FATAL_ERROR "TODO: Unimplemented frontend for this host architecture")
- endif()
+ message(FATAL_ERROR "TODO: Unimplemented frontend for this host architecture")
endif()
if (WIN32)
@@ -423,7 +391,7 @@ target_link_libraries(dynarmic
)
if (BOOST_NO_HEADERS)
-target_link_libraries(dynarmic PRIVATE Boost::variant Boost::icl Boost::pool)
+ target_link_libraries(dynarmic PRIVATE Boost::variant Boost::icl Boost::pool)
else()
target_link_libraries(dynarmic PRIVATE Boost::headers)
endif()
diff --git a/src/dynarmic/src/dynarmic/backend/exception_handler_generic.cpp b/src/dynarmic/src/dynarmic/backend/exception_handler_generic.cpp
index ad7df25ca6..23dc294511 100644
--- a/src/dynarmic/src/dynarmic/backend/exception_handler_generic.cpp
+++ b/src/dynarmic/src/dynarmic/backend/exception_handler_generic.cpp
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
/* This file is part of the dynarmic project.
* Copyright (c) 2016 MerryMage
* SPDX-License-Identifier: 0BSD
@@ -13,15 +16,15 @@ struct ExceptionHandler::Impl final {
ExceptionHandler::ExceptionHandler() = default;
ExceptionHandler::~ExceptionHandler() = default;
-#if defined(MCL_ARCHITECTURE_X86_64)
+#if defined(ARCHITECTURE_x86_64)
void ExceptionHandler::Register(X64::BlockOfCode&) {
// Do nothing
}
-#elif defined(MCL_ARCHITECTURE_ARM64)
+#elif defined(ARCHITECTURE_arm64)
void ExceptionHandler::Register(oaknut::CodeBlock&, std::size_t) {
// Do nothing
}
-#elif defined(MCL_ARCHITECTURE_RISCV)
+#elif defined(ARCHITECTURE_riscv64)
void ExceptionHandler::Register(RV64::CodeBlock&, std::size_t) {
// Do nothing
}
diff --git a/src/dynarmic/src/dynarmic/backend/exception_handler_macos.cpp b/src/dynarmic/src/dynarmic/backend/exception_handler_macos.cpp
index 52bcf5972f..76e517f05b 100644
--- a/src/dynarmic/src/dynarmic/backend/exception_handler_macos.cpp
+++ b/src/dynarmic/src/dynarmic/backend/exception_handler_macos.cpp
@@ -25,7 +25,7 @@
#include "dynarmic/backend/exception_handler.h"
-#if defined(MCL_ARCHITECTURE_X86_64)
+#if defined(ARCHITECTURE_x86_64)
# include "dynarmic/backend/x64/block_of_code.h"
# define mig_external extern "C"
@@ -36,7 +36,7 @@
using dynarmic_thread_state_t = x86_thread_state64_t;
-#elif defined(MCL_ARCHITECTURE_ARM64)
+#elif defined(ARCHITECTURE_arm64)
# include <oaknut/code_block.hpp>
# define mig_external extern "C"
@@ -133,7 +133,7 @@ void MachHandler::MessagePump() {
}
}
-#if defined(MCL_ARCHITECTURE_X86_64)
+#if defined(ARCHITECTURE_x86_64)
kern_return_t MachHandler::HandleRequest(x86_thread_state64_t* ts) {
std::lock_guard<std::mutex> guard(code_block_infos_mutex);
@@ -151,7 +151,7 @@ kern_return_t MachHandler::HandleRequest(x86_thread_state64_t* ts) {
return KERN_SUCCESS;
}
-#elif defined(MCL_ARCHITECTURE_ARM64)
+#elif defined(ARCHITECTURE_arm64)
kern_return_t MachHandler::HandleRequest(arm_thread_state64_t* ts) {
std::lock_guard<std::mutex> guard(code_block_infos_mutex);
@@ -269,13 +269,13 @@ private:
ExceptionHandler::ExceptionHandler() = default;
ExceptionHandler::~ExceptionHandler() = default;
-#if defined(MCL_ARCHITECTURE_X86_64)
+#if defined(ARCHITECTURE_x86_64)
void ExceptionHandler::Register(X64::BlockOfCode& code) {
const u64 code_begin = mcl::bit_cast<u64>(code.getCode());
const u64 code_end = code_begin + code.GetTotalCodeSize();
impl = std::make_unique<Impl>(code_begin, code_end);
}
-#elif defined(MCL_ARCHITECTURE_ARM64)
+#elif defined(ARCHITECTURE_arm64)
void ExceptionHandler::Register(oaknut::CodeBlock& mem, std::size_t size) {
const u64 code_begin = mcl::bit_cast<u64>(mem.ptr());
const u64 code_end = code_begin + size;
diff --git a/src/dynarmic/src/dynarmic/backend/exception_handler_macos_mig.c b/src/dynarmic/src/dynarmic/backend/exception_handler_macos_mig.c
index 762a80ca42..25678ab115 100644
--- a/src/dynarmic/src/dynarmic/backend/exception_handler_macos_mig.c
+++ b/src/dynarmic/src/dynarmic/backend/exception_handler_macos_mig.c
@@ -5,9 +5,9 @@
#include <mcl/macro/architecture.hpp>
-#if defined(MCL_ARCHITECTURE_X86_64)
+#if defined(ARCHITECTURE_x86_64)
# include "dynarmic/backend/x64/mig/mach_exc_server.c"
-#elif defined(MCL_ARCHITECTURE_ARM64)
+#elif defined(ARCHITECTURE_arm64)
# include "dynarmic/backend/arm64/mig/mach_exc_server.c"
#else
# error "Invalid architecture"
diff --git a/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp b/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp
index d0653eceab..f1f208179f 100644
--- a/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp
+++ b/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp
@@ -12,31 +12,17 @@
#include <mutex>
#include <shared_mutex>
#include <optional>
-#include <sys/mman.h>
-#ifdef __APPLE__
-# include <signal.h>
-# include <sys/ucontext.h>
-#else
-# include <signal.h>
-# ifndef __OpenBSD__
-# include <ucontext.h>
-# endif
-# ifdef __sun__
-# include <sys/regset.h>
-# endif
-#endif
-
#include <ankerl/unordered_dense.h>
-
#include "dynarmic/backend/exception_handler.h"
+#include "dynarmic/common/assert.h"
+#include "dynarmic/common/context.h"
#include "dynarmic/common/common_types.h"
-#if defined(MCL_ARCHITECTURE_X86_64)
+#if defined(ARCHITECTURE_x86_64)
# include "dynarmic/backend/x64/block_of_code.h"
-#elif defined(MCL_ARCHITECTURE_ARM64)
+#elif defined(ARCHITECTURE_arm64)
# include <oaknut/code_block.hpp>
-
# include "dynarmic/backend/arm64/abi.h"
-#elif defined(MCL_ARCHITECTURE_RISCV)
+#elif defined(ARCHITECTURE_riscv64)
# include "dynarmic/backend/riscv64/code_block.h"
#else
# error "Invalid architecture"
@@ -129,35 +115,8 @@ void RegisterHandler() {
void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) {
DEBUG_ASSERT(sig == SIGSEGV || sig == SIGBUS);
-#ifndef MCL_ARCHITECTURE_RISCV
- ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(raw_context);
-#ifndef __OpenBSD__
- auto& mctx = ucontext->uc_mcontext;
-#endif
-#endif
-
-#if defined(MCL_ARCHITECTURE_X86_64)
-# if defined(__APPLE__)
-# define CTX_RIP (mctx->__ss.__rip)
-# define CTX_RSP (mctx->__ss.__rsp)
-# elif defined(__linux__)
-# define CTX_RIP (mctx.gregs[REG_RIP])
-# define CTX_RSP (mctx.gregs[REG_RSP])
-# elif defined(__FreeBSD__)
-# define CTX_RIP (mctx.mc_rip)
-# define CTX_RSP (mctx.mc_rsp)
-# elif defined(__NetBSD__)
-# define CTX_RIP (mctx.__gregs[_REG_RIP])
-# define CTX_RSP (mctx.__gregs[_REG_RSP])
-# elif defined(__OpenBSD__)
-# define CTX_RIP (ucontext->sc_rip)
-# define CTX_RSP (ucontext->sc_rsp)
-# elif defined(__sun__)
-# define CTX_RIP (mctx.gregs[REG_RIP])
-# define CTX_RSP (mctx.gregs[REG_RSP])
-# else
-# error "Unknown platform"
-# endif
+ CTX_DECLARE(raw_context);
+#if defined(ARCHITECTURE_x86_64)
{
std::shared_lock guard(sig_handler->code_block_infos_mutex);
if (auto const iter = sig_handler->FindCodeBlockInfo(CTX_RIP); iter != sig_handler->code_block_infos.end()) {
@@ -169,48 +128,7 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) {
}
}
fmt::print(stderr, "Unhandled {} at rip {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_RIP);
-#elif defined(MCL_ARCHITECTURE_ARM64)
-# if defined(__APPLE__)
-# define CTX_PC (mctx->__ss.__pc)
-# define CTX_SP (mctx->__ss.__sp)
-# define CTX_LR (mctx->__ss.__lr)
-# define CTX_X(i) (mctx->__ss.__x[i])
-# define CTX_Q(i) (mctx->__ns.__v[i])
-# elif defined(__linux__)
-# define CTX_PC (mctx.pc)
-# define CTX_SP (mctx.sp)
-# define CTX_LR (mctx.regs[30])
-# define CTX_X(i) (mctx.regs[i])
-# define CTX_Q(i) (fpctx->vregs[i])
- [[maybe_unused]] const auto fpctx = [&mctx] {
- _aarch64_ctx* header = (_aarch64_ctx*)&mctx.__reserved;
- while (header->magic != FPSIMD_MAGIC) {
- ASSERT(header->magic && header->size);
- header = (_aarch64_ctx*)((char*)header + header->size);
- }
- return (fpsimd_context*)header;
- }();
-# elif defined(__FreeBSD__)
-# define CTX_PC (mctx.mc_gpregs.gp_elr)
-# define CTX_SP (mctx.mc_gpregs.gp_sp)
-# define CTX_LR (mctx.mc_gpregs.gp_lr)
-# define CTX_X(i) (mctx.mc_gpregs.gp_x[i])
-# define CTX_Q(i) (mctx.mc_fpregs.fp_q[i])
-# elif defined(__NetBSD__)
-# define CTX_PC (mctx.mc_gpregs.gp_elr)
-# define CTX_SP (mctx.mc_gpregs.gp_sp)
-# define CTX_LR (mctx.mc_gpregs.gp_lr)
-# define CTX_X(i) (mctx.mc_gpregs.gp_x[i])
-# define CTX_Q(i) (mctx.mc_fpregs.fp_q[i])
-# elif defined(__OpenBSD__)
-# define CTX_PC (ucontext->sc_elr)
-# define CTX_SP (ucontext->sc_sp)
-# define CTX_LR (ucontext->sc_lr)
-# define CTX_X(i) (ucontext->sc_x[i])
-# define CTX_Q(i) (ucontext->sc_q[i])
-# else
-# error "Unknown platform"
-# endif
+#elif defined(ARCHITECTURE_arm64)
{
std::shared_lock guard(sig_handler->code_block_infos_mutex);
if (const auto iter = sig_handler->FindCodeBlockInfo(CTX_PC); iter != sig_handler->code_block_infos.end()) {
@@ -220,7 +138,7 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) {
}
}
fmt::print(stderr, "Unhandled {} at pc {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_PC);
-#elif defined(MCL_ARCHITECTURE_RISCV)
+#elif defined(ARCHITECTURE_riscv64)
ASSERT_FALSE("Unimplemented");
#else
# error "Invalid architecture"
diff --git a/src/dynarmic/src/dynarmic/backend/exception_handler_windows.cpp b/src/dynarmic/src/dynarmic/backend/exception_handler_windows.cpp
index 719c007594..58a3325e17 100644
--- a/src/dynarmic/src/dynarmic/backend/exception_handler_windows.cpp
+++ b/src/dynarmic/src/dynarmic/backend/exception_handler_windows.cpp
@@ -1,3 +1,6 @@
+// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
/* This file is part of the dynarmic project.
* Copyright (c) 2023 MerryMage
* SPDX-License-Identifier: 0BSD
@@ -5,9 +8,9 @@
#include <mcl/macro/architecture.hpp>
-#if defined(MCL_ARCHITECTURE_X86_64)
+#if defined(ARCHITECTURE_x86_64)
# include "dynarmic/backend/x64/exception_handler_windows.cpp"
-#elif defined(MCL_ARCHITECTURE_ARM64)
+#elif defined(ARCHITECTURE_arm64)
# include "dynarmic/backend/exception_handler_generic.cpp"
#else
# error "Invalid architecture"
diff --git a/src/dynarmic/src/dynarmic/common/context.h b/src/dynarmic/src/dynarmic/common/context.h
new file mode 100644
index 0000000000..0eb128449c
--- /dev/null
+++ b/src/dynarmic/src/dynarmic/common/context.h
@@ -0,0 +1,120 @@
+// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+#pragma once
+
+#ifdef __APPLE__
+# include <signal.h>
+# include <sys/ucontext.h>
+#else
+# include <signal.h>
+# ifndef __OpenBSD__
+# include <ucontext.h>
+# endif
+# ifdef __sun__
+# include <sys/regset.h>
+# endif
+# ifdef __linux__
+# include <sys/syscall.h>
+# endif
+#endif
+
+#ifdef ARCHITECTURE_x86_64
+# ifdef __OpenBSD__
+# define CTX_DECLARE(raw_context) ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(raw_context);
+# else
+# define CTX_DECLARE(raw_context) \
+ ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(raw_context); \
+ [[maybe_unused]] auto& mctx = ucontext->uc_mcontext;
+# endif
+#elif defined(ARCHITECTURE_arm64)
+# ifdef __OpenBSD__
+# define CTX_DECLARE(raw_context) ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(raw_context);
+# else
+# define CTX_DECLARE(raw_context) \
+ ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(raw_context); \
+ [[maybe_unused]] auto& mctx = ucontext->uc_mcontext; \
+ [[maybe_unused]] const auto fpctx = GetFloatingPointState(mctx);
+# endif
+#endif
+
+#if defined(ARCHITECTURE_x86_64)
+# if defined(__APPLE__)
+# define CTX_RIP (mctx->__ss.__rip)
+# define CTX_RSP (mctx->__ss.__rsp)
+# elif defined(__linux__)
+# define CTX_RIP (mctx.gregs[REG_RIP])
+# define CTX_RSP (mctx.gregs[REG_RSP])
+# elif defined(__FreeBSD__)
+# define CTX_RIP (mctx.mc_rip)
+# define CTX_RSP (mctx.mc_rsp)
+# elif defined(__NetBSD__)
+# define CTX_RIP (mctx.__gregs[_REG_RIP])
+# define CTX_RSP (mctx.__gregs[_REG_RSP])
+# elif defined(__OpenBSD__)
+# define CTX_RIP (ucontext->sc_rip)
+# define CTX_RSP (ucontext->sc_rsp)
+# elif defined(__sun__)
+# define CTX_RIP (mctx.gregs[REG_RIP])
+# define CTX_RSP (mctx.gregs[REG_RSP])
+# else
+# error "Unknown platform"
+# endif
+#elif defined(ARCHITECTURE_arm64)
+# if defined(__APPLE__)
+# define CTX_PC (mctx->__ss.__pc)
+# define CTX_SP (mctx->__ss.__sp)
+# define CTX_LR (mctx->__ss.__lr)
+# define CTX_PSTATE (mctx->__ss.__cpsr)
+# define CTX_X(i) (mctx->__ss.__x[i])
+# define CTX_Q(i) (mctx->__ns.__v[i])
+# define CTX_FPSR (mctx->__ns.__fpsr)
+# define CTX_FPCR (mctx->__ns.__fpcr)
+# elif defined(__linux__)
+# define CTX_PC (mctx.pc)
+# define CTX_SP (mctx.sp)
+# define CTX_LR (mctx.regs[30])
+# define CTX_PSTATE (mctx.pstate)
+# define CTX_X(i) (mctx.regs[i])
+# define CTX_Q(i) (fpctx->vregs[i])
+# define CTX_FPSR (fpctx->fpsr)
+# define CTX_FPCR (fpctx->fpcr)
+# elif defined(__FreeBSD__)
+# define CTX_PC (mctx.mc_gpregs.gp_elr)
+# define CTX_SP (mctx.mc_gpregs.gp_sp)
+# define CTX_LR (mctx.mc_gpregs.gp_lr)
+# define CTX_X(i) (mctx.mc_gpregs.gp_x[i])
+# define CTX_Q(i) (mctx.mc_fpregs.fp_q[i])
+# elif defined(__NetBSD__)
+# define CTX_PC (mctx.mc_gpregs.gp_elr)
+# define CTX_SP (mctx.mc_gpregs.gp_sp)
+# define CTX_LR (mctx.mc_gpregs.gp_lr)
+# define CTX_X(i) (mctx.mc_gpregs.gp_x[i])
+# define CTX_Q(i) (mctx.mc_fpregs.fp_q[i])
+# elif defined(__OpenBSD__)
+# define CTX_PC (ucontext->sc_elr)
+# define CTX_SP (ucontext->sc_sp)
+# define CTX_LR (ucontext->sc_lr)
+# define CTX_X(i) (ucontext->sc_x[i])
+# define CTX_Q(i) (ucontext->sc_q[i])
+# else
+# error "Unknown platform"
+# endif
+#else
+# error "unimplemented"
+#endif
+
+#ifdef ARCHITECTURE_arm64
+#ifdef __APPLE__
+inline _STRUCT_ARM_NEON_STATE64* GetFloatingPointState(mcontext_t& host_ctx) {
+ return &(host_ctx->__ns);
+}
+#elif defined(__linux__)
+inline fpsimd_context* GetFloatingPointState(mcontext_t& host_ctx) {
+ _aarch64_ctx* header = reinterpret_cast<_aarch64_ctx*>(&host_ctx.__reserved);
+ while (header->magic != FPSIMD_MAGIC)
+ header = reinterpret_cast<_aarch64_ctx*>(reinterpret_cast<char*>(header) + header->size);
+ return reinterpret_cast<fpsimd_context*>(header);
+}
+#endif
+#endif
diff --git a/src/dynarmic/tests/CMakeLists.txt b/src/dynarmic/tests/CMakeLists.txt
index 85d86c7966..4ace6c2afd 100644
--- a/src/dynarmic/tests/CMakeLists.txt
+++ b/src/dynarmic/tests/CMakeLists.txt
@@ -1,3 +1,5 @@
+# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+# SPDX-License-Identifier: GPL-3.0-or-later
include(TargetArchitectureSpecificSources)
add_executable(dynarmic_tests
@@ -6,33 +8,24 @@ add_executable(dynarmic_tests
fp/mantissa_util_tests.cpp
fp/unpacked_tests.cpp
rand_int.h
+ # A32
+ A32/test_arm_disassembler.cpp
+ A32/test_arm_instructions.cpp
+ A32/test_coprocessor.cpp
+ A32/test_svc.cpp
+ A32/test_thumb_instructions.cpp
+ A32/testenv.h
+ decoder_tests.cpp
+ # A64
+ A64/a64.cpp
+ A64/fibonacci.cpp
+ A64/fp_min_max.cpp
+ A64/misaligned_page_table.cpp
+ A64/test_invalidation.cpp
+ A64/real_world.cpp
+ A64/testenv.h
)
-
-if ("A32" IN_LIST DYNARMIC_FRONTENDS)
- target_sources(dynarmic_tests PRIVATE
- A32/test_arm_disassembler.cpp
- A32/test_arm_instructions.cpp
- A32/test_coprocessor.cpp
- A32/test_svc.cpp
- A32/test_thumb_instructions.cpp
- A32/testenv.h
- decoder_tests.cpp
- )
-endif()
-
-if ("A64" IN_LIST DYNARMIC_FRONTENDS)
- target_link_libraries(dynarmic_tests PRIVATE merry::oaknut)
-
- target_sources(dynarmic_tests PRIVATE
- A64/a64.cpp
- A64/fibonacci.cpp
- A64/fp_min_max.cpp
- A64/misaligned_page_table.cpp
- A64/test_invalidation.cpp
- A64/real_world.cpp
- A64/testenv.h
- )
-endif()
+target_link_libraries(dynarmic_tests PRIVATE merry::oaknut)
if (DYNARMIC_TESTS_USE_UNICORN)
target_link_libraries(dynarmic_tests PRIVATE Unicorn::Unicorn)
@@ -40,25 +33,17 @@ if (DYNARMIC_TESTS_USE_UNICORN)
target_sources(dynarmic_tests PRIVATE
fuzz_util.cpp
fuzz_util.h
+ # A32
+ A32/fuzz_arm.cpp
+ A32/fuzz_thumb.cpp
+ unicorn_emu/a32_unicorn.cpp
+ unicorn_emu/a32_unicorn.h
+ # A64
+ A64/fuzz_with_unicorn.cpp
+ A64/verify_unicorn.cpp
+ unicorn_emu/a64_unicorn.cpp
+ unicorn_emu/a64_unicorn.h
)
-
- if ("A32" IN_LIST DYNARMIC_FRONTENDS)
- target_sources(dynarmic_tests PRIVATE
- A32/fuzz_arm.cpp
- A32/fuzz_thumb.cpp
- unicorn_emu/a32_unicorn.cpp
- unicorn_emu/a32_unicorn.h
- )
- endif()
-
- if ("A64" IN_LIST DYNARMIC_FRONTENDS)
- target_sources(dynarmic_tests PRIVATE
- A64/fuzz_with_unicorn.cpp
- A64/verify_unicorn.cpp
- unicorn_emu/a64_unicorn.cpp
- unicorn_emu/a64_unicorn.h
- )
- endif()
endif()
if ("riscv" IN_LIST ARCHITECTURE)
@@ -69,9 +54,6 @@ if ("x86_64" IN_LIST ARCHITECTURE)
target_link_libraries(dynarmic_tests PRIVATE xbyak::xbyak)
target_architecture_specific_sources(dynarmic_tests "x86_64"
x64_cpu_info.cpp
- )
-
- target_architecture_specific_sources(dynarmic_tests "x86_64"
native/preserve_xmm.cpp
)
@@ -85,50 +67,70 @@ endif()
include(CreateDirectoryGroups)
-if (("A32" IN_LIST DYNARMIC_FRONTENDS) AND ("A64" IN_LIST DYNARMIC_FRONTENDS))
- add_executable(dynarmic_print_info
- print_info.cpp
- )
-
- create_target_directory_groups(dynarmic_print_info)
-
- target_link_libraries(dynarmic_print_info PRIVATE dynarmic Boost::headers fmt::fmt merry::mcl)
- target_include_directories(dynarmic_print_info PRIVATE . ../src)
- target_compile_options(dynarmic_print_info PRIVATE ${DYNARMIC_CXX_FLAGS})
- target_compile_definitions(dynarmic_print_info PRIVATE FMT_USE_USER_DEFINED_LITERALS=1)
+#
+# dynarmic_print_info
+#
+add_executable(dynarmic_print_info
+ print_info.cpp
+)
+create_target_directory_groups(dynarmic_print_info)
+target_link_libraries(dynarmic_print_info PRIVATE dynarmic fmt::fmt merry::mcl)
+if (BOOST_NO_HEADERS)
+ target_link_libraries(dynarmic_print_info PRIVATE Boost::variant Boost::icl Boost::pool)
+else()
+ target_link_libraries(dynarmic_print_info PRIVATE Boost::headers)
endif()
+target_include_directories(dynarmic_print_info PRIVATE . ../src)
+target_compile_options(dynarmic_print_info PRIVATE ${DYNARMIC_CXX_FLAGS})
+target_compile_definitions(dynarmic_print_info PRIVATE FMT_USE_USER_DEFINED_LITERALS=1)
+
+#
+# dynarmic_test_generator
+#
+add_executable(dynarmic_test_generator
+ fuzz_util.cpp
+ fuzz_util.h
+ test_generator.cpp
+)
-if (("A32" IN_LIST DYNARMIC_FRONTENDS) AND ("A64" IN_LIST DYNARMIC_FRONTENDS))
- add_executable(dynarmic_test_generator
- fuzz_util.cpp
- fuzz_util.h
- test_generator.cpp
- )
-
- create_target_directory_groups(dynarmic_test_generator)
+create_target_directory_groups(dynarmic_test_generator)
- target_link_libraries(dynarmic_test_generator PRIVATE dynarmic Boost::headers fmt::fmt merry::mcl)
- target_include_directories(dynarmic_test_generator PRIVATE . ../src)
- target_compile_options(dynarmic_test_generator PRIVATE ${DYNARMIC_CXX_FLAGS})
- target_compile_definitions(dynarmic_test_generator PRIVATE FMT_USE_USER_DEFINED_LITERALS=1)
+target_link_libraries(dynarmic_test_generator PRIVATE dynarmic fmt::fmt merry::mcl)
+if (BOOST_NO_HEADERS)
+ target_link_libraries(dynarmic_test_generator PRIVATE Boost::variant Boost::icl Boost::pool)
+else()
+ target_link_libraries(dynarmic_test_generator PRIVATE Boost::headers)
endif()
-
-if (("A32" IN_LIST DYNARMIC_FRONTENDS) AND ("A64" IN_LIST DYNARMIC_FRONTENDS))
- add_executable(dynarmic_test_reader
- test_reader.cpp
- )
-
- create_target_directory_groups(dynarmic_test_reader)
-
- target_link_libraries(dynarmic_test_reader PRIVATE dynarmic Boost::headers fmt::fmt merry::mcl)
- target_include_directories(dynarmic_test_reader PRIVATE . ../src)
- target_compile_options(dynarmic_test_reader PRIVATE ${DYNARMIC_CXX_FLAGS})
- target_compile_definitions(dynarmic_test_reader PRIVATE FMT_USE_USER_DEFINED_LITERALS=1)
+target_include_directories(dynarmic_test_generator PRIVATE . ../src)
+target_compile_options(dynarmic_test_generator PRIVATE ${DYNARMIC_CXX_FLAGS})
+target_compile_definitions(dynarmic_test_generator PRIVATE FMT_USE_USER_DEFINED_LITERALS=1)
+
+#
+# dynarmic_test_reader
+#
+add_executable(dynarmic_test_reader
+ test_reader.cpp
+)
+create_target_directory_groups(dynarmic_test_reader)
+target_link_libraries(dynarmic_test_reader PRIVATE dynarmic fmt::fmt merry::mcl)
+if (BOOST_NO_HEADERS)
+ target_link_libraries(dynarmic_test_reader PRIVATE Boost::variant Boost::icl Boost::pool)
+else()
+ target_link_libraries(dynarmic_test_reader PRIVATE Boost::headers)
endif()
+target_include_directories(dynarmic_test_reader PRIVATE . ../src)
+target_compile_options(dynarmic_test_reader PRIVATE ${DYNARMIC_CXX_FLAGS})
+target_compile_definitions(dynarmic_test_reader PRIVATE FMT_USE_USER_DEFINED_LITERALS=1)
+#
create_target_directory_groups(dynarmic_tests)
-target_link_libraries(dynarmic_tests PRIVATE dynarmic Boost::headers Catch2::Catch2WithMain fmt::fmt merry::mcl)
+target_link_libraries(dynarmic_tests PRIVATE dynarmic Catch2::Catch2WithMain fmt::fmt merry::mcl)
+if (BOOST_NO_HEADERS)
+ target_link_libraries(dynarmic_tests PRIVATE Boost::variant Boost::icl Boost::pool)
+else()
+ target_link_libraries(dynarmic_tests PRIVATE Boost::headers)
+endif()
target_include_directories(dynarmic_tests PRIVATE . ../src)
target_compile_options(dynarmic_tests PRIVATE ${DYNARMIC_CXX_FLAGS})
target_compile_definitions(dynarmic_tests PRIVATE FMT_USE_USER_DEFINED_LITERALS=1)