src/cpuinfo/SDL_cpuinfo.c
changeset 11986 e307b74aa643
parent 11985 36aa0bf7312b
child 12242 df7260f149f2
equal deleted inserted replaced
11985:36aa0bf7312b 11986:e307b74aa643
    87 #define CPU_HAS_SSE41   (1 << 7)
    87 #define CPU_HAS_SSE41   (1 << 7)
    88 #define CPU_HAS_SSE42   (1 << 8)
    88 #define CPU_HAS_SSE42   (1 << 8)
    89 #define CPU_HAS_AVX     (1 << 9)
    89 #define CPU_HAS_AVX     (1 << 9)
    90 #define CPU_HAS_AVX2    (1 << 10)
    90 #define CPU_HAS_AVX2    (1 << 10)
    91 #define CPU_HAS_NEON    (1 << 11)
    91 #define CPU_HAS_NEON    (1 << 11)
       
    92 #define CPU_HAS_AVX512F (1 << 12)
    92 
    93 
    93 #if SDL_ALTIVEC_BLITTERS && HAVE_SETJMP && !__MACOSX__ && !__OpenBSD__
    94 #if SDL_ALTIVEC_BLITTERS && HAVE_SETJMP && !__MACOSX__ && !__OpenBSD__
    94 /* This is the brute force way of detecting instruction sets...
    95 /* This is the brute force way of detecting instruction sets...
    95    the idea is borrowed from the libmpeg2 library - thanks!
    96    the idea is borrowed from the libmpeg2 library - thanks!
    96  */
    97  */
   245 #endif
   246 #endif
   246 
   247 
   247 static int CPU_CPUIDFeatures[4];
   248 static int CPU_CPUIDFeatures[4];
   248 static int CPU_CPUIDMaxFunction = 0;
   249 static int CPU_CPUIDMaxFunction = 0;
   249 static SDL_bool CPU_OSSavesYMM = SDL_FALSE;
   250 static SDL_bool CPU_OSSavesYMM = SDL_FALSE;
       
   251 static SDL_bool CPU_OSSavesZMM = SDL_FALSE;
   250 
   252 
   251 static void
   253 static void
   252 CPU_calcCPUIDFeatures(void)
   254 CPU_calcCPUIDFeatures(void)
   253 {
   255 {
   254     static SDL_bool checked = SDL_FALSE;
   256     static SDL_bool checked = SDL_FALSE;
   265                 CPU_CPUIDFeatures[2] = c;
   267                 CPU_CPUIDFeatures[2] = c;
   266                 CPU_CPUIDFeatures[3] = d;
   268                 CPU_CPUIDFeatures[3] = d;
   267 
   269 
   268                 /* Check to make sure we can call xgetbv */
   270                 /* Check to make sure we can call xgetbv */
   269                 if (c & 0x08000000) {
   271                 if (c & 0x08000000) {
   270                     /* Call xgetbv to see if YMM register state is saved */
   272                     /* Call xgetbv to see if YMM (etc) register state is saved */
   271 #if defined(__GNUC__) && (defined(i386) || defined(__x86_64__))
   273 #if defined(__GNUC__) && (defined(i386) || defined(__x86_64__))
   272                     __asm__(".byte 0x0f, 0x01, 0xd0" : "=a" (a) : "c" (0) : "%edx");
   274                     __asm__(".byte 0x0f, 0x01, 0xd0" : "=a" (a) : "c" (0) : "%edx");
   273 #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) && (_MSC_FULL_VER >= 160040219) /* VS2010 SP1 */
   275 #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) && (_MSC_FULL_VER >= 160040219) /* VS2010 SP1 */
   274                     a = (int)_xgetbv(0);
   276                     a = (int)_xgetbv(0);
   275 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
   277 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
   279                         _asm _emit 0x0f _asm _emit 0x01 _asm _emit 0xd0
   281                         _asm _emit 0x0f _asm _emit 0x01 _asm _emit 0xd0
   280                         mov a, eax
   282                         mov a, eax
   281                     }
   283                     }
   282 #endif
   284 #endif
   283                     CPU_OSSavesYMM = ((a & 6) == 6) ? SDL_TRUE : SDL_FALSE;
   285                     CPU_OSSavesYMM = ((a & 6) == 6) ? SDL_TRUE : SDL_FALSE;
       
   286                     CPU_OSSavesZMM = (CPU_OSSavesYMM && ((a & 0xe0) == 0xe0)) ? SDL_TRUE : SDL_FALSE;
   284                 }
   287                 }
   285             }
   288             }
   286         }
   289         }
   287     }
   290     }
   288 }
   291 }
   399         return (b & 0x00000020);
   402         return (b & 0x00000020);
   400     }
   403     }
   401     return 0;
   404     return 0;
   402 }
   405 }
   403 
   406 
       
   407 static int
       
   408 CPU_haveAVX512F(void)
       
   409 {
       
   410     if (CPU_OSSavesZMM && (CPU_CPUIDMaxFunction >= 7)) {
       
   411         int a, b, c, d;
       
   412         (void) a; (void) b; (void) c; (void) d;  /* compiler warnings... */
       
   413         cpuid(7, a, b, c, d);
       
   414         return (b & 0x00010000);
       
   415     }
       
   416     return 0;
       
   417 }
       
   418 
   404 static int SDL_CPUCount = 0;
   419 static int SDL_CPUCount = 0;
   405 
   420 
   406 int
   421 int
   407 SDL_GetCPUCount(void)
   422 SDL_GetCPUCount(void)
   408 {
   423 {
   622         }
   637         }
   623         if (CPU_haveAVX2()) {
   638         if (CPU_haveAVX2()) {
   624             SDL_CPUFeatures |= CPU_HAS_AVX2;
   639             SDL_CPUFeatures |= CPU_HAS_AVX2;
   625             SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 32);
   640             SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 32);
   626         }
   641         }
       
   642         if (CPU_haveAVX512F()) {
       
   643             SDL_CPUFeatures |= CPU_HAS_AVX512F;
       
   644             SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 64);
       
   645         }
   627         if (CPU_haveNEON()) {
   646         if (CPU_haveNEON()) {
   628             SDL_CPUFeatures |= CPU_HAS_NEON;
   647             SDL_CPUFeatures |= CPU_HAS_NEON;
   629             SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 16);
   648             SDL_SIMDAlignment = SDL_max(SDL_SIMDAlignment, 16);
   630         }
   649         }
   631     }
   650     }
   695 
   714 
   696 SDL_bool
   715 SDL_bool
   697 SDL_HasAVX2(void)
   716 SDL_HasAVX2(void)
   698 {
   717 {
   699     return CPU_FEATURE_AVAILABLE(CPU_HAS_AVX2);
   718     return CPU_FEATURE_AVAILABLE(CPU_HAS_AVX2);
       
   719 }
       
   720 
       
   721 SDL_bool
       
   722 SDL_HasAVX512F(void)
       
   723 {
       
   724     return CPU_FEATURE_AVAILABLE(CPU_HAS_AVX512F);
   700 }
   725 }
   701 
   726 
   702 SDL_bool
   727 SDL_bool
   703 SDL_HasNEON(void)
   728 SDL_HasNEON(void)
   704 {
   729 {
   817     printf("SSE3: %d\n", SDL_HasSSE3());
   842     printf("SSE3: %d\n", SDL_HasSSE3());
   818     printf("SSE4.1: %d\n", SDL_HasSSE41());
   843     printf("SSE4.1: %d\n", SDL_HasSSE41());
   819     printf("SSE4.2: %d\n", SDL_HasSSE42());
   844     printf("SSE4.2: %d\n", SDL_HasSSE42());
   820     printf("AVX: %d\n", SDL_HasAVX());
   845     printf("AVX: %d\n", SDL_HasAVX());
   821     printf("AVX2: %d\n", SDL_HasAVX2());
   846     printf("AVX2: %d\n", SDL_HasAVX2());
       
   847     printf("AVX-512F: %d\n", SDL_HasAVX512F());
   822     printf("NEON: %d\n", SDL_HasNEON());
   848     printf("NEON: %d\n", SDL_HasNEON());
   823     printf("RAM: %d MB\n", SDL_GetSystemRAM());
   849     printf("RAM: %d MB\n", SDL_GetSystemRAM());
   824     return 0;
   850     return 0;
   825 }
   851 }
   826 
   852