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 # 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 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 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(code.getCode()); const u64 code_end = code_begin + code.GetTotalCodeSize(); impl = std::make_unique(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(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 -#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 #include #include -#include -#ifdef __APPLE__ -# include -# include -#else -# include -# ifndef __OpenBSD__ -# include -# endif -# ifdef __sun__ -# include -# endif -#endif - #include - #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 - # 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(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 -#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 +# include +#else +# include +# ifndef __OpenBSD__ +# include +# endif +# ifdef __sun__ +# include +# endif +# ifdef __linux__ +# include +# endif +#endif + +#ifdef ARCHITECTURE_x86_64 +# ifdef __OpenBSD__ +# define CTX_DECLARE(raw_context) ucontext_t* ucontext = reinterpret_cast(raw_context); +# else +# define CTX_DECLARE(raw_context) \ + ucontext_t* ucontext = reinterpret_cast(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(raw_context); +# else +# define CTX_DECLARE(raw_context) \ + ucontext_t* ucontext = reinterpret_cast(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(header) + header->size); + return reinterpret_cast(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) -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 - ) +# +# dynarmic_test_generator +# +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() +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) -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) +# +# 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)