diff --git a/CMakeLists.txt b/CMakeLists.txt index 9abca561f3..98db004339 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,7 +50,7 @@ CMAKE_DEPENDENT_OPTION(ENABLE_SDL2 "Enable the SDL2 frontend" ON "NOT ANDROID" O set(EXT_DEFAULT ON) -if (PLATFORM_FREEBSD) +if (PLATFORM_FREEBSD OR APPLE) set(EXT_DEFAULT OFF) endif() @@ -314,7 +314,7 @@ if (UNIX) add_definitions(-DYUZU_UNIX=1) endif() -if (ARCHITECTURE_arm64 AND (ANDROID OR PLATFORM_LINUX)) +if (ARCHITECTURE_arm64 AND (ANDROID OR APPLE OR PLATFORM_LINUX)) set(HAS_NCE 1) add_definitions(-DHAS_NCE=1) endif() @@ -455,10 +455,17 @@ if (YUZU_USE_CPM) if (enet_ADDED) target_include_directories(enet INTERFACE ${enet_SOURCE_DIR}/include) + if (NOT TARGET enet::enet) + add_library(enet::enet ALIAS enet) + endif() endif() # Opus AddJsonPackage(opus) + + if (NOT TARGET Opus::opus) + add_library(Opus::opus ALIAS opus) + endif() else() # Enforce the search mode of non-required packages for better and shorter failure messages find_package(fmt 8 REQUIRED) diff --git a/CMakeModules/CPMUtil.cmake b/CMakeModules/CPMUtil.cmake index 9daada47ad..6ea8243cf7 100644 --- a/CMakeModules/CPMUtil.cmake +++ b/CMakeModules/CPMUtil.cmake @@ -11,10 +11,12 @@ # Future crueter: Wow this was a lie and a half, at this point I might as well make my own CPN # haha just kidding... unless? +cmake_minimum_required(VERSION 3.22) + if (MSVC OR ANDROID) - set(BUNDLED_DEFAULT OFF) -else() set(BUNDLED_DEFAULT ON) +else() + set(BUNDLED_DEFAULT OFF) endif() option(CPMUTIL_FORCE_BUNDLED @@ -23,7 +25,6 @@ option(CPMUTIL_FORCE_BUNDLED option(CPMUTIL_FORCE_SYSTEM "Force system packages for all CPM dependencies (NOT RECOMMENDED)" OFF) -cmake_minimum_required(VERSION 3.22) include(CPM) # TODO(crueter): Better solution for separate cpmfiles e.g. per-directory diff --git a/docs/CrossCompileARM64.md b/docs/CrossCompileARM64.md new file mode 100644 index 0000000000..003c2aa826 --- /dev/null +++ b/docs/CrossCompileARM64.md @@ -0,0 +1,8 @@ +# Cross compile ARM64 + +A painless guide for cross compilation (or to test NCE) from a x86_64 system without polluting your main. + +- Install QEMU: `sudo pkg install qemu` +- Download Debian 13: `wget https://cdimage.debian.org/debian-cd/current/arm64/iso-cd/debian-13.0.0-arm64-netinst.iso` +- Create a system disk: `qemu-img create -f qcow2 debian-13-arm64-ci.qcow2 30G` +- Run the VM: `qemu-system-aarch64 -M virt -m 2G -cpu max -bios /usr/local/share/qemu/edk2-aarch64-code.fd -drive if=none,file=debian-13.0.0-arm64-netinst.iso,format=raw,id=cdrom -device scsi-cd,drive=cdrom -drive if=none,file=debian-13-arm64-ci.qcow2,id=hd0,format=qcow2 -device virtio-blk-device,drive=hd0 -device virtio-gpu-pci -device usb-ehci -device usb-kbd -device intel-hda -device hda-output -nic user,model=virtio-net-pci` diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index e917e4e7d8..4d7686f0f2 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -54,6 +54,7 @@ endif() add_subdirectory(glad) # mbedtls +# TODO(crueter): Findmbedtls that ONLY accepts mbedtls2 AddJsonPackage(mbedtls) if (mbedtls_ADDED) diff --git a/externals/cpmfile.json b/externals/cpmfile.json index 4bc4a97ca4..a3e58be2c7 100644 --- a/externals/cpmfile.json +++ b/externals/cpmfile.json @@ -5,7 +5,8 @@ "hash": "769ad1e94c570671071e1f2a5c0f1027e0bf6bcdd1a80ea8ac970f2c86bc45ce4e31aa88d6d8110fc1bed1de81c48bc624df1b38a26f8b340a44e109d784a966", "patches": [ "0001-cmake-version.patch" - ] + ], + "bundled": true }, "spirv-headers": { "package": "SPIRV-Headers", diff --git a/externals/libusb/libusb b/externals/libusb/libusb index c060e9ce30..3dbfa16f0c 160000 --- a/externals/libusb/libusb +++ b/externals/libusb/libusb @@ -1 +1 @@ -Subproject commit c060e9ce30ac2e3ffb49d94209c4dae77b6642f7 +Subproject commit 3dbfa16f0cd9e8ed4fec916c6c00f41c738cb8f4 diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index e040ec756d..f72448bc87 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt @@ -227,7 +227,7 @@ else() endif() target_include_directories(audio_core PRIVATE ${OPUS_INCLUDE_DIRS}) -target_link_libraries(audio_core PUBLIC common core opus) +target_link_libraries(audio_core PUBLIC common core Opus::opus) if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64) target_link_libraries(audio_core PRIVATE dynarmic::dynarmic) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 1aa433db32..daeeb91acc 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -283,4 +283,13 @@ if(YUZU_USE_PRECOMPILED_HEADERS) target_precompile_headers(common PRIVATE precompiled_headers.h) endif() +# IOPS (needed for power state) requires linking to IOKit +if (APPLE) + find_library(IOKIT_LIBRARY IOKit) + if(NOT IOKIT_LIBRARY) + message(FATAL_ERROR "IOKit not found, did you install XCode tools?") + endif() + target_link_libraries(common PRIVATE ${IOKIT_LIBRARY}) +endif() + create_target_directory_groups(common) diff --git a/src/core/arm/nce/arm_nce.cpp b/src/core/arm/nce/arm_nce.cpp index 877e8ac3c7..d01a5da677 100644 --- a/src/core/arm/nce/arm_nce.cpp +++ b/src/core/arm/nce/arm_nce.cpp @@ -13,12 +13,14 @@ #include "core/arm/nce/patcher.h" #include "core/core.h" #include "core/memory.h" - #include "core/hle/kernel/k_process.h" +#include "dynarmic/common/context.h" + #include #include #include +#include namespace Core { @@ -33,95 +35,67 @@ static_assert(offsetof(NativeExecutionParameters, native_context) == TpidrEl0Nat static_assert(offsetof(NativeExecutionParameters, lock) == TpidrEl0Lock); static_assert(offsetof(NativeExecutionParameters, magic) == TpidrEl0TlsMagic); -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); -} - using namespace Common::Literals; constexpr u32 StackSize = 128_KiB; } // namespace void* ArmNce::RestoreGuestContext(void* raw_context) { - // Retrieve the host context. - auto& host_ctx = static_cast(raw_context)->uc_mcontext; - - // Thread-local parameters will be located in x9. - auto* tpidr = reinterpret_cast(host_ctx.regs[9]); - auto* guest_ctx = static_cast(tpidr->native_context); - - // Retrieve the host floating point state. - auto* fpctx = GetFloatingPointState(host_ctx); - - // Save host callee-saved registers. - std::memcpy(guest_ctx->host_ctx.host_saved_vregs.data(), &fpctx->vregs[8], - sizeof(guest_ctx->host_ctx.host_saved_vregs)); - std::memcpy(guest_ctx->host_ctx.host_saved_regs.data(), &host_ctx.regs[19], - sizeof(guest_ctx->host_ctx.host_saved_regs)); - - // Save stack pointer. - guest_ctx->host_ctx.host_sp = host_ctx.sp; - + CTX_DECLARE(raw_context); // Restore all guest state except tpidr_el0. - host_ctx.sp = guest_ctx->sp; - host_ctx.pc = guest_ctx->pc; - host_ctx.pstate = guest_ctx->pstate; - fpctx->fpcr = guest_ctx->fpcr; - fpctx->fpsr = guest_ctx->fpsr; - std::memcpy(host_ctx.regs, guest_ctx->cpu_registers.data(), sizeof(host_ctx.regs)); - std::memcpy(fpctx->vregs, guest_ctx->vector_registers.data(), sizeof(fpctx->vregs)); - + // Thread-local parameters will be located in x9. + auto* tpidr = reinterpret_cast(CTX_X(9)); + auto* guest_ctx = static_cast(tpidr->native_context); + // Save host callee-saved registers. + std::memcpy(guest_ctx->host_ctx.host_saved_vregs.data(), &CTX_Q(8), + sizeof(guest_ctx->host_ctx.host_saved_vregs)); + // Save stack pointer. + guest_ctx->host_ctx.host_sp = CTX_SP; + CTX_PC = guest_ctx->sp; + CTX_SP = guest_ctx->pc; + CTX_PSTATE = guest_ctx->pstate; + CTX_FPCR = guest_ctx->fpcr; + CTX_FPSR = guest_ctx->fpsr; + std::memcpy(&CTX_X(0), guest_ctx->cpu_registers.data(), sizeof(guest_ctx->cpu_registers)); + std::memcpy(&CTX_Q(0), guest_ctx->vector_registers.data(), sizeof(guest_ctx->vector_registers)); // Return the new thread-local storage pointer. return tpidr; } void ArmNce::SaveGuestContext(GuestContext* guest_ctx, void* raw_context) { - // Retrieve the host context. - auto& host_ctx = static_cast(raw_context)->uc_mcontext; - - // Retrieve the host floating point state. - auto* fpctx = GetFloatingPointState(host_ctx); - + CTX_DECLARE(raw_context); // Save all guest registers except tpidr_el0. - std::memcpy(guest_ctx->cpu_registers.data(), host_ctx.regs, sizeof(host_ctx.regs)); - std::memcpy(guest_ctx->vector_registers.data(), fpctx->vregs, sizeof(fpctx->vregs)); - guest_ctx->fpsr = fpctx->fpsr; - guest_ctx->fpcr = fpctx->fpcr; - guest_ctx->pstate = static_cast(host_ctx.pstate); - guest_ctx->pc = host_ctx.pc; - guest_ctx->sp = host_ctx.sp; - + std::memcpy(guest_ctx->cpu_registers.data(), &CTX_X(0), sizeof(guest_ctx->cpu_registers)); + std::memcpy(guest_ctx->vector_registers.data(), &CTX_Q(0), sizeof(guest_ctx->vector_registers)); + guest_ctx->fpsr = CTX_FPSR; + guest_ctx->fpcr = CTX_FPCR; + guest_ctx->pc = CTX_PC; + guest_ctx->sp = CTX_SP; + guest_ctx->pstate = u32(CTX_PSTATE); // Restore stack pointer. - host_ctx.sp = guest_ctx->host_ctx.host_sp; + CTX_SP = guest_ctx->host_ctx.host_sp; // Restore host callee-saved registers. - std::memcpy(&host_ctx.regs[19], guest_ctx->host_ctx.host_saved_regs.data(), + std::memcpy(&CTX_X(19), guest_ctx->host_ctx.host_saved_regs.data(), sizeof(guest_ctx->host_ctx.host_saved_regs)); - std::memcpy(&fpctx->vregs[8], guest_ctx->host_ctx.host_saved_vregs.data(), + std::memcpy(&CTX_Q(8), guest_ctx->host_ctx.host_saved_vregs.data(), sizeof(guest_ctx->host_ctx.host_saved_vregs)); - // Return from the call on exit by setting pc to x30. - host_ctx.pc = guest_ctx->host_ctx.host_saved_regs[11]; - + CTX_PC = guest_ctx->host_ctx.host_saved_regs[11]; // Clear esr_el1 and return it. - host_ctx.regs[0] = guest_ctx->esr_el1.exchange(0); + CTX_X(0) = guest_ctx->esr_el1.exchange(0); } bool ArmNce::HandleFailedGuestFault(GuestContext* guest_ctx, void* raw_info, void* raw_context) { - auto& host_ctx = static_cast(raw_context)->uc_mcontext; + CTX_DECLARE(raw_context); auto* info = static_cast(raw_info); // We can't handle the access, so determine why we crashed. - const bool is_prefetch_abort = host_ctx.pc == reinterpret_cast(info->si_addr); - + auto const is_prefetch_abort = CTX_PC == reinterpret_cast(info->si_addr); // For data aborts, skip the instruction and return to guest code. // This will allow games to continue in many scenarios where they would otherwise crash. if (!is_prefetch_abort) { - host_ctx.pc += 4; + CTX_PC += 4; return true; } @@ -142,17 +116,13 @@ bool ArmNce::HandleFailedGuestFault(GuestContext* guest_ctx, void* raw_info, voi } bool ArmNce::HandleGuestAlignmentFault(GuestContext* guest_ctx, void* raw_info, void* raw_context) { - auto& host_ctx = static_cast(raw_context)->uc_mcontext; - auto* fpctx = GetFloatingPointState(host_ctx); + CTX_DECLARE(raw_context); auto& memory = guest_ctx->system->ApplicationMemory(); - // Match and execute an instruction. - auto next_pc = MatchAndExecuteOneInstruction(memory, &host_ctx, fpctx); - if (next_pc) { - host_ctx.pc = *next_pc; + if (auto next_pc = MatchAndExecuteOneInstruction(memory, raw_context); next_pc) { + CTX_PC = *next_pc; return true; } - // We couldn't handle the access. return HandleFailedGuestFault(guest_ctx, raw_info, raw_context); } @@ -275,9 +245,51 @@ ArmNce::ArmNce(System& system, bool uses_wall_clock, std::size_t core_index) ArmNce::~ArmNce() = default; +// Borrowed from libusb +static unsigned int posix_gettid(void) { + static thread_local unsigned int tl_tid; + int tid; + if (tl_tid) + return tl_tid; +#if defined(__ANDROID__) + tid = gettid(); +#elif defined(__APPLE__) +#ifdef HAVE_PTHREAD_THREADID_NP + uint64_t thread_id; + if (pthread_threadid_np(NULL, &thread_id) == 0) + tid = (int)thread_id; + else + tid = -1; +#else + tid = (int)pthread_mach_thread_np(pthread_self()); +#endif +#elif defined(__HAIKU__) + tid = get_pthread_thread_id(pthread_self()); +#elif defined(__linux__) + tid = (int)syscall(SYS_gettid); +#elif defined(__NetBSD__) + tid = _lwp_self(); +#elif defined(__OpenBSD__) + /* The following only works with OpenBSD > 5.1 as it requires + * real thread support. For 5.1 and earlier, -1 is returned. */ + tid = syscall(SYS_getthrid); +#elif defined(__sun__) + tid = _lwp_self(); +#else + tid = -1; +#endif + if (tid == -1) { + /* If we don't have a thread ID, at least return a unique + * value that can be used to distinguish individual + * threads. */ + tid = (int)(intptr_t)pthread_self(); + } + return tl_tid = (unsigned int)tid; +} + void ArmNce::Initialize() { if (m_thread_id == -1) { - m_thread_id = gettid(); + m_thread_id = posix_gettid(); } // Configure signal stack. @@ -308,7 +320,7 @@ void ArmNce::Initialize() { &ArmNce::ReturnToRunCodeByExceptionLevelChangeSignalHandler); return_to_run_code_action.sa_mask = signal_mask; Common::SigAction(ReturnToRunCodeByExceptionLevelChangeSignal, &return_to_run_code_action, - nullptr); + nullptr); struct sigaction break_from_run_code_action {}; break_from_run_code_action.sa_flags = SA_SIGINFO | SA_ONSTACK; @@ -378,7 +390,11 @@ void ArmNce::SignalInterrupt(Kernel::KThread* thread) { if (params->is_running) { // We should signal to the running thread. // The running thread will unlock the thread context. +#ifdef __linux__ syscall(SYS_tkill, m_thread_id, BreakFromRunCodeSignal); +#else + pthread_kill(pthread_t(m_thread_id), int(BreakFromRunCodeSignal)); +#endif } else { // If the thread is no longer running, we have nothing to do. UnlockThreadParameters(params); diff --git a/src/core/arm/nce/arm_nce.s b/src/core/arm/nce/arm_nce.s index c68c059491..44e0635346 100644 --- a/src/core/arm/nce/arm_nce.s +++ b/src/core/arm/nce/arm_nce.s @@ -9,10 +9,15 @@ /* static HaltReason Core::ArmNce::ReturnToRunCodeByTrampoline(void* tpidr, Core::GuestContext* ctx, u64 trampoline_addr) */ +#ifdef __APPLE__ +.global __ZN4Core6ArmNce27ReturnToRunCodeByTrampolineEPvPNS_12GuestContextEy +__ZN4Core6ArmNce27ReturnToRunCodeByTrampolineEPvPNS_12GuestContextEy: +#else .section .text._ZN4Core6ArmNce27ReturnToRunCodeByTrampolineEPvPNS_12GuestContextEm, "ax", %progbits -.global _ZN4Core6ArmNce27ReturnToRunCodeByTrampolineEPvPNS_12GuestContextEm .type _ZN4Core6ArmNce27ReturnToRunCodeByTrampolineEPvPNS_12GuestContextEm, %function +.global _ZN4Core6ArmNce27ReturnToRunCodeByTrampolineEPvPNS_12GuestContextEm _ZN4Core6ArmNce27ReturnToRunCodeByTrampolineEPvPNS_12GuestContextEm: +#endif /* Back up host sp to x3. */ /* Back up host tpidr_el0 to x4. */ mov x3, sp @@ -50,38 +55,51 @@ _ZN4Core6ArmNce27ReturnToRunCodeByTrampolineEPvPNS_12GuestContextEm: /* static HaltReason Core::ArmNce::ReturnToRunCodeByExceptionLevelChange(int tid, void* tpidr) */ +#ifdef __APPLE__ +.global __ZN4Core6ArmNce37ReturnToRunCodeByExceptionLevelChangeEiPv +__ZN4Core6ArmNce37ReturnToRunCodeByExceptionLevelChangeEiPv: +#else .section .text._ZN4Core6ArmNce37ReturnToRunCodeByExceptionLevelChangeEiPv, "ax", %progbits -.global _ZN4Core6ArmNce37ReturnToRunCodeByExceptionLevelChangeEiPv .type _ZN4Core6ArmNce37ReturnToRunCodeByExceptionLevelChangeEiPv, %function +.global _ZN4Core6ArmNce37ReturnToRunCodeByExceptionLevelChangeEiPv _ZN4Core6ArmNce37ReturnToRunCodeByExceptionLevelChangeEiPv: +#endif /* This jumps to the signal handler, which will restore the entire context. */ - /* On entry, x0 = thread id, which is already in the right place. */ - + /* On entry, x0 = thread id, which is already in the right place. Even on macOS. */ /* Move tpidr to x9 so it is not trampled. */ mov x9, x1 - - /* Set up arguments. */ - mov x8, #(__NR_tkill) mov x1, #(ReturnToRunCodeByExceptionLevelChangeSignal) - - /* Tail call the signal handler. */ - svc #0 - - /* Block execution from flowing here. */ - brk #1000 - +#ifdef __APPLE__ + /* I can never be happy, why no tkill in mach kernel? Ugh ... */ + /* Signature: 328 AUE_PTHREADKILL ALL { int __pthread_kill(int thread_port, int sig); } */ + mov x16, #(328) +#else + /* Signature: int tgkill(pid_t tgid, pid_t tid, int sig); */ + mov x8, #(__NR_tkill) +#endif + svc #0 /* Tail call the signal handler. */ + brk #1000 /* Block execution from flowing here. */ /* static void Core::ArmNce::ReturnToRunCodeByExceptionLevelChangeSignalHandler(int sig, void* info, void* raw_context) */ +#ifdef __APPLE__ +.global __ZN4Core6ArmNce50ReturnToRunCodeByExceptionLevelChangeSignalHandlerEiPvS1_ +__ZN4Core6ArmNce50ReturnToRunCodeByExceptionLevelChangeSignalHandlerEiPvS1_: +#else .section .text._ZN4Core6ArmNce50ReturnToRunCodeByExceptionLevelChangeSignalHandlerEiPvS1_, "ax", %progbits -.global _ZN4Core6ArmNce50ReturnToRunCodeByExceptionLevelChangeSignalHandlerEiPvS1_ .type _ZN4Core6ArmNce50ReturnToRunCodeByExceptionLevelChangeSignalHandlerEiPvS1_, %function +.global _ZN4Core6ArmNce50ReturnToRunCodeByExceptionLevelChangeSignalHandlerEiPvS1_ _ZN4Core6ArmNce50ReturnToRunCodeByExceptionLevelChangeSignalHandlerEiPvS1_: +#endif stp x29, x30, [sp, #-0x10]! mov x29, sp /* Call the context restorer with the raw context. */ mov x0, x2 +#ifdef __APPLE__ + bl __ZN4Core6ArmNce19RestoreGuestContextEPv +#else bl _ZN4Core6ArmNce19RestoreGuestContextEPv +#endif /* Save the old value of tpidr_el0. */ mrs x8, tpidr_el0 @@ -92,7 +110,11 @@ _ZN4Core6ArmNce50ReturnToRunCodeByExceptionLevelChangeSignalHandlerEiPvS1_: msr tpidr_el0, x0 /* Unlock the context. */ +#ifdef __APPLE__ + bl __ZN4Core6ArmNce22UnlockThreadParametersEPv +#else bl _ZN4Core6ArmNce22UnlockThreadParametersEPv +#endif /* Returning from here will enter the guest. */ ldp x29, x30, [sp], #0x10 @@ -100,10 +122,15 @@ _ZN4Core6ArmNce50ReturnToRunCodeByExceptionLevelChangeSignalHandlerEiPvS1_: /* static void Core::ArmNce::BreakFromRunCodeSignalHandler(int sig, void* info, void* raw_context) */ +#ifdef __APPLE__ +.global __ZN4Core6ArmNce29BreakFromRunCodeSignalHandlerEiPvS1_ +__ZN4Core6ArmNce29BreakFromRunCodeSignalHandlerEiPvS1_: +#else .section .text._ZN4Core6ArmNce29BreakFromRunCodeSignalHandlerEiPvS1_, "ax", %progbits -.global _ZN4Core6ArmNce29BreakFromRunCodeSignalHandlerEiPvS1_ .type _ZN4Core6ArmNce29BreakFromRunCodeSignalHandlerEiPvS1_, %function +.global _ZN4Core6ArmNce29BreakFromRunCodeSignalHandlerEiPvS1_ _ZN4Core6ArmNce29BreakFromRunCodeSignalHandlerEiPvS1_: +#endif /* Check to see if we have the correct TLS magic. */ mrs x8, tpidr_el0 ldr w9, [x8, #(TpidrEl0TlsMagic)] @@ -121,7 +148,11 @@ _ZN4Core6ArmNce29BreakFromRunCodeSignalHandlerEiPvS1_: /* Tail call the restorer. */ mov x1, x2 +#ifdef __APPLE__ + b __ZN4Core6ArmNce16SaveGuestContextEPNS_12GuestContextEPv +#else b _ZN4Core6ArmNce16SaveGuestContextEPNS_12GuestContextEPv +#endif /* Returning from here will enter host code. */ @@ -131,10 +162,15 @@ _ZN4Core6ArmNce29BreakFromRunCodeSignalHandlerEiPvS1_: /* static void Core::ArmNce::GuestAlignmentFaultSignalHandler(int sig, void* info, void* raw_context) */ +#ifdef __APPLE__ +.global __ZN4Core6ArmNce32GuestAlignmentFaultSignalHandlerEiPvS1_ +__ZN4Core6ArmNce32GuestAlignmentFaultSignalHandlerEiPvS1_: +#else .section .text._ZN4Core6ArmNce32GuestAlignmentFaultSignalHandlerEiPvS1_, "ax", %progbits -.global _ZN4Core6ArmNce32GuestAlignmentFaultSignalHandlerEiPvS1_ .type _ZN4Core6ArmNce32GuestAlignmentFaultSignalHandlerEiPvS1_, %function +.global _ZN4Core6ArmNce32GuestAlignmentFaultSignalHandlerEiPvS1_ _ZN4Core6ArmNce32GuestAlignmentFaultSignalHandlerEiPvS1_: +#endif /* Check to see if we have the correct TLS magic. */ mrs x8, tpidr_el0 ldr w9, [x8, #(TpidrEl0TlsMagic)] @@ -146,7 +182,11 @@ _ZN4Core6ArmNce32GuestAlignmentFaultSignalHandlerEiPvS1_: /* Incorrect TLS magic, so this is a host fault. */ /* Tail call the handler. */ +#ifdef __APPLE__ + b __ZN4Core6ArmNce24HandleHostAlignmentFaultEiPvS1_ +#else b _ZN4Core6ArmNce24HandleHostAlignmentFaultEiPvS1_ +#endif 1: /* Correct TLS magic, so this is a guest fault. */ @@ -163,7 +203,11 @@ _ZN4Core6ArmNce32GuestAlignmentFaultSignalHandlerEiPvS1_: msr tpidr_el0, x3 /* Call the handler. */ +#ifdef __APPLE__ + bl __ZN4Core6ArmNce25HandleGuestAlignmentFaultEPNS_12GuestContextEPvS3_ +#else bl _ZN4Core6ArmNce25HandleGuestAlignmentFaultEPNS_12GuestContextEPvS3_ +#endif /* If the handler returned false, we want to preserve the host tpidr_el0. */ cbz x0, 2f @@ -177,10 +221,15 @@ _ZN4Core6ArmNce32GuestAlignmentFaultSignalHandlerEiPvS1_: ret /* static void Core::ArmNce::GuestAccessFaultSignalHandler(int sig, void* info, void* raw_context) */ +#ifdef __APPLE__ +.global __ZN4Core6ArmNce29GuestAccessFaultSignalHandlerEiPvS1_ +__ZN4Core6ArmNce29GuestAccessFaultSignalHandlerEiPvS1_: +#else .section .text._ZN4Core6ArmNce29GuestAccessFaultSignalHandlerEiPvS1_, "ax", %progbits -.global _ZN4Core6ArmNce29GuestAccessFaultSignalHandlerEiPvS1_ .type _ZN4Core6ArmNce29GuestAccessFaultSignalHandlerEiPvS1_, %function +.global _ZN4Core6ArmNce29GuestAccessFaultSignalHandlerEiPvS1_ _ZN4Core6ArmNce29GuestAccessFaultSignalHandlerEiPvS1_: +#endif /* Check to see if we have the correct TLS magic. */ mrs x8, tpidr_el0 ldr w9, [x8, #(TpidrEl0TlsMagic)] @@ -192,7 +241,11 @@ _ZN4Core6ArmNce29GuestAccessFaultSignalHandlerEiPvS1_: /* Incorrect TLS magic, so this is a host fault. */ /* Tail call the handler. */ +#ifdef __APPLE__ + b __ZN4Core6ArmNce21HandleHostAccessFaultEiPvS1_ +#else b _ZN4Core6ArmNce21HandleHostAccessFaultEiPvS1_ +#endif 1: /* Correct TLS magic, so this is a guest fault. */ @@ -209,7 +262,11 @@ _ZN4Core6ArmNce29GuestAccessFaultSignalHandlerEiPvS1_: msr tpidr_el0, x3 /* Call the handler. */ +#ifdef __APPLE__ + bl __ZN4Core6ArmNce22HandleGuestAccessFaultEPNS_12GuestContextEPvS3_ +#else bl _ZN4Core6ArmNce22HandleGuestAccessFaultEPNS_12GuestContextEPvS3_ +#endif /* If the handler returned false, we want to preserve the host tpidr_el0. */ cbz x0, 2f @@ -224,10 +281,15 @@ _ZN4Core6ArmNce29GuestAccessFaultSignalHandlerEiPvS1_: /* static void Core::ArmNce::LockThreadParameters(void* tpidr) */ +#ifdef __APPLE__ +.global __ZN4Core6ArmNce20LockThreadParametersEPv +__ZN4Core6ArmNce20LockThreadParametersEPv: +#else .section .text._ZN4Core6ArmNce20LockThreadParametersEPv, "ax", %progbits -.global _ZN4Core6ArmNce20LockThreadParametersEPv .type _ZN4Core6ArmNce20LockThreadParametersEPv, %function +.global _ZN4Core6ArmNce20LockThreadParametersEPv _ZN4Core6ArmNce20LockThreadParametersEPv: +#endif /* Offset to lock member. */ add x0, x0, #(TpidrEl0Lock) @@ -252,10 +314,15 @@ _ZN4Core6ArmNce20LockThreadParametersEPv: /* static void Core::ArmNce::UnlockThreadParameters(void* tpidr) */ +#ifdef __APPLE__ +.global __ZN4Core6ArmNce22UnlockThreadParametersEPv +__ZN4Core6ArmNce22UnlockThreadParametersEPv: +#else .section .text._ZN4Core6ArmNce22UnlockThreadParametersEPv, "ax", %progbits -.global _ZN4Core6ArmNce22UnlockThreadParametersEPv .type _ZN4Core6ArmNce22UnlockThreadParametersEPv, %function +.global _ZN4Core6ArmNce22UnlockThreadParametersEPv _ZN4Core6ArmNce22UnlockThreadParametersEPv: +#endif /* Offset to lock member. */ add x0, x0, #(TpidrEl0Lock) diff --git a/src/core/arm/nce/arm_nce_asm_definitions.h b/src/core/arm/nce/arm_nce_asm_definitions.h index 8ea4383f73..120a3539fc 100644 --- a/src/core/arm/nce/arm_nce_asm_definitions.h +++ b/src/core/arm/nce/arm_nce_asm_definitions.h @@ -5,22 +5,24 @@ #define __ASSEMBLY__ +#ifdef __APPLE__ +/* https://cpip.readthedocs.io/en/stable/_static/dictobject.c/signal.h_bbe000f9714f274340a28e000a369354.html */ +#define ReturnToRunCodeByExceptionLevelChangeSignal 31 +#define BreakFromRunCodeSignal 16 +#define GuestAccessFaultSignal 11 +#define GuestAlignmentFaultSignal 10 +#else #include #include - #define ReturnToRunCodeByExceptionLevelChangeSignal SIGUSR2 #define BreakFromRunCodeSignal SIGURG #define GuestAccessFaultSignal SIGSEGV #define GuestAlignmentFaultSignal SIGBUS +#endif #define GuestContextSp 0xF8 #define GuestContextHostContext 0x320 -#define HostContextSpTpidrEl0 0xE0 -#define HostContextTpidrEl0 0xE8 -#define HostContextRegs 0x0 -#define HostContextVregs 0x60 - #define TpidrEl0NativeContext 0x10 #define TpidrEl0Lock 0x18 #define TpidrEl0TlsMagic 0x20 @@ -28,3 +30,8 @@ #define SpinLockLocked 0 #define SpinLockUnlocked 1 + +#define HostContextSpTpidrEl0 0xE0 +#define HostContextTpidrEl0 0xE8 +#define HostContextRegs 0x0 +#define HostContextVregs 0x60 diff --git a/src/core/arm/nce/interpreter_visitor.cpp b/src/core/arm/nce/interpreter_visitor.cpp index bbe0289f8e..c18590d5ff 100644 --- a/src/core/arm/nce/interpreter_visitor.cpp +++ b/src/core/arm/nce/interpreter_visitor.cpp @@ -2,8 +2,9 @@ // SPDX-FileCopyrightText: Copyright 2023 merryhime // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/bit_cast.h" #include "core/arm/nce/interpreter_visitor.h" +#include "core/memory.h" +#include "dynarmic/common/context.h" namespace Core { @@ -790,23 +791,20 @@ bool InterpreterVisitor::LDR_reg_fpsimd(Imm<2> size, Imm<1> opc_1, Reg Rm, Imm<3 return this->SIMDOffset(scale, shift, opc_0, Rm, option, Rn, Vt); } -std::optional MatchAndExecuteOneInstruction(Core::Memory::Memory& memory, mcontext_t* context, - fpsimd_context* fpsimd_context) { - std::span regs(reinterpret_cast(context->regs), 31); - std::span vregs(reinterpret_cast(fpsimd_context->vregs), 32); - u64& sp = *reinterpret_cast(&context->sp); - const u64& pc = *reinterpret_cast(&context->pc); - +std::optional MatchAndExecuteOneInstruction(Core::Memory::Memory& memory, void* raw_context) { + CTX_DECLARE(raw_context); + std::span regs(reinterpret_cast(&CTX_X(0)), 31); + std::span vregs(reinterpret_cast(&CTX_Q(0)), 32); + u64& sp = *reinterpret_cast(&CTX_SP); + const u64& pc = *reinterpret_cast(&CTX_PC); InterpreterVisitor visitor(memory, regs, vregs, sp, pc); u32 instruction = memory.Read32(pc); bool was_executed = false; - if (auto decoder = Dynarmic::A64::Decode(instruction)) { was_executed = decoder->get().call(visitor, instruction); } else { LOG_ERROR(Core_ARM, "Unallocated encoding: {:#x}", instruction); } - return was_executed ? std::optional(pc + 4) : std::nullopt; } diff --git a/src/core/arm/nce/interpreter_visitor.h b/src/core/arm/nce/interpreter_visitor.h index f90d876abb..d292f4ebee 100644 --- a/src/core/arm/nce/interpreter_visitor.h +++ b/src/core/arm/nce/interpreter_visitor.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include #include "core/arm/nce/visitor_base.h" @@ -97,7 +98,6 @@ private: const u64& m_pc; }; -std::optional MatchAndExecuteOneInstruction(Core::Memory::Memory& memory, mcontext_t* context, - fpsimd_context* fpsimd_context); +std::optional MatchAndExecuteOneInstruction(Core::Memory::Memory& memory, void* raw_context); } // namespace Core diff --git a/src/core/arm/nce/patcher.cpp b/src/core/arm/nce/patcher.cpp index b8387ce7cb..e57fd95fa5 100644 --- a/src/core/arm/nce/patcher.cpp +++ b/src/core/arm/nce/patcher.cpp @@ -4,13 +4,11 @@ #include "common/arm64/native_clock.h" #include "common/bit_cast.h" #include "common/literals.h" -#include "core/arm/nce/arm_nce.h" #include "core/arm/nce/guest_context.h" #include "core/arm/nce/instructions.h" #include "core/arm/nce/patcher.h" -#include "core/core.h" -#include "core/core_timing.h" -#include "core/hle/kernel/svc.h" +#include "core/hle/kernel/k_thread.h" +#include "core/memory.h" namespace Core::NCE { diff --git a/src/dynarmic/src/dynarmic/backend/exception_handler_generic.cpp b/src/dynarmic/src/dynarmic/backend/exception_handler_generic.cpp index ad7df25ca6..6f9a3ff18a 100644 --- a/src/dynarmic/src/dynarmic/backend/exception_handler_generic.cpp +++ b/src/dynarmic/src/dynarmic/backend/exception_handler_generic.cpp @@ -17,7 +17,7 @@ ExceptionHandler::~ExceptionHandler() = default; 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 } 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 7695df57d2..819ce19228 100644 --- a/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp +++ b/src/dynarmic/src/dynarmic/backend/exception_handler_posix.cpp @@ -8,19 +8,6 @@ #include "dynarmic/backend/exception_handler.h" -#ifdef __APPLE__ -# include -# include -#else -# include -# ifndef __OpenBSD__ -# include -# endif -# ifdef __sun__ -# include -# endif -#endif - #include #include #include @@ -29,12 +16,13 @@ #include #include "dynarmic/common/assert.h" +#include "dynarmic/common/context.h" #include #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" @@ -148,122 +136,35 @@ void SigHandler::RemoveCodeBlock(u64 host_pc) { void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) { 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); +#ifdef ARCHITECTURE_x86_64 { std::lock_guard guard(sig_handler->code_block_infos_mutex); - const auto iter = sig_handler->FindCodeBlockInfo(CTX_RIP); if (iter != sig_handler->code_block_infos.end()) { FakeCall fc = iter->cb(CTX_RIP); - CTX_RSP -= sizeof(u64); *mcl::bit_cast(CTX_RSP) = fc.ret_rip; CTX_RIP = fc.call_rip; - return; } } - 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::lock_guard guard(sig_handler->code_block_infos_mutex); - const auto iter = sig_handler->FindCodeBlockInfo(CTX_PC); if (iter != sig_handler->code_block_infos.end()) { FakeCall fc = iter->cb(CTX_PC); - CTX_PC = fc.call_pc; - return; } } - fmt::print(stderr, "Unhandled {} at pc {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_PC); - #elif defined(MCL_ARCHITECTURE_RISCV) - ASSERT_FALSE("Unimplemented"); - #else - # error "Invalid architecture" - #endif struct sigaction* retry_sa = sig == SIGSEGV ? &sig_handler->old_sa_segv : &sig_handler->old_sa_bus; @@ -309,13 +210,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/common/context.h b/src/dynarmic/src/dynarmic/common/context.h new file mode 100644 index 0000000000..e32581eaf5 --- /dev/null +++ b/src/dynarmic/src/dynarmic/common/context.h @@ -0,0 +1,121 @@ +// 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..f9b4ced733 100644 --- a/src/dynarmic/tests/CMakeLists.txt +++ b/src/dynarmic/tests/CMakeLists.txt @@ -133,6 +133,8 @@ 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) -target_compile_options(dynarmic_tests PRIVATE -mavx2) +if (ARCHITECTURE_x86_64) + target_compile_options(dynarmic_tests PRIVATE -mavx2) +endif() add_test(dynarmic_tests dynarmic_tests --durations yes) diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt index d0787b0936..5a21f67bdf 100644 --- a/src/network/CMakeLists.txt +++ b/src/network/CMakeLists.txt @@ -19,7 +19,7 @@ add_library(network STATIC create_target_directory_groups(network) -target_link_libraries(network PRIVATE common enet Boost::headers) +target_link_libraries(network PRIVATE common enet::enet Boost::headers) if (ENABLE_WEB_SERVICE) target_compile_definitions(network PRIVATE -DENABLE_WEB_SERVICE) target_link_libraries(network PRIVATE web_service) diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 0ce8f3b898..94f0651820 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -376,7 +376,7 @@ if (APPLE) if (NOT USE_SYSTEM_MOLTENVK) set(MOLTENVK_PLATFORM "macOS") - set(MOLTENVK_VERSION "v1.3.0") + set(MOLTENVK_VERSION "v1.4.0") download_moltenvk_external(${MOLTENVK_PLATFORM} ${MOLTENVK_VERSION}) endif() find_library(MOLTENVK_LIBRARY MoltenVK REQUIRED)