Commit 09b462044f776ed1888403be23ae3a2ccb2443f1

Sylvain Becker 2018-12-04T16:50:31

Windows: NEON detection and intrinsic includes on Visual Studio Visual Studio doesn't define __ARM_ARCH nor _ARM_NEON, but _M_ARM and _M_ARM64, so SDL_HasNEON() was bypassed. PF_ARM_NEON_INSTRUCTIONS_AVAILABLE doesn't see to be defined (but still works when defined as 19).

diff --git a/include/SDL_cpuinfo.h b/include/SDL_cpuinfo.h
index bbd66db..5e078f2 100644
--- a/include/SDL_cpuinfo.h
+++ b/include/SDL_cpuinfo.h
@@ -54,8 +54,22 @@
 #if defined(HAVE_ALTIVEC_H) && defined(__ALTIVEC__) && !defined(__APPLE_ALTIVEC__) && defined(SDL_ENABLE_ALTIVEC_H)
 #include <altivec.h>
 #endif
-#if defined(__ARM_NEON) && !defined(SDL_DISABLE_ARM_NEON_H)
-#include <arm_neon.h>
+#if !defined(SDL_DISABLE_ARM_NEON_H)
+#  if defined(__ARM_NEON)
+#    include <arm_neon.h>
+#  elif defined(__WINDOWS__) || defined(__WINRT__)
+/* Visual Studio doesn't define __ARM_ARCH, but _M_ARM (if set, always 7), and _M_ARM64 (if set, always 1).
+#    if defined(_M_ARM)
+#      include <armintr.h>
+#      include <arm_neon.h>
+#    endif
+#    if defined (_M_ARM64)
+#      include <armintr.h>
+#      include <arm_neon.h>
+#    endif
+/* Set __ARM_NEON so that it can be used elsewhere, at compile time */
+#    define __ARM_NEON 1
+#  endif
 #endif
 #if defined(__3dNOW__) && !defined(SDL_DISABLE_MM3DNOW_H)
 #include <mm3dnow.h>
diff --git a/src/cpuinfo/SDL_cpuinfo.c b/src/cpuinfo/SDL_cpuinfo.c
index 7abf408..a0d560a 100644
--- a/src/cpuinfo/SDL_cpuinfo.c
+++ b/src/cpuinfo/SDL_cpuinfo.c
@@ -352,8 +352,18 @@ CPU_haveNEON(void)
 {
 /* The way you detect NEON is a privileged instruction on ARM, so you have
    query the OS kernel in a platform-specific way. :/ */
-#if defined(SDL_CPUINFO_DISABLED) || !defined(__ARM_ARCH)
-    return 0;  /* disabled or not an ARM CPU at all. */
+#if defined(SDL_CPUINFO_DISABLED)
+   return 0; /* disabled */
+#elif (defined(__WINDOWS__) || defined(__WINRT__)) && (defined(_M_ARM) || defined(_M_ARM64))
+/* Visual Studio, for ARM, doesn't define __ARM_ARCH. Handle this first. */
+/* Seems to have been removed */
+#  if !defined(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE)
+#    define PF_ARM_NEON_INSTRUCTIONS_AVAILABLE 19
+#  endif
+/* All WinRT ARM devices are required to support NEON, but just in case. */
+    return IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) != 0;
+#elif !defined(__ARM_ARCH)
+    return 0;  /* not an ARM CPU at all. */
 #elif __ARM_ARCH >= 8
     return 1;  /* ARMv8 always has non-optional NEON support. */
 #elif defined(__APPLE__) && (__ARM_ARCH >= 7)
@@ -379,9 +389,6 @@ CPU_haveNEON(void)
         }
         return 0;
     }
-#elif (defined(__WINDOWS__) || defined(__WINRT__)) && defined(_M_ARM)
-    /* All WinRT ARM devices are required to support NEON, but just in case. */
-    return IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) != 0;
 #else
 #warning SDL_HasNEON is not implemented for this ARM platform. Write me.
     return 0;