cpuinfo: first attempt at SDL_HasNEON() implementation.
authorRyan C. Gordon <icculus@icculus.org>
Thu, 17 Nov 2016 01:15:16 -0500
changeset 10620c37e02dd1a9b
parent 10619 8786a8d1088e
child 10621 3b74422e881d
cpuinfo: first attempt at SDL_HasNEON() implementation.
CMakeLists.txt
configure.in
include/SDL_config.h.cmake
include/SDL_config.h.in
include/SDL_cpuinfo.h
src/cpuinfo/SDL_cpuinfo.c
src/dynapi/SDL_dynapi_overrides.h
src/dynapi/SDL_dynapi_procs.h
test/testplatform.c
     1.1 --- a/CMakeLists.txt	Wed Nov 16 22:49:04 2016 -0500
     1.2 +++ b/CMakeLists.txt	Thu Nov 17 01:15:16 2016 -0500
     1.3 @@ -615,7 +615,7 @@
     1.4              _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull
     1.5              atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp
     1.6              vsscanf vsnprintf fseeko fseeko64 sigaction setjmp
     1.7 -            nanosleep sysconf sysctlbyname
     1.8 +            nanosleep sysconf sysctlbyname getauxval
     1.9              )
    1.10        string(TOUPPER ${_FN} _UPPER)
    1.11        set(_HAVEVAR "HAVE_${_UPPER}")
     2.1 --- a/configure.in	Wed Nov 16 22:49:04 2016 -0500
     2.2 +++ b/configure.in	Thu Nov 17 01:15:16 2016 -0500
     2.3 @@ -268,7 +268,7 @@
     2.4          AC_DEFINE(HAVE_MPROTECT, 1, [ ])
     2.5          ]),
     2.6      )
     2.7 -    AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove strlen strlcpy strlcat strdup _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname)
     2.8 +    AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove strlen strlcpy strlcat strdup _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval)
     2.9  
    2.10      AC_CHECK_LIB(m, pow, [LIBS="$LIBS -lm"; EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lm"])
    2.11      AC_CHECK_FUNCS(atan atan2 acos asin ceil copysign cos cosf fabs floor log pow scalbn sin sinf sqrt sqrtf tan tanf)
     3.1 --- a/include/SDL_config.h.cmake	Wed Nov 16 22:49:04 2016 -0500
     3.2 +++ b/include/SDL_config.h.cmake	Thu Nov 17 01:15:16 2016 -0500
     3.3 @@ -171,6 +171,8 @@
     3.4  #cmakedefine HAVE_PTHREAD_SETNAME_NP 1
     3.5  #cmakedefine HAVE_PTHREAD_SET_NAME_NP 1
     3.6  #cmakedefine HAVE_SEM_TIMEDWAIT 1
     3.7 +#cmakedefine HAVE_GETAUXVAL 1
     3.8 +
     3.9  #elif __WIN32__
    3.10  #cmakedefine HAVE_STDARG_H 1
    3.11  #cmakedefine HAVE_STDDEF_H 1
     4.1 --- a/include/SDL_config.h.in	Wed Nov 16 22:49:04 2016 -0500
     4.2 +++ b/include/SDL_config.h.in	Thu Nov 17 01:15:16 2016 -0500
     4.3 @@ -173,6 +173,7 @@
     4.4  #undef HAVE_PTHREAD_SETNAME_NP
     4.5  #undef HAVE_PTHREAD_SET_NAME_NP
     4.6  #undef HAVE_SEM_TIMEDWAIT
     4.7 +#undef HAVE_GETAUXVAL
     4.8  
     4.9  #else
    4.10  #define HAVE_STDARG_H   1
     5.1 --- a/include/SDL_cpuinfo.h	Wed Nov 16 22:49:04 2016 -0500
     5.2 +++ b/include/SDL_cpuinfo.h	Thu Nov 17 01:15:16 2016 -0500
     5.3 @@ -145,6 +145,11 @@
     5.4  extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX2(void);
     5.5  
     5.6  /**
     5.7 + *  This function returns true if the CPU has NEON (ARM SIMD) features.
     5.8 + */
     5.9 +extern DECLSPEC SDL_bool SDLCALL SDL_HasNEON(void);
    5.10 +
    5.11 +/**
    5.12   *  This function returns the amount of RAM configured in the system, in MB.
    5.13   */
    5.14  extern DECLSPEC int SDLCALL SDL_GetSystemRAM(void);
     6.1 --- a/src/cpuinfo/SDL_cpuinfo.c	Wed Nov 16 22:49:04 2016 -0500
     6.2 +++ b/src/cpuinfo/SDL_cpuinfo.c	Thu Nov 17 01:15:16 2016 -0500
     6.3 @@ -50,6 +50,15 @@
     6.4  #include <setjmp.h>
     6.5  #endif
     6.6  
     6.7 +#if defined(__ANDROID__)
     6.8 +#include <cpu-features.h>
     6.9 +#endif
    6.10 +
    6.11 +#if defined(__LINUX__) && HAVE_GETAUXVAL
    6.12 +#include <sys/auxv.h>
    6.13 +#include <asm/hwcap.h>
    6.14 +#endif
    6.15 +
    6.16  #define CPU_HAS_RDTSC   0x00000001
    6.17  #define CPU_HAS_ALTIVEC 0x00000002
    6.18  #define CPU_HAS_MMX     0x00000004
    6.19 @@ -61,6 +70,7 @@
    6.20  #define CPU_HAS_SSE42   0x00000200
    6.21  #define CPU_HAS_AVX     0x00000400
    6.22  #define CPU_HAS_AVX2    0x00000800
    6.23 +#define CPU_HAS_NEON    0x00001000
    6.24  
    6.25  #if SDL_ALTIVEC_BLITTERS && HAVE_SETJMP && !__MACOSX__ && !__OpenBSD__
    6.26  /* This is the brute force way of detecting instruction sets...
    6.27 @@ -289,6 +299,40 @@
    6.28  }
    6.29  
    6.30  static int
    6.31 +CPU_haveNEON(void)
    6.32 +{
    6.33 +    int neon = 0;
    6.34 +
    6.35 +/* The way you detect NEON is a privileged instruction on ARM, so you have
    6.36 +   query the OS kernel in a platform-specific way. :/ */
    6.37 +#ifndef SDL_CPUINFO_DISABLED
    6.38 +#if defined(__APPLE__) && defined(__ARM_ARCH)
    6.39 +    /* all hardware that runs iOS 5 and later support NEON, but check anyhow */
    6.40 +    size_t length = sizeof (neon);
    6.41 +    const int error = sysctlbyname("hw.optional.neon", &neon, &length, NULL, 0);
    6.42 +    if (!error)
    6.43 +        neon = (neon != 0);
    6.44 +#elif defined(__ANDROID__)
    6.45 +    if ( (android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM) &&
    6.46 +         ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0) ) {
    6.47 +        neon = 1;
    6.48 +    }
    6.49 +#elif defined(__LINUX__) && HAVE_GETAUXVAL && defined(__arm__)
    6.50 +    if (getauxval(AT_HWCAP) & HWCAP_NEON) {
    6.51 +        neon = 1;
    6.52 +    }
    6.53 +#elif (defined(__WINDOWS__) || defined(__WINRT__)) && defined(_M_ARM)
    6.54 +    /* All WinRT ARM devices are required to support NEON, but just in case. */
    6.55 +    if (IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE)) {
    6.56 +        neon = 1;
    6.57 +    }
    6.58 +#endif
    6.59 +#endif
    6.60 +
    6.61 +    return neon;
    6.62 +}
    6.63 +
    6.64 +static int
    6.65  CPU_have3DNow(void)
    6.66  {
    6.67      if (CPU_CPUIDMaxFunction > 0) {  /* that is, do we have CPUID at all? */
    6.68 @@ -527,6 +571,9 @@
    6.69          if (CPU_haveAVX2()) {
    6.70              SDL_CPUFeatures |= CPU_HAS_AVX2;
    6.71          }
    6.72 +        if (CPU_haveNEON()) {
    6.73 +            SDL_CPUFeatures |= CPU_HAS_NEON;
    6.74 +        }
    6.75      }
    6.76      return SDL_CPUFeatures;
    6.77  }
    6.78 @@ -598,6 +645,12 @@
    6.79      return CPU_FEATURE_AVAILABLE(CPU_HAS_AVX2);
    6.80  }
    6.81  
    6.82 +SDL_bool
    6.83 +SDL_HasNEON(void)
    6.84 +{
    6.85 +    return CPU_FEATURE_AVAILABLE(CPU_HAS_NEON);
    6.86 +}
    6.87 +
    6.88  static int SDL_SystemRAM = 0;
    6.89  
    6.90  int
    6.91 @@ -667,6 +720,7 @@
    6.92      printf("SSE4.2: %d\n", SDL_HasSSE42());
    6.93      printf("AVX: %d\n", SDL_HasAVX());
    6.94      printf("AVX2: %d\n", SDL_HasAVX2());
    6.95 +    printf("NEON: %d\n", SDL_HasNEON());
    6.96      printf("RAM: %d MB\n", SDL_GetSystemRAM());
    6.97      return 0;
    6.98  }
     7.1 --- a/src/dynapi/SDL_dynapi_overrides.h	Wed Nov 16 22:49:04 2016 -0500
     7.2 +++ b/src/dynapi/SDL_dynapi_overrides.h	Thu Nov 17 01:15:16 2016 -0500
     7.3 @@ -621,3 +621,4 @@
     7.4  #define SDL_GameControllerGetVendor SDL_GameControllerGetVendor_REAL
     7.5  #define SDL_GameControllerGetProduct SDL_GameControllerGetProduct_REAL
     7.6  #define SDL_GameControllerGetProductVersion SDL_GameControllerGetProductVersion_REAL
     7.7 +#define SDL_HasNEON SDL_HasNEON_REAL
     8.1 --- a/src/dynapi/SDL_dynapi_procs.h	Wed Nov 16 22:49:04 2016 -0500
     8.2 +++ b/src/dynapi/SDL_dynapi_procs.h	Thu Nov 17 01:15:16 2016 -0500
     8.3 @@ -653,3 +653,4 @@
     8.4  SDL_DYNAPI_PROC(Uint16,SDL_GameControllerGetVendor,(SDL_GameController *a),(a),return)
     8.5  SDL_DYNAPI_PROC(Uint16,SDL_GameControllerGetProduct,(SDL_GameController *a),(a),return)
     8.6  SDL_DYNAPI_PROC(Uint16,SDL_GameControllerGetProductVersion,(SDL_GameController *a),(a),return)
     8.7 +SDL_DYNAPI_PROC(SDL_bool,SDL_HasNEON,(void),(),return)
     9.1 --- a/test/testplatform.c	Wed Nov 16 22:49:04 2016 -0500
     9.2 +++ b/test/testplatform.c	Thu Nov 17 01:15:16 2016 -0500
     9.3 @@ -360,6 +360,7 @@
     9.4          SDL_Log("SSE4.2 %s\n", SDL_HasSSE42()? "detected" : "not detected");
     9.5          SDL_Log("AVX %s\n", SDL_HasAVX()? "detected" : "not detected");
     9.6          SDL_Log("AVX2 %s\n", SDL_HasAVX2()? "detected" : "not detected");
     9.7 +        SDL_Log("NEON %s\n", SDL_HasNEON()? "detected" : "not detected");
     9.8          SDL_Log("System RAM %d MB\n", SDL_GetSystemRAM());
     9.9      }
    9.10      return (0);