From a921078483b385b8da979ad581fc568f5e6b14d8 Mon Sep 17 00:00:00 2001 From: amaldika Date: Fri, 13 Mar 2026 14:46:17 +0530 Subject: [PATCH] Changes to support arm64 & arm64EC [+] Enabled platform specific macros & implementation wherever necessary. [+] Changes to obey "EA_TARGET_ARCHITECTURE_ARM64" & "EA_TARGET_ARCHITECTURE_ARM64EC" for arm64 & arm64EC respectively. --- include/eathread/eathread_mutex.h | 2 +- source/arm/eathread_callstack_arm.cpp | 50 +++++++++++++++++++++------ source/pc/eathread_pc.cpp | 4 +-- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/include/eathread/eathread_mutex.h b/include/eathread/eathread_mutex.h index 328c814..69930e7 100644 --- a/include/eathread/eathread_mutex.h +++ b/include/eathread/eathread_mutex.h @@ -108,7 +108,7 @@ #elif defined(EA_PLATFORM_MICROSOFT) && !EA_POSIX_THREADS_AVAILABLE - #ifdef EA_PROCESSOR_X86_64 + #if defined(EA_PROCESSOR_X86_64) || defined(EA_PROCESSOR_ARM64) static const int MUTEX_PLATFORM_DATA_SIZE = 40; // CRITICAL_SECTION is 40 bytes on Win64. #else static const int MUTEX_PLATFORM_DATA_SIZE = 32; // CRITICAL_SECTION is 24 bytes on Win32, 28 bytes on XBox 360. diff --git a/source/arm/eathread_callstack_arm.cpp b/source/arm/eathread_callstack_arm.cpp index 530264f..9ed1c51 100644 --- a/source/arm/eathread_callstack_arm.cpp +++ b/source/arm/eathread_callstack_arm.cpp @@ -44,7 +44,15 @@ namespace Thread RtlCaptureContext(&context); // Possibly use the __emit intrinsic. http://msdn.microsoft.com/en-us/library/ms933778.aspx - pInstruction = (void*)(uintptr_t)context.___; // To do. + #if defined(EA_PROCESSOR_ARM64) + #if defined(EA_TARGET_ARCHITECTURE_ARM64) + pInstruction = (void*)context.Pc; + #else //EA_TARGET_ARCHITECTURE_ARM64EC + pInstruction = (void*)context.Rip; + #endif + #else + pInstruction = (void*)(uintptr_t)context.___; // To do. + #endif } #elif defined(EA_COMPILER_GNUC) || defined(EA_COMPILER_CLANG) EATHREADLIB_API void GetInstructionPointer(void*& pInstruction) @@ -189,15 +197,37 @@ EATHREADLIB_API void ShutdownCallstack() context.mPC = (uintptr_t)p; #elif defined(EA_PLATFORM_WINDOWS) && EA_WINAPI_FAMILY_PARTITION(EA_WINAPI_PARTITION_DESKTOP) - // Possibly use the __emit intrinsic. Do this by making a __declspec(naked) function that - // does nothing but return r14 (move r14 to r0). Need to know the opcode for that. - // http://msdn.microsoft.com/en-us/library/ms933778.aspx - #error Need to complete this somehow. - context.mFP = 0; - context.mLR = 0; - context.mSP = 0; - GetInstructionPointer(p); // Intentionally don't call EAGetInstructionPointer, because it won't set the Thumb bit it this is Thumb code. - context.mPC = (uintptr_t)p; + #if defined(EA_PROCESSOR_ARM64) + CONTEXT context_ = {}; + RtlCaptureContext(&context_); + + #if defined(EA_TARGET_ARCHITECTURE_ARM64) + context.mFP = context_.Fp; + context.mLR = context_.Lr; + context.mSP = context_.Sp; + GetInstructionPointer(p); // Intentionally don't call EAGetInstructionPointer, because it won't set the + // Thumb bit it this is Thumb code. + context.mPC = (uintptr_t)p; + #elif defined(EA_TARGET_ARCHITECTURE_ARM64EC) + context.mFP = context_.Rbp; + context.mLR = (uint64_t)_ReturnAddress(); // In MSVC (Microsoft Visual C++), the equivalent to GCC's __builtin_return_address is the _ReturnAddress() intrinsic. + context.mSP = context_.Rsp; + GetInstructionPointer(p); // Intentionally don't call EAGetInstructionPointer, because it won't set the + // Thumb bit it this is Thumb code. + context.mPC = (uintptr_t)p; + #endif + #else + // Possibly use the __emit intrinsic. Do this by making a __declspec(naked) function that + // does nothing but return r14 (move r14 to r0). Need to know the opcode for that. + // http://msdn.microsoft.com/en-us/library/ms933778.aspx + #error Need to complete this somehow. + context.mFP = 0; + context.mLR = 0; + context.mSP = 0; + GetInstructionPointer(p); // Intentionally don't call EAGetInstructionPointer, because it won't set the + // Thumb bit it this is Thumb code. + context.mPC = (uintptr_t)p; + #endif #endif } diff --git a/source/pc/eathread_pc.cpp b/source/pc/eathread_pc.cpp index a543cbf..995e708 100644 --- a/source/pc/eathread_pc.cpp +++ b/source/pc/eathread_pc.cpp @@ -326,7 +326,7 @@ EATHREADLIB_API EA::Thread::ThreadId EA::Thread::GetThreadId(EA::Thread::SysThre EATHREADLIB_API EA::Thread::SysThreadId EA::Thread::GetSysThreadId(ThreadId id) { - #if defined(EA_PLATFORM_MICROSOFT) && defined(EA_PROCESSOR_X86_64) + #if defined(EA_PLATFORM_MICROSOFT) && (defined(EA_PROCESSOR_X86_64) || defined(EA_PROCESSOR_ARM64)) // Win64 has this function natively. return ::GetThreadId(id); @@ -485,7 +485,7 @@ void* EA::Thread::GetThreadStackBase() return (void*)pTib->StackBase; - #elif defined(EA_PLATFORM_MICROSOFT) && defined(EA_PROCESSOR_X86_64) && defined(EA_COMPILER_MSVC) + #elif defined(EA_PLATFORM_MICROSOFT) && (defined(EA_PROCESSOR_X86_64) || defined(EA_PROCESSOR_ARM64)) && defined(EA_COMPILER_MSVC) // VC++ also offers the __readgsdword() intrinsic, which is an alternative which could // retrieve the current thread TEB if the following proves unreliable. PNT_TIB64 pTib = reinterpret_cast(NtCurrentTeb());