src/cpuinfo/SDL_cpuinfo.c
changeset 10624 294ee69a9f11
parent 10623 3b93b7acc1b4
child 10625 d40f7ebf34eb
equal deleted inserted replaced
10623:3b93b7acc1b4 10624:294ee69a9f11
    48 #elif SDL_ALTIVEC_BLITTERS && HAVE_SETJMP
    48 #elif SDL_ALTIVEC_BLITTERS && HAVE_SETJMP
    49 #include <signal.h>
    49 #include <signal.h>
    50 #include <setjmp.h>
    50 #include <setjmp.h>
    51 #endif
    51 #endif
    52 
    52 
    53 #if 0  /* !!! FIXME */
    53 #if defined(__LINUX__) && defined(__ARM_ARCH)
    54 #if defined(__ANDROID__) && defined(__ARM_ARCH)
       
    55 #include <cpu-features.h>
       
    56 #endif
       
    57 #endif
       
    58 
       
    59 #if defined(__LINUX__) && defined(__ARM_ARCH) && HAVE_GETAUXVAL
       
    60 #include <sys/auxv.h>
    54 #include <sys/auxv.h>
    61 #include <asm/hwcap.h>
    55 #include <asm/hwcap.h>
    62 #endif
    56 #endif
    63 
    57 
    64 #define CPU_HAS_RDTSC   0x00000001
    58 #define CPU_HAS_RDTSC   0x00000001
   298 #endif
   292 #endif
   299 #endif
   293 #endif
   300     return altivec;
   294     return altivec;
   301 }
   295 }
   302 
   296 
       
   297 #if (defined(__LINUX__) || defined(__ANDROID__)) && !HAVE_GETAUXVAL
       
   298 static int
       
   299 readProcAuxvForNeon(void)
       
   300 {
       
   301     int neon = 0;
       
   302     int kv[2];
       
   303     const int fd = open("/proc/self/auxv", O_RDONLY);
       
   304 
       
   305     if (fd == -1) {
       
   306         return 0;
       
   307     }
       
   308 
       
   309     while (read(fd, kv, sizeof (kv)) == sizeof (kv)) {
       
   310         if (kv[0] == AT_HWCAP) {
       
   311             neon = ((kv[1] & HWCAP_NEON) == HWCAP_NEON);
       
   312             break;
       
   313         }
       
   314     }
       
   315 
       
   316     close(fd);
       
   317 
       
   318     return neon;
       
   319 }
       
   320 #endif
       
   321 
       
   322 
   303 static int
   323 static int
   304 CPU_haveNEON(void)
   324 CPU_haveNEON(void)
   305 {
   325 {
   306     int neon = 0;
       
   307 
       
   308 /* The way you detect NEON is a privileged instruction on ARM, so you have
   326 /* The way you detect NEON is a privileged instruction on ARM, so you have
   309    query the OS kernel in a platform-specific way. :/ */
   327    query the OS kernel in a platform-specific way. :/ */
   310 #ifndef SDL_CPUINFO_DISABLED
   328 #if defined(SDL_CPUINFO_DISABLED) || !defined(__ARM_ARCH)
   311 #if defined(__APPLE__) && defined(__ARM_ARCH)
   329     return 0;
       
   330 #elif __ARM_ARCH >= 8
       
   331     return 1;  // ARMv8 always has non-optional NEON support.
       
   332 #elif defined(__APPLE__)
   312     /* all hardware that runs iOS 5 and later support NEON, but check anyhow */
   333     /* all hardware that runs iOS 5 and later support NEON, but check anyhow */
       
   334     int neon = 0;
   313     size_t length = sizeof (neon);
   335     size_t length = sizeof (neon);
   314     const int error = sysctlbyname("hw.optional.neon", &neon, &length, NULL, 0);
   336     const int error = sysctlbyname("hw.optional.neon", &neon, &length, NULL, 0);
   315     if (!error)
   337     return (!error) && (neon != 0);
   316         neon = (neon != 0);
   338 /* Android offers a static library for this but all it does is parse /proc/cpuinfo */
   317 #elif 0 && defined(__ANDROID__) && defined(__ARM_ARCH)  /* !!! FIXME */
   339 #elif (defined(__LINUX__) || defined(__ANDROID__)) && HAVE_GETAUXVAL
   318     if ( (android_getCpuFamily() == ANDROID_CPU_FAMILY_ARM) &&
   340     return ((getauxval(AT_HWCAP) & HWCAP_NEON) == HWCAP_NEON)
   319          ((android_getCpuFeatures() & ANDROID_CPU_ARM_FEATURE_NEON) != 0) ) {
   341 #elif (defined(__LINUX__) || defined(__ANDROID__))
   320         neon = 1;
   342     return readProcAuxvForNeon();
   321     }
       
   322 #elif defined(__LINUX__) && defined(__ARM_ARCH) && HAVE_GETAUXVAL
       
   323     if (getauxval(AT_HWCAP) & HWCAP_NEON) {
       
   324         neon = 1;
       
   325     }
       
   326 #elif (defined(__WINDOWS__) || defined(__WINRT__)) && defined(_M_ARM)
   343 #elif (defined(__WINDOWS__) || defined(__WINRT__)) && defined(_M_ARM)
   327     /* All WinRT ARM devices are required to support NEON, but just in case. */
   344     /* All WinRT ARM devices are required to support NEON, but just in case. */
   328     if (IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE)) {
   345     if (IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE)) {
   329         neon = 1;
   346         neon = 1;
   330     }
   347     }
   331 #endif
   348 #else
   332 #endif
   349 #warning SDL_HasNEON is not implemented for this ARM platform. Write me.
   333 
   350 #endif
   334     return neon;
   351 #endif
   335 }
   352 }
   336 
   353 
   337 static int
   354 static int
   338 CPU_have3DNow(void)
   355 CPU_have3DNow(void)
   339 {
   356 {