ARM64EC target defines x86_64 macros to ensure that x86_64-specific code paths are used, but for code that really needs to use aarch64 branch there is an additional _M_ARM64EC macro that needs to be used. See https://techcommunity.microsoft.com/t5/windows-os-platform-blog/getting-to-k... for details.
-- v2: include: Support ARM64EC target in winnt.h. include: Move __getReg intrinsic to intrin.h. include: Support ARM64EC target in intrin.h.
From: Jacek Caban jacek@codeweavers.com
--- include/msvcrt/intrin.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/include/msvcrt/intrin.h b/include/msvcrt/intrin.h index 8b84929bc02..d92f918ce82 100644 --- a/include/msvcrt/intrin.h +++ b/include/msvcrt/intrin.h @@ -7,7 +7,7 @@ #ifndef _INC_INTRIN #define _INC_INTRIN
-#if defined(__i386__) || defined(__x86_64__) +#if defined(__i386__) || (defined(__x86_64__) && !defined(__arm64ec__)) # include <x86intrin.h> #endif
@@ -15,7 +15,7 @@ extern "C" { #endif
-#if defined(__i386__) || defined(__x86_64__) +#if defined(__i386__) || (defined(__x86_64__) && !defined(__arm64ec__)) static inline void __cpuidex(int info[4], int ax, int cx) { __asm__ ("cpuid" : "=a"(info[0]), "=b" (info[1]), "=c"(info[2]), "=d"(info[3]) : "a"(ax), "c"(cx)); @@ -26,7 +26,7 @@ static inline void __cpuid(int info[4], int ax) } #endif
-#ifdef __aarch64__ +#if defined(__aarch64__) || defined(__arm64ec__) typedef enum _tag_ARM64INTR_BARRIER_TYPE { _ARM64_BARRIER_OSHLD = 0x1, @@ -58,7 +58,7 @@ typedef enum _tag_ARMINTR_BARRIER_TYPE } _ARMINTR_BARRIER_TYPE; #endif
-#if defined(_MSC_VER) && (defined(__arm__) || defined(__aarch64__)) +#if defined(_MSC_VER) && (defined(__arm__) || defined(__aarch64__) || defined(__arm64ec__))
void __dmb(unsigned int);
From: Jacek Caban jacek@codeweavers.com
--- include/msvcrt/intrin.h | 7 +++++++ include/winnt.h | 2 -- 2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/include/msvcrt/intrin.h b/include/msvcrt/intrin.h index d92f918ce82..7981e2798ba 100644 --- a/include/msvcrt/intrin.h +++ b/include/msvcrt/intrin.h @@ -66,6 +66,13 @@ void __dmb(unsigned int);
#endif
+#if defined(_MSC_VER) && (defined(__aarch64__) || defined(__arm64ec__)) + +unsigned __int64 __getReg(int); +#pragma intrinsic(__getReg) + +#endif + #ifdef __cplusplus } #endif diff --git a/include/winnt.h b/include/winnt.h index df0c3282f8c..79fa8d6077b 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -2439,8 +2439,6 @@ static FORCEINLINE struct _TEB * WINAPI NtCurrentTeb(void) return __wine_current_teb; } #elif defined(__aarch64__) && defined(_MSC_VER) -unsigned __int64 __getReg(int); -#pragma intrinsic(__getReg) static FORCEINLINE struct _TEB * WINAPI NtCurrentTeb(void) { return (struct _TEB *)__getReg(18);
From: Jacek Caban jacek@codeweavers.com
--- include/winnt.h | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-)
diff --git a/include/winnt.h b/include/winnt.h index 79fa8d6077b..d8690d313ba 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -33,7 +33,7 @@ #endif
-#if defined(_MSC_VER) && (defined(__arm__) || defined(__aarch64__)) +#if defined(_MSC_VER) && (defined(__arm__) || defined(__aarch64__) || defined(__arm64ec__)) #include <intrin.h> #endif
@@ -2405,6 +2405,17 @@ static FORCEINLINE struct _TEB * WINAPI NtCurrentTeb(void) __asm mov teb, eax; return teb; } +#elif (defined(__aarch64__) || defined(__arm64ec__)) && defined(__GNUC__) +register struct _TEB *__wine_current_teb __asm__("x18"); +static FORCEINLINE struct _TEB * WINAPI NtCurrentTeb(void) +{ + return __wine_current_teb; +} +#elif (defined(__aarch64__) || defined(__arm64ec__)) && defined(_MSC_VER) +static FORCEINLINE struct _TEB * WINAPI NtCurrentTeb(void) +{ + return (struct _TEB *)__getReg(18); +} #elif defined(__x86_64__) && defined(__GNUC__) static FORCEINLINE struct _TEB * WINAPI NtCurrentTeb(void) { @@ -2432,17 +2443,6 @@ static FORCEINLINE struct _TEB * WINAPI NtCurrentTeb(void) { return (struct _TEB *)(ULONG_PTR)_MoveFromCoprocessor(15, 0, 13, 0, 2); } -#elif defined(__aarch64__) && defined(__GNUC__) -register struct _TEB *__wine_current_teb __asm__("x18"); -static FORCEINLINE struct _TEB * WINAPI NtCurrentTeb(void) -{ - return __wine_current_teb; -} -#elif defined(__aarch64__) && defined(_MSC_VER) -static FORCEINLINE struct _TEB * WINAPI NtCurrentTeb(void) -{ - return (struct _TEB *)__getReg(18); -} #elif !defined(RC_INVOKED) # error You must define NtCurrentTeb() for your architecture #endif @@ -6902,6 +6902,13 @@ static FORCEINLINE void MemoryBarrier(void) InterlockedOr(&dummy, 0); }
+#elif defined(__aarch64__) || defined(__arm64ec__) + +static FORCEINLINE void MemoryBarrier(void) +{ + __dmb(_ARM64_BARRIER_SY); +} + #elif defined(__x86_64__)
#pragma intrinsic(__faststorefence) @@ -6919,13 +6926,6 @@ static FORCEINLINE void MemoryBarrier(void) __dmb(_ARM_BARRIER_SY); }
-#elif defined(__aarch64__) - -static FORCEINLINE void MemoryBarrier(void) -{ - __dmb(_ARM64_BARRIER_SY); -} - #endif /* __i386__ */
/* Since Visual Studio 2012, volatile accesses do not always imply acquire and @@ -7191,7 +7191,7 @@ unsigned char _InterlockedCompareExchange128(volatile __int64 *, __int64, __int6
static FORCEINLINE unsigned char InterlockedCompareExchange128( volatile __int64 *dest, __int64 xchg_high, __int64 xchg_low, __int64 *compare ) { -#ifdef __x86_64__ +#if defined(__x86_64__) && !defined(__arm64ec__) unsigned char ret; __asm__ __volatile__( "lock cmpxchg16b %0; setz %b2" : "=m" (dest[0]), "=m" (dest[1]), "=r" (ret),