24 #include "../SDL_internal.h" 27 #if defined(__WIN32__) 28 #include "../core/windows/SDL_windows.h" 38 #ifdef HAVE_SYSCTLBYNAME 39 #include <sys/types.h> 40 #include <sys/sysctl.h> 42 #if defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__)) 43 #include <sys/sysctl.h> 44 #elif defined(__OpenBSD__) && defined(__powerpc__) 45 #include <sys/param.h> 46 #include <sys/sysctl.h> 47 #include <machine/cpu.h> 48 #elif SDL_ALTIVEC_BLITTERS && HAVE_SETJMP 53 #if (defined(__LINUX__) || defined(__ANDROID__)) && defined(__ARM_ARCH) 59 #define HWCAP_NEON (1 << 12) 61 #if defined HAVE_GETAUXVAL 68 #define CPU_HAS_RDTSC 0x00000001 69 #define CPU_HAS_ALTIVEC 0x00000002 70 #define CPU_HAS_MMX 0x00000004 71 #define CPU_HAS_3DNOW 0x00000008 72 #define CPU_HAS_SSE 0x00000010 73 #define CPU_HAS_SSE2 0x00000020 74 #define CPU_HAS_SSE3 0x00000040 75 #define CPU_HAS_SSE41 0x00000100 76 #define CPU_HAS_SSE42 0x00000200 77 #define CPU_HAS_AVX 0x00000400 78 #define CPU_HAS_AVX2 0x00000800 79 #define CPU_HAS_NEON 0x00001000 80 #define CPU_HAS_ARM_SIMD 0x00002000 82 #if SDL_ALTIVEC_BLITTERS && HAVE_SETJMP && !__MACOSX__ && !__OpenBSD__ 86 static jmp_buf jmpbuf;
88 illegal_instruction(
int sig)
99 #ifndef SDL_CPUINFO_DISABLED 100 #if defined(__GNUC__) && defined(i386) 102 " pushfl # Get original EFLAGS \n" 104 " movl %%eax,%%ecx \n" 105 " xorl $0x200000,%%eax # Flip ID bit in EFLAGS \n" 106 " pushl %%eax # Save new EFLAGS value on stack \n" 107 " popfl # Replace current EFLAGS value \n" 108 " pushfl # Get new EFLAGS \n" 109 " popl %%eax # Store new EFLAGS in EAX \n" 110 " xorl %%ecx,%%eax # Can not toggle ID bit, \n" 111 " jz 1f # Processor=80486 \n" 112 " movl $1,%0 # We have CPUID support \n" 118 #elif defined(__GNUC__) && defined(__x86_64__) 122 " pushfq # Get original EFLAGS \n" 124 " movq %%rax,%%rcx \n" 125 " xorl $0x200000,%%eax # Flip ID bit in EFLAGS \n" 126 " pushq %%rax # Save new EFLAGS value on stack \n" 127 " popfq # Replace current EFLAGS value \n" 128 " pushfq # Get new EFLAGS \n" 129 " popq %%rax # Store new EFLAGS in EAX \n" 130 " xorl %%ecx,%%eax # Can not toggle ID bit, \n" 131 " jz 1f # Processor=80486 \n" 132 " movl $1,%0 # We have CPUID support \n" 138 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) 140 pushfd ; Get original EFLAGS
143 xor eax, 200000
h ; Flip ID bit
in EFLAGS
144 push eax ; Save
new EFLAGS
value on stack
145 popfd ; Replace current EFLAGS
value 146 pushfd ; Get
new EFLAGS
147 pop eax ; Store
new EFLAGS
in EAX
148 xor eax, ecx ; Can not toggle ID bit,
149 jz
done ; Processor=80486
150 mov has_CPUID,1 ; We have CPUID support
153 #elif defined(_MSC_VER) && defined(_M_X64) 155 #elif defined(__sun) && defined(__i386) 160 " xorl $0x200000,%eax \n" 167 " movl $1,-8(%ebp) \n" 170 #elif defined(__sun) && defined(__amd64) 175 " xorl $0x200000,%eax \n" 182 " movl $1,-8(%rbp) \n" 191 #if defined(__GNUC__) && defined(i386) 192 #define cpuid(func, a, b, c, d) \ 193 __asm__ __volatile__ ( \ 195 " xorl %%ecx,%%ecx \n" \ 197 " movl %%ebx, %%esi \n" \ 199 "=a" (a), "=S" (b), "=c" (c), "=d" (d) : "a" (func)) 200 #elif defined(__GNUC__) && defined(__x86_64__) 201 #define cpuid(func, a, b, c, d) \ 202 __asm__ __volatile__ ( \ 204 " xorq %%rcx,%%rcx \n" \ 206 " movq %%rbx, %%rsi \n" \ 208 "=a" (a), "=S" (b), "=c" (c), "=d" (d) : "a" (func)) 209 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) 210 #define cpuid(func, a, b, c, d) \ 212 __asm mov eax, func \ 220 #elif defined(_MSC_VER) && defined(_M_X64) 221 #define cpuid(func, a, b, c, d) \ 224 __cpuid(CPUInfo, func); \ 231 #define cpuid(func, a, b, c, d) \ 241 cpuid(0, a, b, c, d);
243 cpuid(1, a, b, c, d);
255 cpuid(0, a, b, c, d);
259 cpuid(1, a, b, c, d);
260 if (!(c & 0x08000000)) {
266 #if defined(__GNUC__) && (defined(i386) || defined(__x86_64__)) 267 asm(
".byte 0x0f, 0x01, 0xd0" :
"=a" (
a) :
"c" (0) :
"%edx");
268 #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) && (_MSC_FULL_VER >= 160040219) 270 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) 274 _asm _emit 0x0f _asm _emit 0x01 _asm _emit 0xd0
293 volatile int altivec = 0;
294 #ifndef SDL_CPUINFO_DISABLED 295 #if (defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__))) || (defined(__OpenBSD__) && defined(__powerpc__)) 297 int selectors[2] = { CTL_MACHDEP, CPU_ALTIVEC };
299 int selectors[2] = { CTL_HW, HW_VECTORUNIT };
301 int hasVectorUnit = 0;
302 size_t length =
sizeof(hasVectorUnit);
303 int error = sysctl(selectors, 2, &hasVectorUnit, &length,
NULL, 0);
305 altivec = (hasVectorUnit != 0);
306 #elif SDL_ALTIVEC_BLITTERS && HAVE_SETJMP 307 void (*handler) (
int sig);
308 handler = signal(SIGILL, illegal_instruction);
309 if (setjmp(jmpbuf) == 0) {
310 asm volatile (
"mtspr 256, %0\n\t" "vand %%v0, %%v0, %%v0"::
"r" (-1));
313 signal(SIGILL, handler);
322 #include <sys/types.h> 323 #include <sys/stat.h> 333 fd = open(
"/proc/self/auxv", O_RDONLY);
337 while (read(fd, &aux,
sizeof aux) ==
sizeof aux)
339 if (aux.a_type == AT_PLATFORM)
341 const char *plat = (
const char *) aux.a_un.a_val;
342 arm_simd = strncmp(plat,
"v6l", 3) == 0 ||
343 strncmp(plat,
"v7l", 3) == 0;
356 #warning SDL_HasARMSIMD is not implemented for this ARM platform. Write me. 362 #if (defined(__LINUX__) || defined(__ANDROID__)) && defined(__ARM_ARCH) && !defined(HAVE_GETAUXVAL) 364 readProcAuxvForNeon(
void)
368 const int fd = open(
"/proc/self/auxv", O_RDONLY);
370 while (read(fd, kv,
sizeof (kv)) ==
sizeof (kv)) {
371 if (kv[0] == AT_HWCAP) {
372 neon = ((kv[1] & HWCAP_NEON) == HWCAP_NEON);
388 #if defined(SDL_CPUINFO_DISABLED) 390 #elif (defined(__WINDOWS__) || defined(__WINRT__)) && (defined(_M_ARM) || defined(_M_ARM64)) 393 # if !defined(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) 394 # define PF_ARM_NEON_INSTRUCTIONS_AVAILABLE 19 397 return IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) != 0;
398 #elif !defined(__ARM_ARCH) 400 #elif __ARM_ARCH >= 8 402 #elif defined(__APPLE__) && (__ARM_ARCH >= 7) 405 #elif defined(__APPLE__) 407 #elif defined(__QNXNTO__) 408 return SYSPAGE_ENTRY(cpuinfo)->flags & ARM_CPU_FLAG_NEON;
409 #elif (defined(__LINUX__) || defined(__ANDROID__)) && defined(HAVE_GETAUXVAL) 410 return ((getauxval(AT_HWCAP) & HWCAP_NEON) == HWCAP_NEON);
411 #elif defined(__LINUX__) 412 return readProcAuxvForNeon();
413 #elif defined(__ANDROID__) 416 AndroidCpuFamily cpu_family = android_getCpuFamily();
417 if (cpu_family == ANDROID_CPU_FAMILY_ARM) {
418 uint64_t cpu_features = android_getCpuFeatures();
419 if ((cpu_features & ANDROID_CPU_ARM_FEATURE_NEON) != 0) {
426 #warning SDL_HasNEON is not implemented for this ARM platform. Write me. 446 cpuid(0x80000000, a, b, c, d);
447 if (a >= 0x80000001) {
448 cpuid(0x80000001, a, b, c, d);
449 return (d & 0x80000000);
479 cpuid(0, a, b, c, d);
481 cpuid(1, a, b, c, d);
482 return (c & 0x00000001);
494 cpuid(0, a, b, c, d);
496 cpuid(1, a, b, c, d);
497 return (c & 0x00080000);
509 cpuid(0, a, b, c, d);
511 cpuid(1, a, b, c, d);
512 return (c & 0x00100000);
524 cpuid(0, a, b, c, d);
526 cpuid(1, a, b, c, d);
527 return (c & 0x10000000);
539 cpuid(0, a, b, c, d);
541 cpuid(7, a, b, c, d);
542 return (b & 0x00000020);
554 #ifndef SDL_CPUINFO_DISABLED 555 #if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) 560 #ifdef HAVE_SYSCTLBYNAME 569 GetSystemInfo(&info);
586 static char SDL_CPUType[13];
588 if (!SDL_CPUType[0]) {
593 cpuid(0x00000000, a, b, c, d);
595 SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
596 SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
597 SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
598 SDL_CPUType[i++] = (char)(b & 0xff);
600 SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
601 SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
602 SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
603 SDL_CPUType[i++] = (char)(d & 0xff);
605 SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
606 SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
607 SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
608 SDL_CPUType[i++] = (char)(c & 0xff);
610 if (!SDL_CPUType[0]) {
611 SDL_strlcpy(SDL_CPUType,
"Unknown",
sizeof(SDL_CPUType));
622 static char SDL_CPUName[48];
624 if (!SDL_CPUName[0]) {
629 cpuid(0x80000000, a, b, c, d);
630 if (a >= 0x80000004) {
631 cpuid(0x80000002, a, b, c, d);
632 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
633 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
634 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
635 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
636 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
637 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
638 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
639 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
640 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
641 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
642 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
643 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
644 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
645 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
646 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
647 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
648 cpuid(0x80000003, a, b, c, d);
649 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
650 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
651 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
652 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
653 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
654 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
655 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
656 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
657 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
658 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
659 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
660 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
661 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
662 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
663 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
664 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
665 cpuid(0x80000004, a, b, c, d);
666 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
667 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
668 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
669 SDL_CPUName[i++] = (char)(a & 0xff); a >>= 8;
670 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
671 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
672 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
673 SDL_CPUName[i++] = (char)(b & 0xff); b >>= 8;
674 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
675 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
676 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
677 SDL_CPUName[i++] = (char)(c & 0xff); c >>= 8;
678 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
679 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
680 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
681 SDL_CPUName[i++] = (char)(d & 0xff); d >>= 8;
684 if (!SDL_CPUName[0]) {
685 SDL_strlcpy(SDL_CPUName,
"Unknown",
sizeof(SDL_CPUName));
698 if (
SDL_strcmp(cpuType,
"GenuineIntel") == 0) {
699 cpuid(0x00000001, a, b, c, d);
700 return (((b >> 8) & 0xff) * 8);
701 }
else if (
SDL_strcmp(cpuType,
"AuthenticAMD") == 0) {
702 cpuid(0x80000005, a, b, c, d);
883 #ifndef SDL_CPUINFO_DISABLED 884 #if defined(HAVE_SYSCONF) && defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE) 886 SDL_SystemRAM = (int)((
Sint64)sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE) / (1024*1024));
889 #ifdef HAVE_SYSCTLBYNAME 891 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) 893 int mib[2] = {CTL_HW, HW_REALMEM};
896 int mib[2] = {CTL_HW, HW_PHYSMEM};
899 int mib[2] = {CTL_HW, HW_MEMSIZE};
902 size_t len =
sizeof(memsize);
904 if (sysctl(mib, 2, &memsize, &len,
NULL, 0) == 0) {
912 stat.dwLength =
sizeof(stat);
913 if (GlobalMemoryStatusEx(&stat)) {
933 printf(
"CPU name: %s\n", SDL_GetCPUName());
static int CPU_haveSSE42(void)
SDL_bool SDL_HasSSE41(void)
int SDL_GetCPUCount(void)
static int CPU_haveAVX(void)
static const char * SDL_GetCPUType(void)
static int CPU_haveRDTSC(void)
unsigned long long uint64_t
static SDL_bool CPU_OSSavesYMM(void)
SDL_bool SDL_HasSSE(void)
SDL_bool SDL_HasSSE3(void)
static SDL_bool CPU_haveARMSIMD(void)
static int CPU_have3DNow(void)
uint32_t Uint32
An unsigned 32-bit integer type.
SDL_bool SDL_HasAltiVec(void)
static int CPU_haveCPUID(void)
uint64_t Uint64
An unsigned 64-bit integer type.
SDL_bool SDL_HasSSE42(void)
SDL_bool SDL_HasARMSIMD(void)
SDL_bool SDL_HasMMX(void)
SDL_bool SDL_HasAVX2(void)
static int CPU_haveAltiVec(void)
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst op &r &cond WK op &r &cond WK op &r &cond WK else op &m &cond &ia op &r &cond WK else op &m &cond &ia elseif elseif else error unsupported base if elseif elseif else error unsupported unaligned pixldst unaligned endm macro pixst base base else pixldst base endif endm macro PF base if bpp PF set rept prefetch_distance PF set OFFSET endr endif endm macro preload_leading_step2 base if bpp ifc DST PF PF else if bpp lsl PF PF lsl PF PF lsl PF PF PF else PF mov
static int CPU_haveSSE3(void)
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 SDL_AssertionHandler void SDL_SpinLock SDL_atomic_t int int return SDL_atomic_t return void void void return void return int return SDL_AudioSpec SDL_AudioSpec return int int return return int SDL_RWops int SDL_AudioSpec Uint8 ** d
GLsizei const GLfloat * value
SDL_bool SDL_HasNEON(void)
#define SDL_CACHELINE_SIZE
#define cpuid(func, a, b, c, d)
SDL_bool SDL_HasAVX(void)
static Uint32 SDL_CPUFeatures
static int CPU_haveSSE(void)
static Uint32 SDL_GetCPUFeatures(void)
static int CPU_haveAVX2(void)
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
static int CPU_haveNEON(void)
SDL_bool SDL_HasRDTSC(void)
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
static int CPU_getCPUIDFeatures(void)
int SDL_GetSystemRAM(void)
int64_t Sint64
A signed 64-bit integer type.
GLuint GLsizei GLsizei * length
GLboolean GLboolean GLboolean GLboolean a
SDL_bool SDL_HasSSE2(void)
static int CPU_haveSSE41(void)
static int CPU_haveMMX(void)
GLboolean GLboolean GLboolean b
static int CPU_haveSSE2(void)
SDL_bool SDL_Has3DNow(void)
GLfloat GLfloat GLfloat GLfloat h
int SDL_GetCPUCacheLineSize(void)