src/cpuinfo/SDL_cpuinfo.c
changeset 10620 c37e02dd1a9b
parent 10619 8786a8d1088e
child 10621 3b74422e881d
     1.1 --- a/src/cpuinfo/SDL_cpuinfo.c	Wed Nov 16 22:49:04 2016 -0500
     1.2 +++ b/src/cpuinfo/SDL_cpuinfo.c	Thu Nov 17 01:15:16 2016 -0500
     1.3 @@ -50,6 +50,15 @@
     1.4  #include <setjmp.h>
     1.5  #endif
     1.6  
     1.7 +#if defined(__ANDROID__)
     1.8 +#include <cpu-features.h>
     1.9 +#endif
    1.10 +
    1.11 +#if defined(__LINUX__) && HAVE_GETAUXVAL
    1.12 +#include <sys/auxv.h>
    1.13 +#include <asm/hwcap.h>
    1.14 +#endif
    1.15 +
    1.16  #define CPU_HAS_RDTSC   0x00000001
    1.17  #define CPU_HAS_ALTIVEC 0x00000002
    1.18  #define CPU_HAS_MMX     0x00000004
    1.19 @@ -61,6 +70,7 @@
    1.20  #define CPU_HAS_SSE42   0x00000200
    1.21  #define CPU_HAS_AVX     0x00000400
    1.22  #define CPU_HAS_AVX2    0x00000800
    1.23 +#define CPU_HAS_NEON    0x00001000
    1.24  
    1.25  #if SDL_ALTIVEC_BLITTERS && HAVE_SETJMP && !__MACOSX__ && !__OpenBSD__
    1.26  /* This is the brute force way of detecting instruction sets...
    1.27 @@ -289,6 +299,40 @@
    1.28  }
    1.29  
    1.30  static int
    1.31 +CPU_haveNEON(void)
    1.32 +{
    1.33 +    int neon = 0;
    1.34 +
    1.35 +/* The way you detect NEON is a privileged instruction on ARM, so you have
    1.36 +   query the OS kernel in a platform-specific way. :/ */
    1.37 +#ifndef SDL_CPUINFO_DISABLED
    1.38 +#if defined(__APPLE__) && defined(__ARM_ARCH)
    1.39 +    /* all hardware that runs iOS 5 and later support NEON, but check anyhow */
    1.40 +    size_t length = sizeof (neon);
    1.41 +    const int error = sysctlbyname("hw.optional.neon", &neon, &length, NULL, 0);
    1.42 +    if (!error)
    1.43 +        neon = (neon != 0);
    1.44 +#elif defined(__ANDROID__)
    1.45 +    if ( (android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM) &&
    1.46 +         ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0) ) {
    1.47 +        neon = 1;
    1.48 +    }
    1.49 +#elif defined(__LINUX__) && HAVE_GETAUXVAL && defined(__arm__)
    1.50 +    if (getauxval(AT_HWCAP) & HWCAP_NEON) {
    1.51 +        neon = 1;
    1.52 +    }
    1.53 +#elif (defined(__WINDOWS__) || defined(__WINRT__)) && defined(_M_ARM)
    1.54 +    /* All WinRT ARM devices are required to support NEON, but just in case. */
    1.55 +    if (IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE)) {
    1.56 +        neon = 1;
    1.57 +    }
    1.58 +#endif
    1.59 +#endif
    1.60 +
    1.61 +    return neon;
    1.62 +}
    1.63 +
    1.64 +static int
    1.65  CPU_have3DNow(void)
    1.66  {
    1.67      if (CPU_CPUIDMaxFunction > 0) {  /* that is, do we have CPUID at all? */
    1.68 @@ -527,6 +571,9 @@
    1.69          if (CPU_haveAVX2()) {
    1.70              SDL_CPUFeatures |= CPU_HAS_AVX2;
    1.71          }
    1.72 +        if (CPU_haveNEON()) {
    1.73 +            SDL_CPUFeatures |= CPU_HAS_NEON;
    1.74 +        }
    1.75      }
    1.76      return SDL_CPUFeatures;
    1.77  }
    1.78 @@ -598,6 +645,12 @@
    1.79      return CPU_FEATURE_AVAILABLE(CPU_HAS_AVX2);
    1.80  }
    1.81  
    1.82 +SDL_bool
    1.83 +SDL_HasNEON(void)
    1.84 +{
    1.85 +    return CPU_FEATURE_AVAILABLE(CPU_HAS_NEON);
    1.86 +}
    1.87 +
    1.88  static int SDL_SystemRAM = 0;
    1.89  
    1.90  int
    1.91 @@ -667,6 +720,7 @@
    1.92      printf("SSE4.2: %d\n", SDL_HasSSE42());
    1.93      printf("AVX: %d\n", SDL_HasAVX());
    1.94      printf("AVX2: %d\n", SDL_HasAVX2());
    1.95 +    printf("NEON: %d\n", SDL_HasNEON());
    1.96      printf("RAM: %d MB\n", SDL_GetSystemRAM());
    1.97      return 0;
    1.98  }