SDL  2.0
SDL_cpuinfo.c File Reference
#include "../SDL_internal.h"
#include "SDL_cpuinfo.h"
#include "SDL_assert.h"
+ Include dependency graph for SDL_cpuinfo.c:

Go to the source code of this file.

Macros

#define CPU_HAS_RDTSC   (1 << 0)
 
#define CPU_HAS_ALTIVEC   (1 << 1)
 
#define CPU_HAS_MMX   (1 << 2)
 
#define CPU_HAS_3DNOW   (1 << 3)
 
#define CPU_HAS_SSE   (1 << 4)
 
#define CPU_HAS_SSE2   (1 << 5)
 
#define CPU_HAS_SSE3   (1 << 6)
 
#define CPU_HAS_SSE41   (1 << 7)
 
#define CPU_HAS_SSE42   (1 << 8)
 
#define CPU_HAS_AVX   (1 << 9)
 
#define CPU_HAS_AVX2   (1 << 10)
 
#define CPU_HAS_NEON   (1 << 11)
 
#define CPU_HAS_AVX512F   (1 << 12)
 
#define cpuid(func, a, b, c, d)   do { a = b = c = d = 0; (void) a; (void) b; (void) c; (void) d; } while (0)
 
#define CPU_haveRDTSC()   (CPU_CPUIDFeatures[3] & 0x00000010)
 
#define CPU_haveMMX()   (CPU_CPUIDFeatures[3] & 0x00800000)
 
#define CPU_haveSSE()   (CPU_CPUIDFeatures[3] & 0x02000000)
 
#define CPU_haveSSE2()   (CPU_CPUIDFeatures[3] & 0x04000000)
 
#define CPU_haveSSE3()   (CPU_CPUIDFeatures[2] & 0x00000001)
 
#define CPU_haveSSE41()   (CPU_CPUIDFeatures[2] & 0x00080000)
 
#define CPU_haveSSE42()   (CPU_CPUIDFeatures[2] & 0x00100000)
 
#define CPU_haveAVX()   (CPU_OSSavesYMM && (CPU_CPUIDFeatures[2] & 0x10000000))
 
#define CPU_FEATURE_AVAILABLE(f)   ((SDL_GetCPUFeatures() & f) ? SDL_TRUE : SDL_FALSE)
 

Functions

static int CPU_haveCPUID (void)
 
static void CPU_calcCPUIDFeatures (void)
 
static int CPU_haveAltiVec (void)
 
static int CPU_haveNEON (void)
 
static int CPU_have3DNow (void)
 
static int CPU_haveAVX2 (void)
 
static int CPU_haveAVX512F (void)
 
int SDL_GetCPUCount (void)
 
static const char * SDL_GetCPUType (void)
 
int SDL_GetCPUCacheLineSize (void)
 
static Uint32 SDL_GetCPUFeatures (void)
 
SDL_bool SDL_HasRDTSC (void)
 
SDL_bool SDL_HasAltiVec (void)
 
SDL_bool SDL_HasMMX (void)
 
SDL_bool SDL_Has3DNow (void)
 
SDL_bool SDL_HasSSE (void)
 
SDL_bool SDL_HasSSE2 (void)
 
SDL_bool SDL_HasSSE3 (void)
 
SDL_bool SDL_HasSSE41 (void)
 
SDL_bool SDL_HasSSE42 (void)
 
SDL_bool SDL_HasAVX (void)
 
SDL_bool SDL_HasAVX2 (void)
 
SDL_bool SDL_HasAVX512F (void)
 
SDL_bool SDL_HasNEON (void)
 
int SDL_GetSystemRAM (void)
 
size_t SDL_SIMDGetAlignment (void)
 Report the alignment this system needs for SIMD allocations. More...
 
voidSDL_SIMDAlloc (const size_t len)
 Allocate memory in a SIMD-friendly way. More...
 
void SDL_SIMDFree (void *ptr)
 Deallocate memory obtained from SDL_SIMDAlloc. More...
 

Variables

static int CPU_CPUIDFeatures [4]
 
static int CPU_CPUIDMaxFunction = 0
 
static SDL_bool CPU_OSSavesYMM = SDL_FALSE
 
static SDL_bool CPU_OSSavesZMM = SDL_FALSE
 
static int SDL_CPUCount = 0
 
static Uint32 SDL_CPUFeatures = 0xFFFFFFFF
 
static Uint32 SDL_SIMDAlignment = 0xFFFFFFFF
 
static int SDL_SystemRAM = 0
 

Macro Definition Documentation

◆ CPU_FEATURE_AVAILABLE

#define CPU_FEATURE_AVAILABLE (   f)    ((SDL_GetCPUFeatures() & f) ? SDL_TRUE : SDL_FALSE)

Definition at line 679 of file SDL_cpuinfo.c.

◆ CPU_HAS_3DNOW

#define CPU_HAS_3DNOW   (1 << 3)

Definition at line 89 of file SDL_cpuinfo.c.

◆ CPU_HAS_ALTIVEC

#define CPU_HAS_ALTIVEC   (1 << 1)

Definition at line 87 of file SDL_cpuinfo.c.

◆ CPU_HAS_AVX

#define CPU_HAS_AVX   (1 << 9)

Definition at line 95 of file SDL_cpuinfo.c.

◆ CPU_HAS_AVX2

#define CPU_HAS_AVX2   (1 << 10)

Definition at line 96 of file SDL_cpuinfo.c.

◆ CPU_HAS_AVX512F

#define CPU_HAS_AVX512F   (1 << 12)

Definition at line 98 of file SDL_cpuinfo.c.

◆ CPU_HAS_MMX

#define CPU_HAS_MMX   (1 << 2)

Definition at line 88 of file SDL_cpuinfo.c.

◆ CPU_HAS_NEON

#define CPU_HAS_NEON   (1 << 11)

Definition at line 97 of file SDL_cpuinfo.c.

◆ CPU_HAS_RDTSC

#define CPU_HAS_RDTSC   (1 << 0)

Definition at line 86 of file SDL_cpuinfo.c.

◆ CPU_HAS_SSE

#define CPU_HAS_SSE   (1 << 4)

Definition at line 90 of file SDL_cpuinfo.c.

◆ CPU_HAS_SSE2

#define CPU_HAS_SSE2   (1 << 5)

Definition at line 91 of file SDL_cpuinfo.c.

◆ CPU_HAS_SSE3

#define CPU_HAS_SSE3   (1 << 6)

Definition at line 92 of file SDL_cpuinfo.c.

◆ CPU_HAS_SSE41

#define CPU_HAS_SSE41   (1 << 7)

Definition at line 93 of file SDL_cpuinfo.c.

◆ CPU_HAS_SSE42

#define CPU_HAS_SSE42   (1 << 8)

Definition at line 94 of file SDL_cpuinfo.c.

◆ CPU_haveAVX

#define CPU_haveAVX ( )    (CPU_OSSavesYMM && (CPU_CPUIDFeatures[2] & 0x10000000))

Definition at line 418 of file SDL_cpuinfo.c.

◆ CPU_haveMMX

#define CPU_haveMMX ( )    (CPU_CPUIDFeatures[3] & 0x00800000)

Definition at line 412 of file SDL_cpuinfo.c.

◆ CPU_haveRDTSC

#define CPU_haveRDTSC ( )    (CPU_CPUIDFeatures[3] & 0x00000010)

Definition at line 411 of file SDL_cpuinfo.c.

◆ CPU_haveSSE

#define CPU_haveSSE ( )    (CPU_CPUIDFeatures[3] & 0x02000000)

Definition at line 413 of file SDL_cpuinfo.c.

◆ CPU_haveSSE2

#define CPU_haveSSE2 ( )    (CPU_CPUIDFeatures[3] & 0x04000000)

Definition at line 414 of file SDL_cpuinfo.c.

◆ CPU_haveSSE3

#define CPU_haveSSE3 ( )    (CPU_CPUIDFeatures[2] & 0x00000001)

Definition at line 415 of file SDL_cpuinfo.c.

◆ CPU_haveSSE41

#define CPU_haveSSE41 ( )    (CPU_CPUIDFeatures[2] & 0x00080000)

Definition at line 416 of file SDL_cpuinfo.c.

◆ CPU_haveSSE42

#define CPU_haveSSE42 ( )    (CPU_CPUIDFeatures[2] & 0x00100000)

Definition at line 417 of file SDL_cpuinfo.c.

◆ cpuid

#define cpuid (   func,
  a,
  b,
  c,
  d 
)    do { a = b = c = d = 0; (void) a; (void) b; (void) c; (void) d; } while (0)

Definition at line 250 of file SDL_cpuinfo.c.

Function Documentation

◆ CPU_calcCPUIDFeatures()

static void CPU_calcCPUIDFeatures ( void  )
static

Definition at line 260 of file SDL_cpuinfo.c.

261 {
262  static SDL_bool checked = SDL_FALSE;
263  if (!checked) {
264  checked = SDL_TRUE;
265  if (CPU_haveCPUID()) {
266  int a, b, c, d;
267  cpuid(0, a, b, c, d);
269  if (CPU_CPUIDMaxFunction >= 1) {
270  cpuid(1, a, b, c, d);
271  CPU_CPUIDFeatures[0] = a;
272  CPU_CPUIDFeatures[1] = b;
273  CPU_CPUIDFeatures[2] = c;
274  CPU_CPUIDFeatures[3] = d;
275 
276  /* Check to make sure we can call xgetbv */
277  if (c & 0x08000000) {
278  /* Call xgetbv to see if YMM (etc) register state is saved */
279 #if defined(__GNUC__) && (defined(i386) || defined(__x86_64__))
280  __asm__(".byte 0x0f, 0x01, 0xd0" : "=a" (a) : "c" (0) : "%edx");
281 #elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) && (_MSC_FULL_VER >= 160040219) /* VS2010 SP1 */
282  a = (int)_xgetbv(0);
283 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
284  __asm
285  {
286  xor ecx, ecx
287  _asm _emit 0x0f _asm _emit 0x01 _asm _emit 0xd0
288  mov a, eax
289  }
290 #endif
291  CPU_OSSavesYMM = ((a & 6) == 6) ? SDL_TRUE : SDL_FALSE;
292  CPU_OSSavesZMM = (CPU_OSSavesYMM && ((a & 0xe0) == 0xe0)) ? SDL_TRUE : SDL_FALSE;
293  }
294  }
295  }
296  }
297 }

References CPU_CPUIDFeatures, CPU_CPUIDMaxFunction, CPU_haveCPUID(), CPU_OSSavesYMM, CPU_OSSavesZMM, cpuid, d, SDL_FALSE, and SDL_TRUE.

Referenced by SDL_GetCPUFeatures(), and SDL_GetCPUType().

◆ CPU_have3DNow()

static int CPU_have3DNow ( void  )
static

Definition at line 398 of file SDL_cpuinfo.c.

399 {
400  if (CPU_CPUIDMaxFunction > 0) { /* that is, do we have CPUID at all? */
401  int a, b, c, d;
402  cpuid(0x80000000, a, b, c, d);
403  if (a >= 0x80000001) {
404  cpuid(0x80000001, a, b, c, d);
405  return (d & 0x80000000);
406  }
407  }
408  return 0;
409 }

References CPU_CPUIDMaxFunction, cpuid, and d.

Referenced by SDL_GetCPUFeatures().

◆ CPU_haveAltiVec()

static int CPU_haveAltiVec ( void  )
static

Definition at line 300 of file SDL_cpuinfo.c.

301 {
302  volatile int altivec = 0;
303 #ifndef SDL_CPUINFO_DISABLED
304 #if (defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__))) || (defined(__OpenBSD__) && defined(__powerpc__))
305 #ifdef __OpenBSD__
306  int selectors[2] = { CTL_MACHDEP, CPU_ALTIVEC };
307 #else
308  int selectors[2] = { CTL_HW, HW_VECTORUNIT };
309 #endif
310  int hasVectorUnit = 0;
311  size_t length = sizeof(hasVectorUnit);
312  int error = sysctl(selectors, 2, &hasVectorUnit, &length, NULL, 0);
313  if (0 == error)
314  altivec = (hasVectorUnit != 0);
315 #elif SDL_ALTIVEC_BLITTERS && HAVE_SETJMP
316  void (*handler) (int sig);
317  handler = signal(SIGILL, illegal_instruction);
318  if (setjmp(jmpbuf) == 0) {
319  asm volatile ("mtspr 256, %0\n\t" "vand %%v0, %%v0, %%v0"::"r" (-1));
320  altivec = 1;
321  }
322  signal(SIGILL, handler);
323 #endif
324 #endif
325  return altivec;
326 }

References NULL, and void.

Referenced by SDL_GetCPUFeatures().

◆ CPU_haveAVX2()

static int CPU_haveAVX2 ( void  )
static

Definition at line 421 of file SDL_cpuinfo.c.

422 {
423  if (CPU_OSSavesYMM && (CPU_CPUIDMaxFunction >= 7)) {
424  int a, b, c, d;
425  (void) a; (void) b; (void) c; (void) d; /* compiler warnings... */
426  cpuid(7, a, b, c, d);
427  return (b & 0x00000020);
428  }
429  return 0;
430 }

References CPU_CPUIDMaxFunction, CPU_OSSavesYMM, cpuid, d, and void.

Referenced by SDL_GetCPUFeatures().

◆ CPU_haveAVX512F()

static int CPU_haveAVX512F ( void  )
static

Definition at line 433 of file SDL_cpuinfo.c.

434 {
435  if (CPU_OSSavesZMM && (CPU_CPUIDMaxFunction >= 7)) {
436  int a, b, c, d;
437  (void) a; (void) b; (void) c; (void) d; /* compiler warnings... */
438  cpuid(7, a, b, c, d);
439  return (b & 0x00010000);
440  }
441  return 0;
442 }

References CPU_CPUIDMaxFunction, CPU_OSSavesZMM, cpuid, d, and void.

Referenced by SDL_GetCPUFeatures().

◆ CPU_haveCPUID()

static int CPU_haveCPUID ( void  )
static

Definition at line 113 of file SDL_cpuinfo.c.

114 {
115  int has_CPUID = 0;
116 
117 /* *INDENT-OFF* */
118 #ifndef SDL_CPUINFO_DISABLED
119 #if defined(__GNUC__) && defined(i386)
120  __asm__ (
121 " pushfl # Get original EFLAGS \n"
122 " popl %%eax \n"
123 " movl %%eax,%%ecx \n"
124 " xorl $0x200000,%%eax # Flip ID bit in EFLAGS \n"
125 " pushl %%eax # Save new EFLAGS value on stack \n"
126 " popfl # Replace current EFLAGS value \n"
127 " pushfl # Get new EFLAGS \n"
128 " popl %%eax # Store new EFLAGS in EAX \n"
129 " xorl %%ecx,%%eax # Can not toggle ID bit, \n"
130 " jz 1f # Processor=80486 \n"
131 " movl $1,%0 # We have CPUID support \n"
132 "1: \n"
133  : "=m" (has_CPUID)
134  :
135  : "%eax", "%ecx"
136  );
137 #elif defined(__GNUC__) && defined(__x86_64__)
138 /* Technically, if this is being compiled under __x86_64__ then it has
139  CPUid by definition. But it's nice to be able to prove it. :) */
140  __asm__ (
141 " pushfq # Get original EFLAGS \n"
142 " popq %%rax \n"
143 " movq %%rax,%%rcx \n"
144 " xorl $0x200000,%%eax # Flip ID bit in EFLAGS \n"
145 " pushq %%rax # Save new EFLAGS value on stack \n"
146 " popfq # Replace current EFLAGS value \n"
147 " pushfq # Get new EFLAGS \n"
148 " popq %%rax # Store new EFLAGS in EAX \n"
149 " xorl %%ecx,%%eax # Can not toggle ID bit, \n"
150 " jz 1f # Processor=80486 \n"
151 " movl $1,%0 # We have CPUID support \n"
152 "1: \n"
153  : "=m" (has_CPUID)
154  :
155  : "%rax", "%rcx"
156  );
157 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
158  __asm {
159  pushfd ; Get original EFLAGS
160  pop eax
161  mov ecx, eax
162  xor eax, 200000h ; Flip ID bit in EFLAGS
163  push eax ; Save new EFLAGS value on stack
164  popfd ; Replace current EFLAGS value
165  pushfd ; Get new EFLAGS
166  pop eax ; Store new EFLAGS in EAX
167  xor eax, ecx ; Can not toggle ID bit,
168  jz done ; Processor=80486
169  mov has_CPUID,1 ; We have CPUID support
170 done:
171  }
172 #elif defined(_MSC_VER) && defined(_M_X64)
173  has_CPUID = 1;
174 #elif defined(__sun) && defined(__i386)
175  __asm (
176 " pushfl \n"
177 " popl %eax \n"
178 " movl %eax,%ecx \n"
179 " xorl $0x200000,%eax \n"
180 " pushl %eax \n"
181 " popfl \n"
182 " pushfl \n"
183 " popl %eax \n"
184 " xorl %ecx,%eax \n"
185 " jz 1f \n"
186 " movl $1,-8(%ebp) \n"
187 "1: \n"
188  );
189 #elif defined(__sun) && defined(__amd64)
190  __asm (
191 " pushfq \n"
192 " popq %rax \n"
193 " movq %rax,%rcx \n"
194 " xorl $0x200000,%eax \n"
195 " pushq %rax \n"
196 " popfq \n"
197 " pushfq \n"
198 " popq %rax \n"
199 " xorl %ecx,%eax \n"
200 " jz 1f \n"
201 " movl $1,-8(%rbp) \n"
202 "1: \n"
203  );
204 #endif
205 #endif
206 /* *INDENT-ON* */
207  return has_CPUID;
208 }

References done, and pop.

Referenced by CPU_calcCPUIDFeatures().

◆ CPU_haveNEON()

static int CPU_haveNEON ( void  )
static

Definition at line 350 of file SDL_cpuinfo.c.

351 {
352 /* The way you detect NEON is a privileged instruction on ARM, so you have
353  query the OS kernel in a platform-specific way. :/ */
354 #if defined(SDL_CPUINFO_DISABLED)
355  return 0; /* disabled */
356 #elif (defined(__WINDOWS__) || defined(__WINRT__)) && (defined(_M_ARM) || defined(_M_ARM64))
357 /* Visual Studio, for ARM, doesn't define __ARM_ARCH. Handle this first. */
358 /* Seems to have been removed */
359 # if !defined(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE)
360 # define PF_ARM_NEON_INSTRUCTIONS_AVAILABLE 19
361 # endif
362 /* All WinRT ARM devices are required to support NEON, but just in case. */
363  return IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) != 0;
364 #elif !defined(__ARM_ARCH)
365  return 0; /* not an ARM CPU at all. */
366 #elif __ARM_ARCH >= 8
367  return 1; /* ARMv8 always has non-optional NEON support. */
368 #elif defined(__APPLE__) && (__ARM_ARCH >= 7)
369  /* (note that sysctlbyname("hw.optional.neon") doesn't work!) */
370  return 1; /* all Apple ARMv7 chips and later have NEON. */
371 #elif defined(__APPLE__)
372  return 0; /* assume anything else from Apple doesn't have NEON. */
373 #elif defined(__QNXNTO__)
374  return SYSPAGE_ENTRY(cpuinfo)->flags & ARM_CPU_FLAG_NEON;
375 #elif (defined(__LINUX__) || defined(__ANDROID__)) && defined(HAVE_GETAUXVAL)
376  return ((getauxval(AT_HWCAP) & HWCAP_NEON) == HWCAP_NEON);
377 #elif defined(__LINUX__)
378  return readProcAuxvForNeon();
379 #elif defined(__ANDROID__)
380  /* Use NDK cpufeatures to read either /proc/self/auxv or /proc/cpuinfo */
381  {
382  AndroidCpuFamily cpu_family = android_getCpuFamily();
383  if (cpu_family == ANDROID_CPU_FAMILY_ARM) {
384  uint64_t cpu_features = android_getCpuFeatures();
385  if ((cpu_features & ANDROID_CPU_ARM_FEATURE_NEON) != 0) {
386  return 1;
387  }
388  }
389  return 0;
390  }
391 #else
392 #warning SDL_HasNEON is not implemented for this ARM platform. Write me.
393  return 0;
394 #endif
395 }

Referenced by SDL_GetCPUFeatures().

◆ SDL_GetCPUCacheLineSize()

int SDL_GetCPUCacheLineSize ( void  )

This function returns the L1 cache line size of the CPU

This is useful for determining multi-threaded structure padding or SIMD prefetch sizes.

Definition at line 597 of file SDL_cpuinfo.c.

598 {
599  const char *cpuType = SDL_GetCPUType();
600  int a, b, c, d;
601  (void) a; (void) b; (void) c; (void) d;
602  if (SDL_strcmp(cpuType, "GenuineIntel") == 0) {
603  cpuid(0x00000001, a, b, c, d);
604  return (((b >> 8) & 0xff) * 8);
605  } else if (SDL_strcmp(cpuType, "AuthenticAMD") == 0) {
606  cpuid(0x80000005, a, b, c, d);
607  return (c & 0xff);
608  } else {
609  /* Just make a guess here... */
610  return SDL_CACHELINE_SIZE;
611  }
612 }

References cpuid, d, SDL_CACHELINE_SIZE, SDL_GetCPUType(), SDL_strcmp, and void.

◆ SDL_GetCPUCount()

int SDL_GetCPUCount ( void  )

This function returns the number of CPU cores available.

Definition at line 447 of file SDL_cpuinfo.c.

448 {
449  if (!SDL_CPUCount) {
450 #ifndef SDL_CPUINFO_DISABLED
451 #if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
452  if (SDL_CPUCount <= 0) {
453  SDL_CPUCount = (int)sysconf(_SC_NPROCESSORS_ONLN);
454  }
455 #endif
456 #ifdef HAVE_SYSCTLBYNAME
457  if (SDL_CPUCount <= 0) {
458  size_t size = sizeof(SDL_CPUCount);
459  sysctlbyname("hw.ncpu", &SDL_CPUCount, &size, NULL, 0);
460  }
461 #endif
462 #ifdef __WIN32__
463  if (SDL_CPUCount <= 0) {
464  SYSTEM_INFO info;
465  GetSystemInfo(&info);
466  SDL_CPUCount = info.dwNumberOfProcessors;
467  }
468 #endif
469 #ifdef __OS2__
470  if (SDL_CPUCount <= 0) {
471  DosQuerySysInfo(QSV_NUMPROCESSORS, QSV_NUMPROCESSORS,
472  &SDL_CPUCount, sizeof(SDL_CPUCount) );
473  }
474 #endif
475 #endif
476  /* There has to be at least 1, right? :) */
477  if (SDL_CPUCount <= 0) {
478  SDL_CPUCount = 1;
479  }
480  }
481  return SDL_CPUCount;
482 }

References NULL, and SDL_CPUCount.

◆ SDL_GetCPUFeatures()

static Uint32 SDL_GetCPUFeatures ( void  )
static

Definition at line 618 of file SDL_cpuinfo.c.

619 {
620  if (SDL_CPUFeatures == 0xFFFFFFFF) {
622  SDL_CPUFeatures = 0;
623  SDL_SIMDAlignment = 4; /* a good safe base value */
624  if (CPU_haveRDTSC()) {
626  }
627  if (CPU_haveAltiVec()) {
630  }
631  if (CPU_haveMMX()) {
634  }
635  if (CPU_have3DNow()) {
638  }
639  if (CPU_haveSSE()) {
642  }
643  if (CPU_haveSSE2()) {
646  }
647  if (CPU_haveSSE3()) {
650  }
651  if (CPU_haveSSE41()) {
654  }
655  if (CPU_haveSSE42()) {
658  }
659  if (CPU_haveAVX()) {
662  }
663  if (CPU_haveAVX2()) {
666  }
667  if (CPU_haveAVX512F()) {
670  }
671  if (CPU_haveNEON()) {
674  }
675  }
676  return SDL_CPUFeatures;
677 }

References CPU_calcCPUIDFeatures(), CPU_HAS_3DNOW, CPU_HAS_ALTIVEC, CPU_HAS_AVX, CPU_HAS_AVX2, CPU_HAS_AVX512F, CPU_HAS_MMX, CPU_HAS_NEON, CPU_HAS_RDTSC, CPU_HAS_SSE, CPU_HAS_SSE2, CPU_HAS_SSE3, CPU_HAS_SSE41, CPU_HAS_SSE42, CPU_have3DNow(), CPU_haveAltiVec(), CPU_haveAVX, CPU_haveAVX2(), CPU_haveAVX512F(), CPU_haveMMX, CPU_haveNEON(), CPU_haveRDTSC, CPU_haveSSE, CPU_haveSSE2, CPU_haveSSE3, CPU_haveSSE41, CPU_haveSSE42, SDL_CPUFeatures, SDL_max, and SDL_SIMDAlignment.

Referenced by SDL_SIMDGetAlignment().

◆ SDL_GetCPUType()

static const char* SDL_GetCPUType ( void  )
static

Definition at line 486 of file SDL_cpuinfo.c.

487 {
488  static char SDL_CPUType[13];
489 
490  if (!SDL_CPUType[0]) {
491  int i = 0;
492 
494  if (CPU_CPUIDMaxFunction > 0) { /* do we have CPUID at all? */
495  int a, b, c, d;
496  cpuid(0x00000000, a, b, c, d);
497  (void) a;
498  SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
499  SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
500  SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
501  SDL_CPUType[i++] = (char)(b & 0xff);
502 
503  SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
504  SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
505  SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
506  SDL_CPUType[i++] = (char)(d & 0xff);
507 
508  SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
509  SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
510  SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
511  SDL_CPUType[i++] = (char)(c & 0xff);
512  }
513  if (!SDL_CPUType[0]) {
514  SDL_strlcpy(SDL_CPUType, "Unknown", sizeof(SDL_CPUType));
515  }
516  }
517  return SDL_CPUType;
518 }

References CPU_calcCPUIDFeatures(), CPU_CPUIDMaxFunction, cpuid, d, i, SDL_strlcpy, and void.

Referenced by SDL_GetCPUCacheLineSize().

◆ SDL_GetSystemRAM()

int SDL_GetSystemRAM ( void  )

This function returns the amount of RAM configured in the system, in MB.

Definition at line 761 of file SDL_cpuinfo.c.

762 {
763  if (!SDL_SystemRAM) {
764 #ifndef SDL_CPUINFO_DISABLED
765 #if defined(HAVE_SYSCONF) && defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE)
766  if (SDL_SystemRAM <= 0) {
767  SDL_SystemRAM = (int)((Sint64)sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE) / (1024*1024));
768  }
769 #endif
770 #ifdef HAVE_SYSCTLBYNAME
771  if (SDL_SystemRAM <= 0) {
772 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
773 #ifdef HW_REALMEM
774  int mib[2] = {CTL_HW, HW_REALMEM};
775 #else
776  /* might only report up to 2 GiB */
777  int mib[2] = {CTL_HW, HW_PHYSMEM};
778 #endif /* HW_REALMEM */
779 #else
780  int mib[2] = {CTL_HW, HW_MEMSIZE};
781 #endif /* __FreeBSD__ || __FreeBSD_kernel__ */
782  Uint64 memsize = 0;
783  size_t len = sizeof(memsize);
784 
785  if (sysctl(mib, 2, &memsize, &len, NULL, 0) == 0) {
786  SDL_SystemRAM = (int)(memsize / (1024*1024));
787  }
788  }
789 #endif
790 #ifdef __WIN32__
791  if (SDL_SystemRAM <= 0) {
792  MEMORYSTATUSEX stat;
793  stat.dwLength = sizeof(stat);
794  if (GlobalMemoryStatusEx(&stat)) {
795  SDL_SystemRAM = (int)(stat.ullTotalPhys / (1024 * 1024));
796  }
797  }
798 #endif
799 #ifdef __OS2__
800  if (SDL_SystemRAM <= 0) {
801  Uint32 sysram = 0;
802  DosQuerySysInfo(QSV_TOTPHYSMEM, QSV_TOTPHYSMEM, &sysram, 4);
803  SDL_SystemRAM = (int) (sysram / 0x100000U);
804  }
805 #endif
806 #endif
807  }
808  return SDL_SystemRAM;
809 }

References NULL, and SDL_SystemRAM.

◆ SDL_Has3DNow()

SDL_bool SDL_Has3DNow ( void  )

This function returns true if the CPU has 3DNow! features.

Definition at line 699 of file SDL_cpuinfo.c.

700 {
702 }

References CPU_FEATURE_AVAILABLE, and CPU_HAS_3DNOW.

◆ SDL_HasAltiVec()

SDL_bool SDL_HasAltiVec ( void  )

This function returns true if the CPU has AltiVec features.

Definition at line 687 of file SDL_cpuinfo.c.

688 {
690 }

References CPU_FEATURE_AVAILABLE, and CPU_HAS_ALTIVEC.

◆ SDL_HasAVX()

SDL_bool SDL_HasAVX ( void  )

This function returns true if the CPU has AVX features.

Definition at line 735 of file SDL_cpuinfo.c.

736 {
738 }

References CPU_FEATURE_AVAILABLE, and CPU_HAS_AVX.

◆ SDL_HasAVX2()

SDL_bool SDL_HasAVX2 ( void  )

This function returns true if the CPU has AVX2 features.

Definition at line 741 of file SDL_cpuinfo.c.

742 {
744 }

References CPU_FEATURE_AVAILABLE, and CPU_HAS_AVX2.

◆ SDL_HasAVX512F()

SDL_bool SDL_HasAVX512F ( void  )

This function returns true if the CPU has AVX-512F (foundation) features.

Definition at line 747 of file SDL_cpuinfo.c.

748 {
750 }

References CPU_FEATURE_AVAILABLE, and CPU_HAS_AVX512F.

◆ SDL_HasMMX()

SDL_bool SDL_HasMMX ( void  )

This function returns true if the CPU has MMX features.

Definition at line 693 of file SDL_cpuinfo.c.

694 {
696 }

References CPU_FEATURE_AVAILABLE, and CPU_HAS_MMX.

◆ SDL_HasNEON()

SDL_bool SDL_HasNEON ( void  )

This function returns true if the CPU has NEON (ARM SIMD) features.

Definition at line 753 of file SDL_cpuinfo.c.

754 {
756 }

References CPU_FEATURE_AVAILABLE, and CPU_HAS_NEON.

◆ SDL_HasRDTSC()

SDL_bool SDL_HasRDTSC ( void  )

This function returns true if the CPU has the RDTSC instruction.

Definition at line 681 of file SDL_cpuinfo.c.

682 {
684 }

References CPU_FEATURE_AVAILABLE, and CPU_HAS_RDTSC.

◆ SDL_HasSSE()

SDL_bool SDL_HasSSE ( void  )

This function returns true if the CPU has SSE features.

Definition at line 705 of file SDL_cpuinfo.c.

706 {
708 }

References CPU_FEATURE_AVAILABLE, and CPU_HAS_SSE.

◆ SDL_HasSSE2()

SDL_bool SDL_HasSSE2 ( void  )

This function returns true if the CPU has SSE2 features.

Definition at line 711 of file SDL_cpuinfo.c.

712 {
714 }

References CPU_FEATURE_AVAILABLE, and CPU_HAS_SSE2.

◆ SDL_HasSSE3()

SDL_bool SDL_HasSSE3 ( void  )

This function returns true if the CPU has SSE3 features.

Definition at line 717 of file SDL_cpuinfo.c.

718 {
720 }

References CPU_FEATURE_AVAILABLE, and CPU_HAS_SSE3.

◆ SDL_HasSSE41()

SDL_bool SDL_HasSSE41 ( void  )

This function returns true if the CPU has SSE4.1 features.

Definition at line 723 of file SDL_cpuinfo.c.

724 {
726 }

References CPU_FEATURE_AVAILABLE, and CPU_HAS_SSE41.

◆ SDL_HasSSE42()

SDL_bool SDL_HasSSE42 ( void  )

This function returns true if the CPU has SSE4.2 features.

Definition at line 729 of file SDL_cpuinfo.c.

730 {
732 }

References CPU_FEATURE_AVAILABLE, and CPU_HAS_SSE42.

◆ SDL_SIMDAlloc()

void* SDL_SIMDAlloc ( const size_t  len)

Allocate memory in a SIMD-friendly way.

This will allocate a block of memory that is suitable for use with SIMD instructions. Specifically, it will be properly aligned and padded for the system's supported vector instructions.

The memory returned will be padded such that it is safe to read or write an incomplete vector at the end of the memory block. This can be useful so you don't have to drop back to a scalar fallback at the end of your SIMD processing loop to deal with the final elements without overflowing the allocated buffer.

You must free this memory with SDL_FreeSIMD(), not free() or SDL_free() or delete[], etc.

Note that SDL will only deal with SIMD instruction sets it is aware of; for example, SDL 2.0.8 knows that SSE wants 16-byte vectors (SDL_HasSSE()), and AVX2 wants 32 bytes (SDL_HasAVX2()), but doesn't know that AVX-512 wants 64. To be clear: if you can't decide to use an instruction set with an SDL_Has*() function, don't use that instruction set with memory allocated through here.

SDL_AllocSIMD(0) will return a non-NULL pointer, assuming the system isn't out of memory.

Parameters
lenThe length, in bytes, of the block to allocated. The actual allocated block might be larger due to padding, etc.
Returns
Pointer to newly-allocated block, NULL if out of memory.
See also
SDL_SIMDAlignment
SDL_SIMDFree

Definition at line 823 of file SDL_cpuinfo.c.

824 {
825  const size_t alignment = SDL_SIMDGetAlignment();
826  const size_t padding = alignment - (len % alignment);
827  const size_t padded = (padding != alignment) ? (len + padding) : len;
828  Uint8 *retval = NULL;
829  Uint8 *ptr = (Uint8 *) SDL_malloc(padded + alignment + sizeof (void *));
830  if (ptr) {
831  /* store the actual malloc pointer right before our aligned pointer. */
832  retval = ptr + sizeof (void *);
833  retval += alignment - (((size_t) retval) % alignment);
834  *(((void **) retval) - 1) = ptr;
835  }
836  return retval;
837 }

References NULL, retval, SDL_malloc, and SDL_SIMDGetAlignment().

◆ SDL_SIMDFree()

void SDL_SIMDFree ( void ptr)

Deallocate memory obtained from SDL_SIMDAlloc.

It is not valid to use this function on a pointer from anything but SDL_SIMDAlloc(). It can't be used on pointers from malloc, realloc, SDL_malloc, memalign, new[], etc.

However, SDL_SIMDFree(NULL) is a legal no-op.

See also
SDL_SIMDAlloc

Definition at line 840 of file SDL_cpuinfo.c.

841 {
842  if (ptr) {
843  void **realptr = (void **) ptr;
844  realptr--;
845  SDL_free(*(((void **) ptr) - 1));
846  }
847 }

References SDL_free.

◆ SDL_SIMDGetAlignment()

size_t SDL_SIMDGetAlignment ( void  )

Report the alignment this system needs for SIMD allocations.

This will return the minimum number of bytes to which a pointer must be aligned to be compatible with SIMD instructions on the current machine. For example, if the machine supports SSE only, it will return 16, but if it supports AVX-512F, it'll return 64 (etc). This only reports values for instruction sets SDL knows about, so if your SDL build doesn't have SDL_HasAVX512F(), then it might return 16 for the SSE support it sees and not 64 for the AVX-512 instructions that exist but SDL doesn't know about. Plan accordingly.

Definition at line 813 of file SDL_cpuinfo.c.

814 {
815  if (SDL_SIMDAlignment == 0xFFFFFFFF) {
816  SDL_GetCPUFeatures(); /* make sure this has been calculated */
817  }
819  return SDL_SIMDAlignment;
820 }

References SDL_assert, SDL_GetCPUFeatures(), and SDL_SIMDAlignment.

Referenced by SDL_SIMDAlloc().

Variable Documentation

◆ CPU_CPUIDFeatures

int CPU_CPUIDFeatures[4]
static

Definition at line 254 of file SDL_cpuinfo.c.

Referenced by CPU_calcCPUIDFeatures().

◆ CPU_CPUIDMaxFunction

int CPU_CPUIDMaxFunction = 0
static

◆ CPU_OSSavesYMM

SDL_bool CPU_OSSavesYMM = SDL_FALSE
static

Definition at line 256 of file SDL_cpuinfo.c.

Referenced by CPU_calcCPUIDFeatures(), and CPU_haveAVX2().

◆ CPU_OSSavesZMM

SDL_bool CPU_OSSavesZMM = SDL_FALSE
static

Definition at line 257 of file SDL_cpuinfo.c.

Referenced by CPU_calcCPUIDFeatures(), and CPU_haveAVX512F().

◆ SDL_CPUCount

int SDL_CPUCount = 0
static

Definition at line 444 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUCount().

◆ SDL_CPUFeatures

Uint32 SDL_CPUFeatures = 0xFFFFFFFF
static

Definition at line 614 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures().

◆ SDL_SIMDAlignment

Uint32 SDL_SIMDAlignment = 0xFFFFFFFF
static

Definition at line 615 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures(), and SDL_SIMDGetAlignment().

◆ SDL_SystemRAM

int SDL_SystemRAM = 0
static

Definition at line 758 of file SDL_cpuinfo.c.

Referenced by SDL_GetSystemRAM().

CPU_haveMMX
#define CPU_haveMMX()
Definition: SDL_cpuinfo.c:412
c
const GLubyte * c
Definition: SDL_opengl_glext.h:11093
SDL_CACHELINE_SIZE
#define SDL_CACHELINE_SIZE
Definition: SDL_cpuinfo.h:114
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
CPU_OSSavesZMM
static SDL_bool CPU_OSSavesZMM
Definition: SDL_cpuinfo.c:257
CPU_haveAltiVec
static int CPU_haveAltiVec(void)
Definition: SDL_cpuinfo.c:300
SDL_GetCPUType
static const char * SDL_GetCPUType(void)
Definition: SDL_cpuinfo.c:486
SDL_strlcpy
#define SDL_strlcpy
Definition: SDL_dynapi_overrides.h:394
Sint64
int64_t Sint64
Definition: SDL_stdinc.h:210
SDL_CPUFeatures
static Uint32 SDL_CPUFeatures
Definition: SDL_cpuinfo.c:614
SDL_GetCPUFeatures
static Uint32 SDL_GetCPUFeatures(void)
Definition: SDL_cpuinfo.c:618
CPU_HAS_SSE
#define CPU_HAS_SSE
Definition: SDL_cpuinfo.c:90
in
GLuint in
Definition: SDL_opengl_glext.h:7940
NULL
#define NULL
Definition: begin_code.h:167
b
GLboolean GLboolean GLboolean b
Definition: SDL_opengl_glext.h:1109
CPU_haveAVX
#define CPU_haveAVX()
Definition: SDL_cpuinfo.c:418
CPU_HAS_SSE41
#define CPU_HAS_SSE41
Definition: SDL_cpuinfo.c:93
CPU_HAS_AVX2
#define CPU_HAS_AVX2
Definition: SDL_cpuinfo.c:96
CPU_HAS_ALTIVEC
#define CPU_HAS_ALTIVEC
Definition: SDL_cpuinfo.c:87
SDL_SystemRAM
static int SDL_SystemRAM
Definition: SDL_cpuinfo.c:758
CPU_haveCPUID
static int CPU_haveCPUID(void)
Definition: SDL_cpuinfo.c:113
CPU_HAS_3DNOW
#define CPU_HAS_3DNOW
Definition: SDL_cpuinfo.c:89
CPU_FEATURE_AVAILABLE
#define CPU_FEATURE_AVAILABLE(f)
Definition: SDL_cpuinfo.c:679
a
GLboolean GLboolean GLboolean GLboolean a
Definition: SDL_opengl_glext.h:1109
h
GLfloat GLfloat GLfloat GLfloat h
Definition: SDL_opengl_glext.h:1946
length
GLuint GLsizei GLsizei * length
Definition: SDL_opengl_glext.h:669
CPU_HAS_NEON
#define CPU_HAS_NEON
Definition: SDL_cpuinfo.c:97
CPU_HAS_SSE42
#define CPU_HAS_SSE42
Definition: SDL_cpuinfo.c:94
SDL_SIMDAlignment
static Uint32 SDL_SIMDAlignment
Definition: SDL_cpuinfo.c:615
CPU_haveSSE
#define CPU_haveSSE()
Definition: SDL_cpuinfo.c:413
len
GLenum GLsizei len
Definition: SDL_opengl_glext.h:2926
SDL_FALSE
@ SDL_FALSE
Definition: SDL_stdinc.h:163
done
int done
Definition: checkkeys.c:28
retval
SDL_bool retval
Definition: testgamecontroller.c:65
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
SDL_max
#define SDL_max(x, y)
Definition: SDL_stdinc.h:407
CPU_HAS_SSE2
#define CPU_HAS_SSE2
Definition: SDL_cpuinfo.c:91
CPU_haveSSE41
#define CPU_haveSSE41()
Definition: SDL_cpuinfo.c:416
CPU_HAS_RDTSC
#define CPU_HAS_RDTSC
Definition: SDL_cpuinfo.c:86
CPU_HAS_AVX512F
#define CPU_HAS_AVX512F
Definition: SDL_cpuinfo.c:98
CPU_haveNEON
static int CPU_haveNEON(void)
Definition: SDL_cpuinfo.c:350
SDL_SIMDGetAlignment
size_t SDL_SIMDGetAlignment(void)
Report the alignment this system needs for SIMD allocations.
Definition: SDL_cpuinfo.c:813
pop
#define pop
Definition: SDL_qsort.c:192
CPU_HAS_MMX
#define CPU_HAS_MMX
Definition: SDL_cpuinfo.c:88
SDL_assert
#define SDL_assert(condition)
Definition: SDL_assert.h:169
CPU_calcCPUIDFeatures
static void CPU_calcCPUIDFeatures(void)
Definition: SDL_cpuinfo.c:260
size
GLsizeiptr size
Definition: SDL_opengl_glext.h:537
CPU_haveSSE2
#define CPU_haveSSE2()
Definition: SDL_cpuinfo.c:414
SDL_TRUE
@ SDL_TRUE
Definition: SDL_stdinc.h:164
value
GLsizei const GLfloat * value
Definition: SDL_opengl_glext.h:698
CPU_CPUIDFeatures
static int CPU_CPUIDFeatures[4]
Definition: SDL_cpuinfo.c:254
Uint64
uint64_t Uint64
Definition: SDL_stdinc.h:216
CPU_haveSSE42
#define CPU_haveSSE42()
Definition: SDL_cpuinfo.c:417
CPU_OSSavesYMM
static SDL_bool CPU_OSSavesYMM
Definition: SDL_cpuinfo.c:256
CPU_HAS_SSE3
#define CPU_HAS_SSE3
Definition: SDL_cpuinfo.c:92
CPU_have3DNow
static int CPU_have3DNow(void)
Definition: SDL_cpuinfo.c:398
size_t
unsigned int size_t
Definition: SDL_config_windows.h:68
cpuid
#define cpuid(func, a, b, c, d)
Definition: SDL_cpuinfo.c:250
CPU_haveAVX512F
static int CPU_haveAVX512F(void)
Definition: SDL_cpuinfo.c:433
CPU_HAS_AVX
#define CPU_HAS_AVX
Definition: SDL_cpuinfo.c:95
SDL_malloc
#define SDL_malloc
Definition: SDL_dynapi_overrides.h:374
SDL_strcmp
#define SDL_strcmp
Definition: SDL_dynapi_overrides.h:417
void
const SDL_PRINTF_FORMAT_STRING char int const SDL_PRINTF_FORMAT_STRING char int const SDL_PRINTF_FORMAT_STRING char int const SDL_PRINTF_FORMAT_STRING char const char const SDL_SCANF_FORMAT_STRING char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
Definition: SDL_dynapi_procs.h:89
CPU_haveAVX2
static int CPU_haveAVX2(void)
Definition: SDL_cpuinfo.c:421
uint64_t
unsigned long long uint64_t
Definition: SDL_config_windows.h:65
i
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)
Definition: SDL_x11sym.h:50
CPU_CPUIDMaxFunction
static int CPU_CPUIDMaxFunction
Definition: SDL_cpuinfo.c:255
CPU_haveSSE3
#define CPU_haveSSE3()
Definition: SDL_cpuinfo.c:415
d
const SDL_PRINTF_FORMAT_STRING char int const SDL_PRINTF_FORMAT_STRING char int const SDL_PRINTF_FORMAT_STRING char int const SDL_PRINTF_FORMAT_STRING char const char const SDL_SCANF_FORMAT_STRING 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
Definition: SDL_dynapi_procs.h:117
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:161
SDL_CPUCount
static int SDL_CPUCount
Definition: SDL_cpuinfo.c:444
CPU_haveRDTSC
#define CPU_haveRDTSC()
Definition: SDL_cpuinfo.c:411
Uint8
uint8_t Uint8
Definition: SDL_stdinc.h:179