Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

revisit MSVC platform checks for ARM64EC ? #8759

Open
sezero opened this issue Dec 29, 2023 · 2 comments
Open

revisit MSVC platform checks for ARM64EC ? #8759

sezero opened this issue Dec 29, 2023 · 2 comments
Milestone

Comments

@sezero
Copy link
Contributor

sezero commented Dec 29, 2023

@sezero
Copy link
Contributor Author

sezero commented Dec 31, 2023

After a quick'n'dirty search for _M_X64, _M_AMD64 and _M_ARM64, I
generated the draft below. Not even compile-tested, may be wrong
and/or incomplete: Someone with access to proper hardware+compiler
should check && test things. A CI workflow may help too.

In addition, CheckCPUArchitecture.cmake and cmake'ry may need some
similar surgery.

Hope these help.

diff --git a/include/SDL3/SDL_atomic.h b/include/SDL3/SDL_atomic.h
index ece4ac5..512844b 100644
--- a/include/SDL3/SDL_atomic.h
+++ b/include/SDL3/SDL_atomic.h
@@ -250,9 +250,9 @@ typedef void (*SDL_KernelMemoryBarrierFunc)();
     #define SDL_CPUPauseInstruction() __asm__ __volatile__("or 27,27,27");
 #elif (defined(__riscv) && __riscv_xlen == 64)
     #define SDL_CPUPauseInstruction() __asm__ __volatile__(".insn i 0x0F, 0, x0, x0, 0x010");
-#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
+#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64) && !defined(_M_ARM64EC))
     #define SDL_CPUPauseInstruction() _mm_pause()  /* this is actually "rep nop" and not a SIMD instruction. No inline asm in MSVC x86-64! */
-#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
+#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC))
     #define SDL_CPUPauseInstruction() __yield()
 #elif defined(__WATCOMC__) && defined(__386__)
     extern __inline void SDL_CPUPauseInstruction(void);
diff --git a/include/SDL3/SDL_intrin.h b/include/SDL3/SDL_intrin.h
index 5d276d6..2f1e339 100644
--- a/include/SDL3/SDL_intrin.h
+++ b/include/SDL3/SDL_intrin.h
@@ -32,7 +32,7 @@
 
 /* Need to do this here because intrin.h has C++ code in it */
 /* Visual Studio 2005 has a bug where intrin.h conflicts with winnt.h */
-#if defined(_MSC_VER) && (_MSC_VER >= 1500) && (defined(_M_IX86) || defined(_M_X64))
+#if defined(_MSC_VER) && (_MSC_VER >= 1500) && (defined(_M_IX86) || defined(_M_X64) && !defined(_M_ARM64EC))
 #ifdef __clang__
 /* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version,
    so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */
@@ -72,7 +72,7 @@ _m_prefetch(void *__P)
 #      include <arm_neon.h>
 #      define __ARM_NEON 1 /* Set __ARM_NEON so that it can be used elsewhere, at compile time */
 #    endif
-#    if defined (_M_ARM64)
+#    if defined (_M_ARM64) || defined(_M_ARM64EC)
 #      define SDL_NEON_INTRINSICS 1
 #      include <arm64intr.h>
 #      include <arm64_neon.h>
@@ -110,7 +110,7 @@ _m_prefetch(void *__P)
 # endif
 #endif
 
-#if defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86)
+#if defined(__x86_64__) || (defined(_M_X64) && !defined(_M_ARM64EC)) || defined(__i386__) || defined(_M_IX86)
 # if ((defined(_MSC_VER) && !defined(_M_X64)) || defined(__MMX__) || defined(SDL_HAS_TARGET_ATTRIBS)) && !defined(SDL_DISABLE_MMX)
 #  define SDL_MMX_INTRINSICS 1
 #  include <mmintrin.h>
@@ -156,6 +156,6 @@ _m_prefetch(void *__P)
 #  define SDL_AVX512F_INTRINSICS 1
 #  include <immintrin.h>
 # endif
-#endif /* defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86) */
+#endif /* defined(__x86_64__) || (defined(_M_X64) && !defined(_M_ARM64EC)) || defined(__i386__) || defined(_M_IX86) */
 
 #endif /* SDL_intrin_h_ */
diff --git a/src/atomic/SDL_spinlock.c b/src/atomic/SDL_spinlock.c
index 25615ac..4d48464 100644
--- a/src/atomic/SDL_spinlock.c
+++ b/src/atomic/SDL_spinlock.c
@@ -32,7 +32,7 @@
 #include <unixlib/local.h>
 #endif
 
-#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64))
+#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) && !defined(_M_ARM64EC)
 #include <xmmintrin.h>
 #endif
 
@@ -80,7 +80,7 @@ SDL_bool SDL_AtomicTryLock(SDL_SpinLock *lock)
 #elif defined(HAVE_GCC_ATOMICS) || defined(HAVE_GCC_SYNC_LOCK_TEST_AND_SET)
     return __sync_lock_test_and_set(lock, 1) == 0;
 
-#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
+#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC))
     return _InterlockedExchange_acq(lock, 1) == 0;
 
 #elif defined(_MSC_VER)
@@ -185,7 +185,7 @@ void SDL_AtomicUnlock(SDL_SpinLock *lock)
 #if defined(HAVE_GCC_ATOMICS) || defined(HAVE_GCC_SYNC_LOCK_TEST_AND_SET)
     __sync_lock_release(lock);
 
-#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64))
+#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC))
     _InterlockedExchange_rel(lock, 0);
 
 #elif defined(_MSC_VER)
diff --git a/src/cpuinfo/SDL_cpuinfo.c b/src/cpuinfo/SDL_cpuinfo.c
index bed2a35..ce75697 100644
--- a/src/cpuinfo/SDL_cpuinfo.c
+++ b/src/cpuinfo/SDL_cpuinfo.c
@@ -176,7 +176,7 @@ static int CPU_haveCPUID(void)
         mov     has_CPUID,1         ; We have CPUID support
 done:
     }
-#elif defined(_MSC_VER) && defined(_M_X64)
+#elif defined(_MSC_VER) && defined(_M_X64) && !defined(_M_ARM64EC)
     has_CPUID = 1;
 #elif defined(__sun) && defined(__i386)
     __asm (
@@ -245,7 +245,7 @@ done:
         __asm mov c, ecx \
         __asm mov d, edx                   \
     }
-#elif (defined(_MSC_VER) && defined(_M_X64))
+#elif (defined(_MSC_VER) && defined(_M_X64) && !defined(_M_ARM64EC))
 /* Use __cpuidex instead of __cpuid because ICL does not clear ecx register */
 #define cpuid(func, a, b, c, d)      \
     {                                \
@@ -296,7 +296,7 @@ static void CPU_calcCPUIDFeatures(void)
                             : "=a"(a)
                             : "c"(0)
                             : "%edx");
-#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) && (_MSC_FULL_VER >= 160040219) /* VS2010 SP1 */
+#elif defined(_MSC_VER) && !defined(_M_ARM64EC) && (defined(_M_IX86) || defined(_M_X64)) && (_MSC_FULL_VER >= 160040219) /* VS2010 SP1 */
                     a = (int)_xgetbv(0);
 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
                     __asm
@@ -441,7 +441,7 @@ static int CPU_haveNEON(void)
    query the OS kernel in a platform-specific way. :/ */
 #ifdef SDL_CPUINFO_DISABLED
     return 0; /* disabled */
-#elif (defined(__WINDOWS__) || defined(__WINRT__) || defined(__GDK__)) && (defined(_M_ARM) || defined(_M_ARM64))
+#elif (defined(__WINDOWS__) || defined(__WINRT__) || defined(__GDK__)) && (defined(_M_ARM) || defined(_M_ARM64) || defined(_M_ARM64EC))
 /* Visual Studio, for ARM, doesn't define __ARM_ARCH. Handle this first. */
 /* Seems to have been removed */
 #ifndef PF_ARM_NEON_INSTRUCTIONS_AVAILABLE
diff --git a/src/stdlib/SDL_mslibc.c b/src/stdlib/SDL_mslibc.c
index 184b7e2..7951abb 100644
--- a/src/stdlib/SDL_mslibc.c
+++ b/src/stdlib/SDL_mslibc.c
@@ -762,7 +762,7 @@ void __declspec(naked) _alloca_probe_16(void)
 
 #endif /* _M_IX86 */
 
-#ifdef _M_ARM64
+#if defined(_M_ARM64) || defined(_M_ARM64EC)
 
 void __chkstk(void);
 void __chkstk() {
diff --git a/src/video/SDL_blit.h b/src/video/SDL_blit.h
index 0903026..fbad01b 100644
--- a/src/video/SDL_blit.h
+++ b/src/video/SDL_blit.h
@@ -24,7 +24,7 @@
 #define SDL_blit_h_
 
 /* pixman ARM blitters are 32 bit only : */
-#if defined(__aarch64__) || defined(_M_ARM64)
+#if defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
 #undef SDL_ARM_SIMD_BLITTERS
 #undef SDL_ARM_NEON_BLITTERS
 #endif

@slouken
Copy link
Collaborator

slouken commented Mar 3, 2024

From the documentation:

When compiling ARM64EC, x64 intrinsic functions are supported and will be translated to ARM64EC code automatically.

I think this means we really don't have to make any SDL code changes to build and run in that environment?

As a test, I followed the instructions to add an ARM64EC target here, and everything built fine.
https://learn.microsoft.com/en-us/windows/arm/arm64ec-build

I don't have an ARM64 device to test on, so maybe someone could verify that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants