diff --git a/CMakeLists.txt b/CMakeLists.txt index 5c91750da..93d6d7a54 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -363,9 +363,9 @@ set(KERNEL_LIB src/core/libraries/kernel/coredump/coredump.cpp src/core/libraries/kernel/aio.h ) -if (ARCHITECTURE STREQUAL "x86_64") +if (ARCHITECTURE STREQUAL "x86_64" OR ARCHITECTURE STREQUAL "arm64") list(APPEND KERNEL_LIB src/core/libraries/kernel/threads/stack.S) - set_source_files_properties(src/core/libraries/kernel/threads/stack.s PROPERTIES COMPILE_OPTIONS -Wno-unused-command-line-argument) + set_source_files_properties(src/core/libraries/kernel/threads/stack.S PROPERTIES COMPILE_OPTIONS -Wno-unused-command-line-argument) endif() set(NETWORK_LIBS src/core/libraries/network/http.cpp diff --git a/src/core/libraries/kernel/threads/pthread.cpp b/src/core/libraries/kernel/threads/pthread.cpp index ec52a3edc..2dc1b72cf 100644 --- a/src/core/libraries/kernel/threads/pthread.cpp +++ b/src/core/libraries/kernel/threads/pthread.cpp @@ -12,7 +12,7 @@ #include "core/libraries/libs.h" #include "core/memory.h" -#ifdef ARCH_X86_64 +#if defined(ARCH_X86_64) || defined(__arm64__) || defined(__aarch64__) extern "C" void* PS4_SYSV_ABI _runOnAnotherStack(void* arg, void* func, void* stackb) asm("_runOnAnotherStack"); #else diff --git a/src/core/libraries/kernel/threads/stack.S b/src/core/libraries/kernel/threads/stack.S index 53842167b..e75895ea0 100644 --- a/src/core/libraries/kernel/threads/stack.S +++ b/src/core/libraries/kernel/threads/stack.S @@ -1,6 +1,8 @@ # SPDX-FileCopyrightText: Copyright 2026 shadPS4 Emulator Project # SPDX-License-Identifier: GPL-2.0-or-later +#if defined(__x86_64__) + .global _runOnAnotherStack _runOnAnotherStack: pushq %r12 @@ -35,3 +37,41 @@ _runOnAnotherStack: popq %r13 popq %r12 ret + +#elif defined(__arm64__) || defined(__aarch64__) + +.global _runOnAnotherStack +_runOnAnotherStack: + // Save frame pointer (x29), link register (x30), and callee-saved registers x19, x20 + stp x29, x30, [sp, #-32]! + mov x29, sp + stp x19, x20, [sp, #16] + + // Save the current stack pointer into x19 (callee-saved) + mov x19, sp + // Save the current frame pointer into x20 (callee-saved) + mov x20, x29 + + // Align the target stack pointer (x2) to 16 bytes (ARM64 constraint) + and x2, x2, #-16 + + // Switch stack pointer to the new stack (x2) + mov sp, x2 + // Switch frame pointer to the new stack (x2) + mov x29, x2 + + // Call the function (target address is in x1) + // Note: the argument is already in x0! + blr x1 + + // Restore the old stack pointer and frame pointer + mov sp, x19 + mov x29, x20 + + // Restore saved registers and return + ldp x19, x20, [sp, #16] + ldp x29, x30, [sp], #32 + ret + +#endif +