SDL  2.0
SDL_cpuinfo.c File Reference
#include "../SDL_internal.h"
#include "SDL_simd.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.
voidSDL_SIMDAlloc (const size_t len)
 Allocate memory in a SIMD-friendly way.
void SDL_SIMDFree (void *ptr)
 Deallocate memory obtained from SDL_SIMDAlloc.

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

#define CPU_HAS_3DNOW   (1 << 3)

Definition at line 84 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures(), and SDL_Has3DNow().

#define CPU_HAS_ALTIVEC   (1 << 1)

Definition at line 82 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures(), and SDL_HasAltiVec().

#define CPU_HAS_AVX   (1 << 9)

Definition at line 90 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures(), and SDL_HasAVX().

#define CPU_HAS_AVX2   (1 << 10)

Definition at line 91 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures(), and SDL_HasAVX2().

#define CPU_HAS_AVX512F   (1 << 12)

Definition at line 93 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures(), and SDL_HasAVX512F().

#define CPU_HAS_MMX   (1 << 2)

Definition at line 83 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures(), and SDL_HasMMX().

#define CPU_HAS_NEON   (1 << 11)

Definition at line 92 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures(), and SDL_HasNEON().

#define CPU_HAS_RDTSC   (1 << 0)

Definition at line 81 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures(), and SDL_HasRDTSC().

#define CPU_HAS_SSE   (1 << 4)

Definition at line 85 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures(), and SDL_HasSSE().

#define CPU_HAS_SSE2   (1 << 5)

Definition at line 86 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures(), and SDL_HasSSE2().

#define CPU_HAS_SSE3   (1 << 6)

Definition at line 87 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures(), and SDL_HasSSE3().

#define CPU_HAS_SSE41   (1 << 7)

Definition at line 88 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures(), and SDL_HasSSE41().

#define CPU_HAS_SSE42   (1 << 8)

Definition at line 89 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures(), and SDL_HasSSE42().

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

Definition at line 394 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures().

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

Definition at line 388 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures().

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

Definition at line 387 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures().

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

Definition at line 389 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures().

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

Definition at line 390 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures().

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

Definition at line 391 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures().

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

Definition at line 392 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures().

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

Definition at line 393 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures().

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

Function Documentation

static void CPU_calcCPUIDFeatures ( void  )
static

Definition at line 255 of file SDL_cpuinfo.c.

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().

{
static SDL_bool checked = SDL_FALSE;
if (!checked) {
checked = SDL_TRUE;
if (CPU_haveCPUID()) {
int a, b, c, d;
cpuid(0, a, b, c, d);
cpuid(1, a, b, c, d);
/* Check to make sure we can call xgetbv */
if (c & 0x08000000) {
/* Call xgetbv to see if YMM (etc) register state is saved */
#if defined(__GNUC__) && (defined(i386) || defined(__x86_64__))
__asm__(".byte 0x0f, 0x01, 0xd0" : "=a" (a) : "c" (0) : "%edx");
#elif defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) && (_MSC_FULL_VER >= 160040219) /* VS2010 SP1 */
a = (int)_xgetbv(0);
#elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
__asm
{
xor ecx, ecx
_asm _emit 0x0f _asm _emit 0x01 _asm _emit 0xd0
mov a, eax
}
#endif
CPU_OSSavesYMM = ((a & 6) == 6) ? SDL_TRUE : SDL_FALSE;
CPU_OSSavesZMM = (CPU_OSSavesYMM && ((a & 0xe0) == 0xe0)) ? SDL_TRUE : SDL_FALSE;
}
}
}
}
}
static int CPU_have3DNow ( void  )
static

Definition at line 374 of file SDL_cpuinfo.c.

References CPU_CPUIDMaxFunction, cpuid, and d.

Referenced by SDL_GetCPUFeatures().

{
if (CPU_CPUIDMaxFunction > 0) { /* that is, do we have CPUID at all? */
int a, b, c, d;
cpuid(0x80000000, a, b, c, d);
if (a >= 0x80000001) {
cpuid(0x80000001, a, b, c, d);
return (d & 0x80000000);
}
}
return 0;
}
static int CPU_haveAltiVec ( void  )
static

Definition at line 295 of file SDL_cpuinfo.c.

References NULL, and void.

Referenced by SDL_GetCPUFeatures().

{
volatile int altivec = 0;
#ifndef SDL_CPUINFO_DISABLED
#if (defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__))) || (defined(__OpenBSD__) && defined(__powerpc__))
#ifdef __OpenBSD__
int selectors[2] = { CTL_MACHDEP, CPU_ALTIVEC };
#else
int selectors[2] = { CTL_HW, HW_VECTORUNIT };
#endif
int hasVectorUnit = 0;
size_t length = sizeof(hasVectorUnit);
int error = sysctl(selectors, 2, &hasVectorUnit, &length, NULL, 0);
if (0 == error)
altivec = (hasVectorUnit != 0);
#elif SDL_ALTIVEC_BLITTERS && HAVE_SETJMP
void (*handler) (int sig);
handler = signal(SIGILL, illegal_instruction);
if (setjmp(jmpbuf) == 0) {
asm volatile ("mtspr 256, %0\n\t" "vand %%v0, %%v0, %%v0"::"r" (-1));
altivec = 1;
}
signal(SIGILL, handler);
#endif
#endif
return altivec;
}
static int CPU_haveAVX2 ( void  )
static

Definition at line 397 of file SDL_cpuinfo.c.

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

Referenced by SDL_GetCPUFeatures().

{
int a, b, c, d;
(void) a; (void) b; (void) c; (void) d; /* compiler warnings... */
cpuid(7, a, b, c, d);
return (b & 0x00000020);
}
return 0;
}
static int CPU_haveAVX512F ( void  )
static

Definition at line 409 of file SDL_cpuinfo.c.

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

Referenced by SDL_GetCPUFeatures().

{
int a, b, c, d;
(void) a; (void) b; (void) c; (void) d; /* compiler warnings... */
cpuid(7, a, b, c, d);
return (b & 0x00010000);
}
return 0;
}
static int CPU_haveCPUID ( void  )
static

Definition at line 108 of file SDL_cpuinfo.c.

References done, and pop.

Referenced by CPU_calcCPUIDFeatures().

{
int has_CPUID = 0;
/* *INDENT-OFF* */
#ifndef SDL_CPUINFO_DISABLED
#if defined(__GNUC__) && defined(i386)
__asm__ (
" pushfl # Get original EFLAGS \n"
" popl %%eax \n"
" movl %%eax,%%ecx \n"
" xorl $0x200000,%%eax # Flip ID bit in EFLAGS \n"
" pushl %%eax # Save new EFLAGS value on stack \n"
" popfl # Replace current EFLAGS value \n"
" pushfl # Get new EFLAGS \n"
" popl %%eax # Store new EFLAGS in EAX \n"
" xorl %%ecx,%%eax # Can not toggle ID bit, \n"
" jz 1f # Processor=80486 \n"
" movl $1,%0 # We have CPUID support \n"
"1: \n"
: "=m" (has_CPUID)
:
: "%eax", "%ecx"
);
#elif defined(__GNUC__) && defined(__x86_64__)
/* Technically, if this is being compiled under __x86_64__ then it has
CPUid by definition. But it's nice to be able to prove it. :) */
__asm__ (
" pushfq # Get original EFLAGS \n"
" popq %%rax \n"
" movq %%rax,%%rcx \n"
" xorl $0x200000,%%eax # Flip ID bit in EFLAGS \n"
" pushq %%rax # Save new EFLAGS value on stack \n"
" popfq # Replace current EFLAGS value \n"
" pushfq # Get new EFLAGS \n"
" popq %%rax # Store new EFLAGS in EAX \n"
" xorl %%ecx,%%eax # Can not toggle ID bit, \n"
" jz 1f # Processor=80486 \n"
" movl $1,%0 # We have CPUID support \n"
"1: \n"
: "=m" (has_CPUID)
:
: "%rax", "%rcx"
);
#elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
__asm {
pushfd ; Get original EFLAGS
pop eax
mov ecx, eax
xor eax, 200000h ; Flip ID bit in EFLAGS
push eax ; Save new EFLAGS value on stack
popfd ; Replace current EFLAGS value
pushfd ; Get new EFLAGS
pop eax ; Store new EFLAGS in EAX
xor eax, ecx ; Can not toggle ID bit,
jz done ; Processor=80486
mov has_CPUID,1 ; We have CPUID support
done:
}
#elif defined(_MSC_VER) && defined(_M_X64)
has_CPUID = 1;
#elif defined(__sun) && defined(__i386)
__asm (
" pushfl \n"
" popl %eax \n"
" movl %eax,%ecx \n"
" xorl $0x200000,%eax \n"
" pushl %eax \n"
" popfl \n"
" pushfl \n"
" popl %eax \n"
" xorl %ecx,%eax \n"
" jz 1f \n"
" movl $1,-8(%ebp) \n"
"1: \n"
);
#elif defined(__sun) && defined(__amd64)
__asm (
" pushfq \n"
" popq %rax \n"
" movq %rax,%rcx \n"
" xorl $0x200000,%eax \n"
" pushq %rax \n"
" popfq \n"
" pushfq \n"
" popq %rax \n"
" xorl %ecx,%eax \n"
" jz 1f \n"
" movl $1,-8(%rbp) \n"
"1: \n"
);
#endif
#endif
/* *INDENT-ON* */
return has_CPUID;
}
static int CPU_haveNEON ( void  )
static

Definition at line 345 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures().

{
/* The way you detect NEON is a privileged instruction on ARM, so you have
query the OS kernel in a platform-specific way. :/ */
#if defined(SDL_CPUINFO_DISABLED) || !defined(__ARM_ARCH)
return 0; /* disabled or not an ARM CPU at all. */
#elif __ARM_ARCH >= 8
return 1; /* ARMv8 always has non-optional NEON support. */
#elif defined(__APPLE__) && (__ARM_ARCH >= 7)
/* (note that sysctlbyname("hw.optional.neon") doesn't work!) */
return 1; /* all Apple ARMv7 chips and later have NEON. */
#elif defined(__APPLE__)
return 0; /* assume anything else from Apple doesn't have NEON. */
#elif defined(__QNXNTO__)
return SYSPAGE_ENTRY(cpuinfo)->flags & ARM_CPU_FLAG_NEON;
#elif (defined(__LINUX__) || defined(__ANDROID__)) && defined(HAVE_GETAUXVAL)
return ((getauxval(AT_HWCAP) & HWCAP_NEON) == HWCAP_NEON);
#elif (defined(__LINUX__) || defined(__ANDROID__))
return readProcAuxvForNeon(); /* Android offers a static library for this, but it just parses /proc/self/auxv */
#elif (defined(__WINDOWS__) || defined(__WINRT__)) && defined(_M_ARM)
/* All WinRT ARM devices are required to support NEON, but just in case. */
return IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE) != 0;
#else
#warning SDL_HasNEON is not implemented for this ARM platform. Write me.
return 0;
#endif
}
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 573 of file SDL_cpuinfo.c.

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

{
const char *cpuType = SDL_GetCPUType();
int a, b, c, d;
(void) a; (void) b; (void) c; (void) d;
if (SDL_strcmp(cpuType, "GenuineIntel") == 0) {
cpuid(0x00000001, a, b, c, d);
return (((b >> 8) & 0xff) * 8);
} else if (SDL_strcmp(cpuType, "AuthenticAMD") == 0) {
cpuid(0x80000005, a, b, c, d);
return (c & 0xff);
} else {
/* Just make a guess here... */
}
}
int SDL_GetCPUCount ( void  )

This function returns the number of CPU cores available.

Definition at line 423 of file SDL_cpuinfo.c.

References NULL, and SDL_CPUCount.

{
if (!SDL_CPUCount) {
#ifndef SDL_CPUINFO_DISABLED
#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
if (SDL_CPUCount <= 0) {
SDL_CPUCount = (int)sysconf(_SC_NPROCESSORS_ONLN);
}
#endif
#ifdef HAVE_SYSCTLBYNAME
if (SDL_CPUCount <= 0) {
size_t size = sizeof(SDL_CPUCount);
sysctlbyname("hw.ncpu", &SDL_CPUCount, &size, NULL, 0);
}
#endif
#ifdef __WIN32__
if (SDL_CPUCount <= 0) {
SYSTEM_INFO info;
GetSystemInfo(&info);
SDL_CPUCount = info.dwNumberOfProcessors;
}
#endif
#ifdef __OS2__
if (SDL_CPUCount <= 0) {
DosQuerySysInfo(QSV_NUMPROCESSORS, QSV_NUMPROCESSORS,
}
#endif
#endif
/* There has to be at least 1, right? :) */
if (SDL_CPUCount <= 0) {
}
}
return SDL_CPUCount;
}
static Uint32 SDL_GetCPUFeatures ( void  )
static

Definition at line 594 of file SDL_cpuinfo.c.

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, and SDL_max.

Referenced by SDL_SIMDGetAlignment().

{
if (SDL_CPUFeatures == 0xFFFFFFFF) {
SDL_SIMDAlignment = 4; /* a good safe base value */
if (CPU_haveRDTSC()) {
}
if (CPU_haveAltiVec()) {
}
if (CPU_haveMMX()) {
}
if (CPU_have3DNow()) {
}
if (CPU_haveSSE()) {
}
if (CPU_haveSSE2()) {
}
if (CPU_haveSSE3()) {
}
if (CPU_haveSSE41()) {
}
if (CPU_haveSSE42()) {
}
if (CPU_haveAVX()) {
}
if (CPU_haveAVX2()) {
}
if (CPU_haveAVX512F()) {
}
if (CPU_haveNEON()) {
}
}
}
static const char* SDL_GetCPUType ( void  )
static

Definition at line 462 of file SDL_cpuinfo.c.

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

Referenced by SDL_GetCPUCacheLineSize().

{
static char SDL_CPUType[13];
if (!SDL_CPUType[0]) {
int i = 0;
if (CPU_CPUIDMaxFunction > 0) { /* do we have CPUID at all? */
int a, b, c, d;
cpuid(0x00000000, a, b, c, d);
(void) a;
SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUType[i++] = (char)(b & 0xff); b >>= 8;
SDL_CPUType[i++] = (char)(b & 0xff);
SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
SDL_CPUType[i++] = (char)(d & 0xff); d >>= 8;
SDL_CPUType[i++] = (char)(d & 0xff);
SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUType[i++] = (char)(c & 0xff); c >>= 8;
SDL_CPUType[i++] = (char)(c & 0xff);
}
if (!SDL_CPUType[0]) {
SDL_strlcpy(SDL_CPUType, "Unknown", sizeof(SDL_CPUType));
}
}
return SDL_CPUType;
}
int SDL_GetSystemRAM ( void  )

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

Definition at line 737 of file SDL_cpuinfo.c.

References NULL, and SDL_SystemRAM.

{
if (!SDL_SystemRAM) {
#ifndef SDL_CPUINFO_DISABLED
#if defined(HAVE_SYSCONF) && defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE)
if (SDL_SystemRAM <= 0) {
SDL_SystemRAM = (int)((Sint64)sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE) / (1024*1024));
}
#endif
#ifdef HAVE_SYSCTLBYNAME
if (SDL_SystemRAM <= 0) {
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
#ifdef HW_REALMEM
int mib[2] = {CTL_HW, HW_REALMEM};
#else
/* might only report up to 2 GiB */
int mib[2] = {CTL_HW, HW_PHYSMEM};
#endif /* HW_REALMEM */
#else
int mib[2] = {CTL_HW, HW_MEMSIZE};
#endif /* __FreeBSD__ || __FreeBSD_kernel__ */
Uint64 memsize = 0;
size_t len = sizeof(memsize);
if (sysctl(mib, 2, &memsize, &len, NULL, 0) == 0) {
SDL_SystemRAM = (int)(memsize / (1024*1024));
}
}
#endif
#ifdef __WIN32__
if (SDL_SystemRAM <= 0) {
MEMORYSTATUSEX stat;
stat.dwLength = sizeof(stat);
if (GlobalMemoryStatusEx(&stat)) {
SDL_SystemRAM = (int)(stat.ullTotalPhys / (1024 * 1024));
}
}
#endif
#ifdef __OS2__
if (SDL_SystemRAM <= 0) {
Uint32 sysram = 0;
DosQuerySysInfo(QSV_TOTPHYSMEM, QSV_TOTPHYSMEM, &sysram, 4);
SDL_SystemRAM = (int) (sysram / 0x100000U);
}
#endif
#endif
}
return SDL_SystemRAM;
}
SDL_bool SDL_Has3DNow ( void  )

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

Definition at line 675 of file SDL_cpuinfo.c.

References CPU_FEATURE_AVAILABLE, and CPU_HAS_3DNOW.

SDL_bool SDL_HasAltiVec ( void  )

This function returns true if the CPU has AltiVec features.

Definition at line 663 of file SDL_cpuinfo.c.

References CPU_FEATURE_AVAILABLE, and CPU_HAS_ALTIVEC.

SDL_bool SDL_HasAVX ( void  )

This function returns true if the CPU has AVX features.

Definition at line 711 of file SDL_cpuinfo.c.

References CPU_FEATURE_AVAILABLE, and CPU_HAS_AVX.

SDL_bool SDL_HasAVX2 ( void  )

This function returns true if the CPU has AVX2 features.

Definition at line 717 of file SDL_cpuinfo.c.

References CPU_FEATURE_AVAILABLE, and CPU_HAS_AVX2.

SDL_bool SDL_HasAVX512F ( void  )

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

Definition at line 723 of file SDL_cpuinfo.c.

References CPU_FEATURE_AVAILABLE, and CPU_HAS_AVX512F.

SDL_bool SDL_HasMMX ( void  )

This function returns true if the CPU has MMX features.

Definition at line 669 of file SDL_cpuinfo.c.

References CPU_FEATURE_AVAILABLE, and CPU_HAS_MMX.

SDL_bool SDL_HasNEON ( void  )

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

Definition at line 729 of file SDL_cpuinfo.c.

References CPU_FEATURE_AVAILABLE, and CPU_HAS_NEON.

SDL_bool SDL_HasRDTSC ( void  )

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

Definition at line 657 of file SDL_cpuinfo.c.

References CPU_FEATURE_AVAILABLE, and CPU_HAS_RDTSC.

SDL_bool SDL_HasSSE ( void  )

This function returns true if the CPU has SSE features.

Definition at line 681 of file SDL_cpuinfo.c.

References CPU_FEATURE_AVAILABLE, and CPU_HAS_SSE.

SDL_bool SDL_HasSSE2 ( void  )

This function returns true if the CPU has SSE2 features.

Definition at line 687 of file SDL_cpuinfo.c.

References CPU_FEATURE_AVAILABLE, and CPU_HAS_SSE2.

SDL_bool SDL_HasSSE3 ( void  )

This function returns true if the CPU has SSE3 features.

Definition at line 693 of file SDL_cpuinfo.c.

References CPU_FEATURE_AVAILABLE, and CPU_HAS_SSE3.

SDL_bool SDL_HasSSE41 ( void  )

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

Definition at line 699 of file SDL_cpuinfo.c.

References CPU_FEATURE_AVAILABLE, and CPU_HAS_SSE41.

SDL_bool SDL_HasSSE42 ( void  )

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

Definition at line 705 of file SDL_cpuinfo.c.

References CPU_FEATURE_AVAILABLE, and CPU_HAS_SSE42.

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 799 of file SDL_cpuinfo.c.

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

{
const size_t alignment = SDL_SIMDGetAlignment();
const size_t padding = alignment - (len % alignment);
const size_t padded = (padding != alignment) ? (len + padding) : len;
Uint8 *ptr = (Uint8 *) SDL_malloc(padded + alignment + sizeof (void *));
if (ptr) {
/* store the actual malloc pointer right before our aligned pointer. */
retval = ptr + sizeof (void *);
retval += alignment - (((size_t) retval) % alignment);
*(((void **) retval) - 1) = ptr;
}
return retval;
}
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 816 of file SDL_cpuinfo.c.

References SDL_free.

{
if (ptr) {
void **realptr = (void **) ptr;
realptr--;
SDL_free(*(((void **) ptr) - 1));
}
}
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 789 of file SDL_cpuinfo.c.

References SDL_assert, SDL_GetCPUFeatures(), and SDL_SIMDAlignment.

Referenced by SDL_SIMDAlloc().

{
if (SDL_SIMDAlignment == 0xFFFFFFFF) {
SDL_GetCPUFeatures(); /* make sure this has been calculated */
}
}

Variable Documentation

int CPU_CPUIDFeatures[4]
static

Definition at line 249 of file SDL_cpuinfo.c.

Referenced by CPU_calcCPUIDFeatures().

int CPU_CPUIDMaxFunction = 0
static
SDL_bool CPU_OSSavesYMM = SDL_FALSE
static

Definition at line 251 of file SDL_cpuinfo.c.

Referenced by CPU_calcCPUIDFeatures(), and CPU_haveAVX2().

SDL_bool CPU_OSSavesZMM = SDL_FALSE
static

Definition at line 252 of file SDL_cpuinfo.c.

Referenced by CPU_calcCPUIDFeatures(), and CPU_haveAVX512F().

int SDL_CPUCount = 0
static

Definition at line 420 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUCount().

Uint32 SDL_CPUFeatures = 0xFFFFFFFF
static

Definition at line 590 of file SDL_cpuinfo.c.

Referenced by SDL_GetCPUFeatures().

Uint32 SDL_SIMDAlignment = 0xFFFFFFFF
static

Definition at line 591 of file SDL_cpuinfo.c.

Referenced by SDL_SIMDGetAlignment().

int SDL_SystemRAM = 0
static

Definition at line 734 of file SDL_cpuinfo.c.

Referenced by SDL_GetSystemRAM().