build: Get compiling on ARM64 again (#4598)

This commit is contained in:
squidbus 2026-06-19 08:21:38 -07:00 committed by GitHub
parent ad95aac357
commit dcd036d261
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 151 additions and 99 deletions

View File

@ -337,7 +337,6 @@ set(KERNEL_LIB src/core/libraries/kernel/coredump/coredump.cpp
src/core/libraries/kernel/threads/sleepq.cpp
src/core/libraries/kernel/threads/sleepq.h
src/core/libraries/kernel/threads/stack.cpp
src/core/libraries/kernel/threads/stack.S
src/core/libraries/kernel/threads/tcb.cpp
src/core/libraries/kernel/threads/pthread.h
src/core/libraries/kernel/threads/thread_state.cpp
@ -364,7 +363,10 @@ set(KERNEL_LIB src/core/libraries/kernel/coredump/coredump.cpp
src/core/libraries/kernel/aio.h
)
set_source_files_properties(src/core/libraries/kernel/threads/stack.s PROPERTIES COMPILE_OPTIONS -Wno-unused-command-line-argument)
if (ARCHITECTURE STREQUAL "x86_64")
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)
endif()
set(NETWORK_LIBS src/core/libraries/network/http.cpp
src/core/libraries/network/http.h
@ -888,7 +890,6 @@ set(CORE src/core/aerolib/stubs.cpp
${ZLIB_LIB}
${MISC_LIBS}
${IME_LIB}
${FIBER_LIB}
${VDEC_LIB}
${VR_LIBS}
${CAMERA_LIBS}
@ -924,7 +925,8 @@ set(CORE src/core/aerolib/stubs.cpp
if (ARCHITECTURE STREQUAL "x86_64")
set(CORE ${CORE}
src/core/cpu_patches.cpp
src/core/cpu_patches.h)
src/core/cpu_patches.h
${FIBER_LIB})
endif()
set(SHADER_RECOMPILER src/shader_recompiler/profile.h

View File

@ -2,7 +2,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/arch.h"
#include "common/assert.h"
#include "common/signal_context.h"
#ifdef _WIN32
@ -16,76 +15,19 @@
namespace Common {
void* GetXmmPointer(void* ctx, u8 index) {
#if defined(_WIN32)
#define CASE(index) \
case index: \
return (void*)(&((EXCEPTION_POINTERS*)ctx)->ContextRecord->Xmm##index.Low)
#elif defined(__APPLE__)
#define CASE(index) \
case index: \
return (void*)(&((ucontext_t*)ctx)->uc_mcontext->__fs.__fpu_xmm##index);
#elif defined(__FreeBSD__)
// In mc_fpstate
// See <machine/npx.h> for the internals of mc_fpstate[].
#define CASE(index) \
case index: { \
auto& mctx = ((ucontext_t*)ctx)->uc_mcontext; \
ASSERT(mctx.mc_fpformat == _MC_FPFMT_XMM); \
auto* s_fpu = (struct savefpu*)(&mctx.mc_fpstate[0]); \
return (void*)(&(s_fpu->sv_xmm[0])); \
}
#else
#define CASE(index) \
case index: \
return (void*)(&((ucontext_t*)ctx)->uc_mcontext.fpregs->_xmm[index].element[0])
#endif
switch (index) {
CASE(0);
CASE(1);
CASE(2);
CASE(3);
CASE(4);
CASE(5);
CASE(6);
CASE(7);
CASE(8);
CASE(9);
CASE(10);
CASE(11);
CASE(12);
CASE(13);
CASE(14);
CASE(15);
default: {
UNREACHABLE_MSG("Invalid XMM register index: {}", index);
return nullptr;
}
}
#undef CASE
}
void* GetRip(void* ctx) {
#if defined(_WIN32)
return (void*)((EXCEPTION_POINTERS*)ctx)->ContextRecord->Rip;
#elif defined(__APPLE__)
#elif defined(__APPLE__) && defined(ARCH_X86_64)
return (void*)((ucontext_t*)ctx)->uc_mcontext->__ss.__rip;
#elif defined(__APPLE__) && defined(ARCH_ARM64)
return (void*)((ucontext_t*)ctx)->uc_mcontext->__ss.__pc;
#elif defined(__FreeBSD__)
return (void*)((ucontext_t*)ctx)->uc_mcontext.mc_rip;
#else
#elif defined(ARCH_X86_64)
return (void*)((ucontext_t*)ctx)->uc_mcontext.gregs[REG_RIP];
#endif
}
void IncrementRip(void* ctx, u64 length) {
#if defined(_WIN32)
((EXCEPTION_POINTERS*)ctx)->ContextRecord->Rip += length;
#elif defined(__APPLE__)
((ucontext_t*)ctx)->uc_mcontext->__ss.__rip += length;
#elif defined(__FreeBSD__)
((ucontext_t*)ctx)->uc_mcontext.mc_rip += length;
#else
((ucontext_t*)ctx)->uc_mcontext.gregs[REG_RIP] += length;
#error "Unsupported architecture"
#endif
}
@ -104,4 +46,5 @@ bool IsWriteError(void* ctx) {
#error "Unsupported architecture"
#endif
}
} // namespace Common

View File

@ -2,9 +2,16 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <xmmintrin.h>
#include "common/arch.h"
#include "common/types.h"
#ifdef ARCH_X86_64
#include <xmmintrin.h>
#else
// FIXME
typedef __int128 __m128;
#endif
#define VA_ARGS \
uint64_t rdi, uint64_t rsi, uint64_t rdx, uint64_t rcx, uint64_t r8, uint64_t r9, \
uint64_t overflow_arg_area, __m128 xmm0, __m128 xmm1, __m128 xmm2, __m128 xmm3, \

View File

@ -22,7 +22,11 @@
#ifdef _WIN32
#include <windows.h>
#else
#if defined(__FreeBSD__)
#include <machine/npx.h>
#endif
#include <pthread.h>
#include <sys/ucontext.h>
#endif
using namespace Xbyak::util;
@ -590,8 +594,6 @@ static std::pair<bool, u64> TryPatch(u8* code, PatchModule* module) {
return std::make_pair(false, instruction.length);
}
#if defined(ARCH_X86_64)
static bool Is4ByteExtrqOrInsertq(void* code_address) {
u8* bytes = (u8*)code_address;
if (bytes[0] == 0x66 && bytes[1] == 0x0F && bytes[2] == 0x79) {
@ -603,6 +605,67 @@ static bool Is4ByteExtrqOrInsertq(void* code_address) {
}
}
static void* GetXmmPointer(void* ctx, u8 index) {
#if defined(_WIN32)
#define CASE(index) \
case index: \
return (void*)(&((EXCEPTION_POINTERS*)ctx)->ContextRecord->Xmm##index.Low)
#elif defined(__APPLE__)
#define CASE(index) \
case index: \
return (void*)(&((ucontext_t*)ctx)->uc_mcontext->__fs.__fpu_xmm##index);
#elif defined(__FreeBSD__)
// In mc_fpstate
// See <machine/npx.h> for the internals of mc_fpstate[].
#define CASE(index) \
case index: { \
auto& mctx = ((ucontext_t*)ctx)->uc_mcontext; \
ASSERT(mctx.mc_fpformat == _MC_FPFMT_XMM); \
auto* s_fpu = (struct savefpu*)(&mctx.mc_fpstate[0]); \
return (void*)(&(s_fpu->sv_xmm[0])); \
}
#else
#define CASE(index) \
case index: \
return (void*)(&((ucontext_t*)ctx)->uc_mcontext.fpregs->_xmm[index].element[0])
#endif
switch (index) {
CASE(0);
CASE(1);
CASE(2);
CASE(3);
CASE(4);
CASE(5);
CASE(6);
CASE(7);
CASE(8);
CASE(9);
CASE(10);
CASE(11);
CASE(12);
CASE(13);
CASE(14);
CASE(15);
default: {
UNREACHABLE_MSG("Invalid XMM register index: {}", index);
return nullptr;
}
}
#undef CASE
}
static void IncrementRip(void* ctx, u64 length) {
#if defined(_WIN32)
((EXCEPTION_POINTERS*)ctx)->ContextRecord->Rip += length;
#elif defined(__APPLE__)
((ucontext_t*)ctx)->uc_mcontext->__ss.__rip += length;
#elif defined(__FreeBSD__)
((ucontext_t*)ctx)->uc_mcontext.mc_rip += length;
#else
((ucontext_t*)ctx)->uc_mcontext.gregs[REG_RIP] += length;
#endif
}
static bool TryExecuteIllegalInstruction(void* ctx, void* code_address) {
// We need to decode the instruction to find out what it is. Normally we'd use a fully fleshed
// out decoder like Zydis, however Zydis does a bunch of stuff that impact performance that we
@ -644,8 +707,8 @@ static bool TryExecuteIllegalInstruction(void* ctx, void* code_address) {
switch (mnemonic) {
case ZYDIS_MNEMONIC_EXTRQ: {
const auto dst = Common::GetXmmPointer(ctx, dstIndex);
const auto src = Common::GetXmmPointer(ctx, srcIndex);
const auto dst = GetXmmPointer(ctx, dstIndex);
const auto src = GetXmmPointer(ctx, srcIndex);
u64 lowQWordSrc;
memcpy(&lowQWordSrc, src, sizeof(lowQWordSrc));
@ -678,13 +741,13 @@ static bool TryExecuteIllegalInstruction(void* ctx, void* code_address) {
memset((u8*)dst + sizeof(u64), 0, sizeof(u64));
memcpy(dst, &lowQWordDst, sizeof(lowQWordDst));
Common::IncrementRip(ctx, 4);
IncrementRip(ctx, 4);
return true;
}
case ZYDIS_MNEMONIC_INSERTQ: {
const auto dst = Common::GetXmmPointer(ctx, dstIndex);
const auto src = Common::GetXmmPointer(ctx, srcIndex);
const auto dst = GetXmmPointer(ctx, dstIndex);
const auto src = GetXmmPointer(ctx, srcIndex);
u64 lowQWordSrc, highQWordSrc;
memcpy(&lowQWordSrc, src, sizeof(lowQWordSrc));
@ -719,7 +782,7 @@ static bool TryExecuteIllegalInstruction(void* ctx, void* code_address) {
memset((u8*)dst + sizeof(u64), 0, sizeof(u64));
memcpy(dst, &lowQWordDst, sizeof(lowQWordDst));
Common::IncrementRip(ctx, 4);
IncrementRip(ctx, 4);
return true;
}
@ -730,15 +793,6 @@ static bool TryExecuteIllegalInstruction(void* ctx, void* code_address) {
UNREACHABLE();
}
#elif defined(ARCH_ARM64)
// These functions shouldn't be needed for ARM as it will use a JIT so there's no need to patch
// instructions.
static bool TryExecuteIllegalInstruction(void*, void*) {
return false;
}
#else
#error "Unsupported architecture"
#endif
static bool TryPatchJit(void* code_address) {
auto* code = static_cast<u8*>(code_address);

View File

@ -4,9 +4,12 @@
#pragma once
#include "common/types.h"
#include "common/va_ctx.h"
#include "core/libraries/kernel/orbis_error.h"
namespace Common {
struct VaCtx;
}
namespace Libraries::Kernel {
struct OrbisKernelStat;
struct OrbisKernelIovec;

View File

@ -1,9 +1,8 @@
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <cstdlib>
#include <ctime>
#include "common/logging/log.h"
#include "common/va_ctx.h"
#include "core/file_sys/devices/rng_device.h"
namespace Core::Devices {

View File

@ -3,10 +3,8 @@
#pragma once
#include <string_view>
#include <vector>
#include "common/types.h"
#include "common/va_ctx.h"
#include "core/libraries/kernel/file_system.h"
#include "core/libraries/kernel/orbis_error.h"

View File

@ -711,7 +711,7 @@ private:
d[i] = OrbisFloatToS16(s[i]);
}
}
#elif
#else
static void ConvertF32ToS16Stereo(const void* src, void* dst, u32 frames, const float*) {
const float* s = static_cast<const float*>(src);
s16* d = static_cast<s16*>(dst);
@ -755,7 +755,7 @@ private:
d[i] = OrbisFloatToS16(s[i]);
}
}
#elif
#else
static void ConvertF32ToS16_8CH(const void* src, void* dst, u32 frames, const float*) {
const float* s = static_cast<const float*>(src);
s16* d = static_cast<s16*>(dst);

View File

@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/arch.h"
#include "common/assert.h"
#include "core/libraries/kernel/kernel.h"
#include "core/libraries/kernel/orbis_error.h"
@ -194,6 +195,7 @@ void SigactionHandler(int native_signum, siginfo_t* inf, ucontext_t* raw_context
const auto handler = Handlers[NativeToOrbisSignal(native_signum)];
if (handler) {
auto ctx = Ucontext{};
#ifdef ARCH_X86_64
#ifdef __APPLE__
const auto& regs = raw_context->uc_mcontext->__ss;
ctx.uc_mcontext.mc_r8 = regs.__r8;
@ -260,6 +262,9 @@ void SigactionHandler(int native_signum, siginfo_t* inf, ucontext_t* raw_context
ctx.uc_mcontext.mc_gs = (regs[REG_CSGSFS] >> 16) & 0xFFFF;
ctx.uc_mcontext.mc_rip = (regs[REG_RIP]);
ctx.uc_mcontext.mc_addr = reinterpret_cast<uint64_t>(inf->si_addr);
#endif
#else
UNREACHABLE_MSG("SigactionHandler not implemented for current architecture.");
#endif
handler(NativeToOrbisSignal(native_signum), &ctx);
} else {

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <thread>
#include "common/arch.h"
#include "common/assert.h"
#include "common/types.h"
#include "core/libraries/kernel/kernel.h"
@ -18,7 +19,11 @@ static std::mutex MutxStaticLock;
#define THR_ADAPTIVE_MUTEX_INITIALIZER ((PthreadMutex*)1)
#define THR_MUTEX_DESTROYED ((PthreadMutex*)2)
#if defined(ARCH_X86_64)
#define CPU_SPINWAIT __asm__ volatile("pause")
#elif defined(ARCH_ARM64)
#define CPU_SPINWAIT __asm__ volatile("yield")
#endif
#define CHECK_AND_INIT_MUTEX \
if (PthreadMutex* m = *mutex; m <= THR_MUTEX_DESTROYED) [[unlikely]] { \

View File

@ -12,8 +12,14 @@
#include "core/libraries/libs.h"
#include "core/memory.h"
#ifdef ARCH_X86_64
extern "C" void* PS4_SYSV_ABI _runOnAnotherStack(void* arg, void* func,
void* stackb) asm("_runOnAnotherStack");
#else
void* PS4_SYSV_ABI _runOnAnotherStack(void* arg, void* func, void* stackb) {
UNREACHABLE_MSG("_runOnAnotherStack not implemented on target architecture.");
}
#endif
namespace Libraries::Kernel {

View File

@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2024-2026 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/arch.h"
#include "core/libraries/ajm/ajm.h"
#include "core/libraries/app_content/app_content.h"
#include "core/libraries/audio/audioin.h"
@ -13,6 +14,7 @@
#include "core/libraries/companion/companion_util.h"
#include "core/libraries/content_export/content_export.h"
#include "core/libraries/disc_map/disc_map.h"
#include "core/libraries/fiber/fiber.h"
#include "core/libraries/game_live_streaming/gamelivestreaming.h"
#include "core/libraries/gnmdriver/gnmdriver.h"
#include "core/libraries/hmd/hmd.h"
@ -75,7 +77,6 @@
#include "core/libraries/vr_tracker/vr_tracker.h"
#include "core/libraries/web_browser_dialog/webbrowserdialog.h"
#include "core/libraries/zlib/zlib_sce.h"
#include "fiber/fiber.h"
namespace Libraries {
@ -140,7 +141,9 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
Libraries::Remoteplay::RegisterLib(sym);
Libraries::RazorCpu::RegisterLib(sym);
Libraries::Move::RegisterLib(sym);
#ifdef ARCH_X86_64
Libraries::Fiber::RegisterLib(sym);
#endif
Libraries::Mouse::RegisterLib(sym);
Libraries::WebBrowserDialog::RegisterLib(sym);
Libraries::Zlib::RegisterLib(sym);

View File

@ -33,8 +33,8 @@ static PS4_SYSV_ABI void ProgramExitFunc() {
LOG_ERROR(Core_Linker, "Exit function called");
}
#ifdef ARCH_X86_64
static PS4_SYSV_ABI void* RunMainEntry [[noreturn]] (EntryParams* params) {
#ifdef ARCH_X86_64
// Start shared library modules
asm volatile("andq $-16, %%rsp\n" // Align to 16 bytes
"subq $8, %%rsp\n" // videoout_basic expects the stack to be misaligned
@ -54,8 +54,10 @@ static PS4_SYSV_ABI void* RunMainEntry [[noreturn]] (EntryParams* params) {
: "r"(params->entry_addr), "r"(params), "r"(ProgramExitFunc)
: "rax", "rsi", "rdi");
UNREACHABLE();
}
#else
UNREACHABLE_MSG("RunMainEntry unimplemented for current architecture.");
#endif
}
Linker::Linker() : memory{Memory::Instance()} {}

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/alignment.h"
#include "common/arch.h"
#include "core/libraries/kernel/threads/pthread.h"
#include "thread.h"
#ifdef _WIN64
@ -11,8 +12,10 @@
#include <csignal>
#include <pthread.h>
#include <unistd.h>
#ifdef ARCH_X86_64
#include <xmmintrin.h>
#endif
#endif
namespace Core {
@ -62,9 +65,11 @@ void NativeThread::Exit() {
}
void NativeThread::Initialize() {
#ifdef ARCH_X86_64
// Set MXCSR and FPUCW registers to the values used by Orbis.
_mm_setcsr(ORBIS_MXCSR);
asm volatile("fldcw %0" : : "m"(ORBIS_FPUCW));
#endif
#if _WIN64
tid = GetCurrentThreadId();
#else

View File

@ -5,6 +5,8 @@
#include <boost/container/flat_map.hpp>
#include <xbyak/xbyak.h>
#include <xbyak/xbyak_util.h>
#include "common/arch.h"
#include "common/decoder.h"
#include "common/io_file.h"
#include "common/logging/log.h"
#include "common/path_util.h"
@ -19,8 +21,8 @@
#include "shader_recompiler/ir/reg.h"
#include "shader_recompiler/ir/srt_gvn_table.h"
#include "shader_recompiler/ir/value.h"
#include "src/common/arch.h"
#include "src/common/decoder.h"
#ifdef ARCH_X86_64
using namespace Xbyak::util;
@ -41,7 +43,6 @@ PFN_SrtWalker RegisterWalkerCode(const u8* ptr, size_t size) {
namespace {
static void DumpSrtProgram(const Shader::Info& info, const u8* code, size_t codesize) {
#ifdef ARCH_X86_64
using namespace Common::FS;
const auto dump_dir = GetUserPath(PathType::ShaderDir) / "dumps";
@ -64,7 +65,6 @@ static void DumpSrtProgram(const Shader::Info& info, const u8* code, size_t code
file.WriteString(s);
address += instruction.length;
}
#endif
}
static bool SrtWalkerSignalHandler(void* context, void* fault_address) {
@ -305,3 +305,23 @@ void FlattenExtendedUserdataPass(IR::Program& program) {
}
} // namespace Shader::Optimization
#else
namespace Shader {
PFN_SrtWalker RegisterWalkerCode(const u8* ptr, size_t size) {
UNREACHABLE_MSG("RegisterWalkerCode unimplemented for target architecture.");
}
namespace Optimization {
void FlattenExtendedUserdataPass(IR::Program& program) {
UNREACHABLE_MSG("FlattenExtendedUserdataPass unimplemented for target architecture.");
}
} // namespace Optimization
} // namespace Shader
#endif