cpuinfo: Added SDL_HasAVX512F().
authorRyan C. Gordon <icculus@icculus.org>
Mon, 21 May 2018 11:35:42 -0400
changeset 11986e307b74aa643
parent 11985 36aa0bf7312b
child 11987 0c284754e25b
cpuinfo: Added SDL_HasAVX512F().

This checks for the "foundation" AVX-512 instructions (that all AVX-512
compatible CPUs support).
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/include/SDL_cpuinfo.h	Mon May 14 00:03:39 2018 -0400
     1.2 +++ b/include/SDL_cpuinfo.h	Mon May 21 11:35:42 2018 -0400
     1.3 @@ -160,6 +160,11 @@
     1.4  extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX2(void);
     1.5  
     1.6  /**
     1.7 + *  This function returns true if the CPU has AVX-512F (foundation) features.
     1.8 + */
     1.9 +extern DECLSPEC SDL_bool SDLCALL SDL_HasAVX512F(void);
    1.10 +
    1.11 +/**
    1.12   *  This function returns true if the CPU has NEON (ARM SIMD) features.
    1.13   */
    1.14  extern DECLSPEC SDL_bool SDLCALL SDL_HasNEON(void);
     2.1 --- a/src/cpuinfo/SDL_cpuinfo.c	Mon May 14 00:03:39 2018 -0400
     2.2 +++ b/src/cpuinfo/SDL_cpuinfo.c	Mon May 21 11:35:42 2018 -0400
     2.3 @@ -89,6 +89,7 @@
     2.4  #define CPU_HAS_AVX     (1 << 9)
     2.5  #define CPU_HAS_AVX2    (1 << 10)
     2.6  #define CPU_HAS_NEON    (1 << 11)
     2.7 +#define CPU_HAS_AVX512F (1 << 12)
     2.8  
     2.9  #if SDL_ALTIVEC_BLITTERS && HAVE_SETJMP && !__MACOSX__ && !__OpenBSD__
    2.10  /* This is the brute force way of detecting instruction sets...
    2.11 @@ -247,6 +248,7 @@
    2.12  static int CPU_CPUIDFeatures[4];
    2.13  static int CPU_CPUIDMaxFunction = 0;
    2.14  static SDL_bool CPU_OSSavesYMM = SDL_FALSE;
    2.15 +static SDL_bool CPU_OSSavesZMM = SDL_FALSE;
    2.16  
    2.17  static void
    2.18  CPU_calcCPUIDFeatures(void)
    2.19 @@ -267,7 +269,7 @@
    2.20  
    2.21                  /* Check to make sure we can call xgetbv */
    2.22                  if (c & 0x08000000) {
    2.23 -                    /* Call xgetbv to see if YMM register state is saved */
    2.24 +                    /* Call xgetbv to see if YMM (etc) register state is saved */
    2.25  #if defined(__GNUC__) && (defined(i386) || defined(__x86_64__))
    2.26                      __asm__(".byte 0x0f, 0x01, 0xd0" : "=a" (a) : "c" (0) : "%edx");
    2.27  #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) && (_MSC_FULL_VER >= 160040219) /* VS2010 SP1 */
    2.28 @@ -281,6 +283,7 @@
    2.29                      }
    2.30  #endif
    2.31                      CPU_OSSavesYMM = ((a & 6) == 6) ? SDL_TRUE : SDL_FALSE;
    2.32 +                    CPU_OSSavesZMM = (CPU_OSSavesYMM && ((a & 0xe0) == 0xe0)) ? SDL_TRUE : SDL_FALSE;
    2.33                  }
    2.34              }
    2.35          }
    2.36 @@ -401,6 +404,18 @@
    2.37      return 0;
    2.38  }
    2.39  
    2.40 +static int
    2.41 +CPU_haveAVX512F(void)
    2.42 +{
    2.43 +    if (CPU_OSSavesZMM && (CPU_CPUIDMaxFunction >= 7)) {
    2.44 +        int a, b, c, d;
    2.45 +        (void) a; (void) b; (void) c; (void) d;  /* compiler warnings... */
    2.46 +        cpuid(7, a, b, c, d);
    2.47 +        return (b & 0x00010000);
    2.48 +    }
    2.49 +    return 0;
    2.50 +}
    2.51 +
    2.52  static int SDL_CPUCount = 0;
    2.53  
    2.54  int
    2.55 @@ -624,6 +639,10 @@
    2.56              SDL_CPUFeatures |= CPU_HAS_AVX2;
    2.57              SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 32);
    2.58          }
    2.59 +        if (CPU_haveAVX512F()) {
    2.60 +            SDL_CPUFeatures |= CPU_HAS_AVX512F;
    2.61 +            SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 64);
    2.62 +        }
    2.63          if (CPU_haveNEON()) {
    2.64              SDL_CPUFeatures |= CPU_HAS_NEON;
    2.65              SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 16);
    2.66 @@ -700,6 +719,12 @@
    2.67  }
    2.68  
    2.69  SDL_bool
    2.70 +SDL_HasAVX512F(void)
    2.71 +{
    2.72 +    return CPU_FEATURE_AVAILABLE(CPU_HAS_AVX512F);
    2.73 +}
    2.74 +
    2.75 +SDL_bool
    2.76  SDL_HasNEON(void)
    2.77  {
    2.78      return CPU_FEATURE_AVAILABLE(CPU_HAS_NEON);
    2.79 @@ -819,6 +844,7 @@
    2.80      printf("SSE4.2: %d\n", SDL_HasSSE42());
    2.81      printf("AVX: %d\n", SDL_HasAVX());
    2.82      printf("AVX2: %d\n", SDL_HasAVX2());
    2.83 +    printf("AVX-512F: %d\n", SDL_HasAVX512F());
    2.84      printf("NEON: %d\n", SDL_HasNEON());
    2.85      printf("RAM: %d MB\n", SDL_GetSystemRAM());
    2.86      return 0;
     3.1 --- a/src/dynapi/SDL_dynapi_overrides.h	Mon May 14 00:03:39 2018 -0400
     3.2 +++ b/src/dynapi/SDL_dynapi_overrides.h	Mon May 21 11:35:42 2018 -0400
     3.3 @@ -671,3 +671,4 @@
     3.4  #define SDL_log10f SDL_log10f_REAL
     3.5  #define SDL_GameControllerMappingForDeviceIndex SDL_GameControllerMappingForDeviceIndex_REAL
     3.6  #define SDL_LinuxSetThreadPriority SDL_LinuxSetThreadPriority_REAL
     3.7 +#define SDL_HasAVX512F SDL_HasAVX512F_REAL
     4.1 --- a/src/dynapi/SDL_dynapi_procs.h	Mon May 14 00:03:39 2018 -0400
     4.2 +++ b/src/dynapi/SDL_dynapi_procs.h	Mon May 21 11:35:42 2018 -0400
     4.3 @@ -711,3 +711,4 @@
     4.4  #ifdef __LINUX__
     4.5  SDL_DYNAPI_PROC(int,SDL_LinuxSetThreadPriority,(Sint64 a, int b),(a,b),return)
     4.6  #endif
     4.7 +SDL_DYNAPI_PROC(SDL_bool,SDL_HasAVX512F,(void),(),return)
     5.1 --- a/test/testplatform.c	Mon May 14 00:03:39 2018 -0400
     5.2 +++ b/test/testplatform.c	Mon May 21 11:35:42 2018 -0400
     5.3 @@ -380,6 +380,7 @@
     5.4          SDL_Log("SSE4.2 %s\n", SDL_HasSSE42()? "detected" : "not detected");
     5.5          SDL_Log("AVX %s\n", SDL_HasAVX()? "detected" : "not detected");
     5.6          SDL_Log("AVX2 %s\n", SDL_HasAVX2()? "detected" : "not detected");
     5.7 +        SDL_Log("AVX-512F %s\n", SDL_HasAVX512F()? "detected" : "not detected");
     5.8          SDL_Log("NEON %s\n", SDL_HasNEON()? "detected" : "not detected");
     5.9          SDL_Log("System RAM %d MB\n", SDL_GetSystemRAM());
    5.10      }