Mercurial > sdl-ios-xcode
changeset 785:ca06a994f03c
Fixed bugs in CPU feature detection and added extended feature detection
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 24 Jan 2004 05:47:19 +0000 |
parents | a2dde6aff60e |
children | e1e0a0a94570 |
files | include/SDL_cpuinfo.h src/cpuinfo/SDL_cpuinfo.c test/testcpuinfo.c |
diffstat | 3 files changed, 120 insertions(+), 51 deletions(-) [+] |
line wrap: on
line diff
--- a/include/SDL_cpuinfo.h Sat Jan 17 20:37:06 2004 +0000 +++ b/include/SDL_cpuinfo.h Sat Jan 24 05:47:19 2004 +0000 @@ -45,14 +45,26 @@ */ extern DECLSPEC SDL_bool SDLCALL SDL_HasMMX(); +/* This function returns true if the CPU has MMX Ext. features + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasMMXExt(); + /* This function returns true if the CPU has 3DNow features */ extern DECLSPEC SDL_bool SDLCALL SDL_Has3DNow(); +/* This function returns true if the CPU has 3DNow! Ext. features + */ +extern DECLSPEC SDL_bool SDLCALL SDL_Has3DNowExt(); + /* This function returns true if the CPU has SSE features */ extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE(); +/* This function returns true if the CPU has SSE2 features + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE2(); + /* This function returns true if the CPU has AltiVec features */ extern DECLSPEC SDL_bool SDLCALL SDL_HasAltiVec();
--- a/src/cpuinfo/SDL_cpuinfo.c Sat Jan 17 20:37:06 2004 +0000 +++ b/src/cpuinfo/SDL_cpuinfo.c Sat Jan 24 05:47:19 2004 +0000 @@ -36,16 +36,18 @@ #define CPU_HAS_RDTSC 0x00000001 #define CPU_HAS_MMX 0x00000002 -#define CPU_HAS_3DNOW 0x00000004 -#define CPU_HAS_SSE 0x00000008 -#define CPU_HAS_ALTIVEC 0x00000010 +#define CPU_HAS_MMXEXT 0x00000004 +#define CPU_HAS_3DNOW 0x00000010 +#define CPU_HAS_3DNOWEXT 0x00000020 +#define CPU_HAS_SSE 0x00000040 +#define CPU_HAS_SSE2 0x00000080 +#define CPU_HAS_ALTIVEC 0x00000100 static __inline__ int CPU_haveCPUID() { int has_CPUID = 0; #if defined(__GNUC__) && defined(i386) __asm__ ( -"push %%ecx\n" " pushfl # Get original EFLAGS \n" " popl %%eax \n" " movl %%eax,%%ecx \n" @@ -58,7 +60,6 @@ " jz 1f # Processor=80486 \n" " movl $1,%0 # We have CPUID support \n" "1: \n" -"pop %%ecx\n" : "=m" (has_CPUID) : : "%eax", "%ecx" @@ -87,9 +88,7 @@ int features = 0; #if defined(__GNUC__) && defined(i386) __asm__ ( -"push %%ebx\n" -"push %%ecx\n" -"push %%edx\n" +" movl %%ebx,%%edi\n" " xorl %%eax,%%eax # Set up for CPUID instruction \n" " cpuid # Get and save vendor ID \n" " cmpl $1,%%eax # Make sure 1 is valid input for CPUID\n" @@ -99,12 +98,10 @@ " cpuid # Get family/model/stepping/features\n" " movl %%edx,%0 \n" "1: \n" -"pop %%edx\n" -"pop %%ecx\n" -"pop %%ebx\n" +" movl %%edi,%%ebx\n" : "=m" (features) : - : "%eax", "%ebx", "%ecx", "%edx" + : "%eax", "%ebx", "%ecx", "%edx", "%edi" ); #elif defined(_MSC_VER) __asm { @@ -122,6 +119,40 @@ return features; } +static __inline__ int CPU_getCPUIDFeaturesExt() +{ + int features = 0; +#if defined(__GNUC__) && defined(i386) + __asm__ ( +" movl %%ebx,%%edi\n" +" movl $0x80000000,%%eax # Query for extended functions \n" +" cpuid # Get extended function limit \n" +" cmpl $0x80000001,%%eax \n" +" jbe 1f # Nope, we dont have function 800000001h\n" +" movl $0x80000001,%%eax # Setup extended function 800000001h\n" +" cpuid # and get the information \n" +" movl %%edx,%0 \n" +"1: \n" +" movl %%edi,%%ebx\n" + : "=m" (features) + : + : "%eax", "%ebx", "%ecx", "%edx", "%edi" + ); +#elif defined(_MSC_VER) + __asm { + mov eax,80000000h ; Query for extended functions + cpuid ; Get extended function limit + cmp eax,80000001h + jbe done ; Nope, we dont have function 800000001h + mov eax,80000001h ; Setup extended function 800000001h + cpuid ; and get the information + mov features,edx +done: + } +#endif + return features; +} + static __inline__ int CPU_haveRDTSC() { if ( CPU_haveCPUID() ) { @@ -138,49 +169,28 @@ return 0; } +static __inline__ int CPU_haveMMXExt() +{ + if ( CPU_haveCPUID() ) { + return (CPU_getCPUIDFeaturesExt() & 0x00400000); + } + return 0; +} + static __inline__ int CPU_have3DNow() { - int has_3DNow = 0; - if ( !CPU_haveCPUID() ) { - return 0; + if ( CPU_haveCPUID() ) { + return (CPU_getCPUIDFeaturesExt() & 0x80000000); } -#if defined(__GNUC__) && defined(i386) - __asm__ ( -"push %%ebx\n" -"push %%ecx\n" -"push %%edx\n" -" movl $0x80000000,%%eax # Query for extended functions \n" -" cpuid # Get extended function limit \n" -" cmpl $0x80000001,%%eax \n" -" jbe 1f # Nope, we dont have function 800000001h\n" -" movl $0x80000001,%%eax # Setup extended function 800000001h\n" -" cpuid # and get the information \n" -" testl $0x80000000,%%edx # Bit 31 is set if 3DNow! present \n" -" jz 1f # Nope, we dont have 3DNow support\n" -" movl $1,%0 # Yep, we have 3DNow! support! \n" -"1: \n" -"pop %%edx\n" -"pop %%ecx\n" -"pop %%ebx\n" - : "=m" (has_3DNow) - : - : "%eax", "%ebx", "%ecx", "%edx" - ); -#elif defined(_MSC_VER) - __asm { - mov eax,80000000h ; Query for extended functions - cpuid ; Get extended function limit - cmp eax,80000001h - jbe done ; Nope, we dont have function 800000001h - mov eax,80000001h ; Setup extended function 800000001h - cpuid ; and get the information - test edx,80000000h ; Bit 31 is set if 3DNow! present - jz done ; Nope, we dont have 3DNow support - mov has_3DNow,1 ; Yep, we have 3DNow! support! -done: + return 0; +} + +static __inline__ int CPU_have3DNowExt() +{ + if ( CPU_haveCPUID() ) { + return (CPU_getCPUIDFeaturesExt() & 0x40000000); } -#endif - return has_3DNow; + return 0; } static __inline__ int CPU_haveSSE() @@ -191,6 +201,14 @@ return 0; } +static __inline__ int CPU_haveSSE2() +{ + if ( CPU_haveCPUID() ) { + return (CPU_getCPUIDFeatures() & 0x04000000); + } + return 0; +} + static __inline__ int CPU_haveAltiVec() { #ifdef MACOSX @@ -229,6 +247,15 @@ if ( CPU_haveAltiVec() ) { SDL_CPUFeatures |= CPU_HAS_ALTIVEC; } + if ( CPU_haveMMXExt() ) { + SDL_CPUFeatures |= CPU_HAS_MMXEXT; + } + if ( CPU_have3DNowExt() ) { + SDL_CPUFeatures |= CPU_HAS_3DNOWEXT; + } + if ( CPU_haveSSE2() ) { + SDL_CPUFeatures |= CPU_HAS_SSE2; + } } return SDL_CPUFeatures; } @@ -273,6 +300,30 @@ return SDL_FALSE; } +SDL_bool SDL_HasMMXExt() +{ + if ( SDL_GetCPUFeatures() & CPU_HAS_MMXEXT ) { + return SDL_TRUE; + } + return SDL_FALSE; +} + +SDL_bool SDL_Has3DNowExt() +{ + if ( SDL_GetCPUFeatures() & CPU_HAS_3DNOWEXT ) { + return SDL_TRUE; + } + return SDL_FALSE; +} + +SDL_bool SDL_HasSSE2() +{ + if ( SDL_GetCPUFeatures() & CPU_HAS_SSE2 ) { + return SDL_TRUE; + } + return SDL_FALSE; +} + #ifdef TEST_MAIN #include <stdio.h> @@ -281,8 +332,11 @@ { printf("RDTSC: %d\n", SDL_HasRDTSC()); printf("MMX: %d\n", SDL_HasMMX()); + printf("MMXExt: %d\n", SDL_HasMMXExt()); printf("3DNow: %d\n", SDL_Has3DNow()); + printf("3DNowExt: %d\n", SDL_Has3DNowExt()); printf("SSE: %d\n", SDL_HasSSE()); + printf("SSE2: %d\n", SDL_HasSSE2()); printf("AltiVec: %d\n", SDL_HasAltiVec()); return 0; }
--- a/test/testcpuinfo.c Sat Jan 17 20:37:06 2004 +0000 +++ b/test/testcpuinfo.c Sat Jan 24 05:47:19 2004 +0000 @@ -10,8 +10,11 @@ { printf("RDTSC %s\n", SDL_HasRDTSC() ? "detected" : "not detected"); printf("MMX %s\n", SDL_HasMMX() ? "detected" : "not detected"); + printf("MMX Ext %s\n", SDL_HasMMXExt() ? "detected" : "not detected"); printf("3DNow %s\n", SDL_Has3DNow() ? "detected" : "not detected"); + printf("3DNow Ext %s\n", SDL_Has3DNowExt() ? "detected" : "not detected"); printf("SSE %s\n", SDL_HasSSE() ? "detected" : "not detected"); + printf("SSE2 %s\n", SDL_HasSSE2() ? "detected" : "not detected"); printf("AltiVec %s\n", SDL_HasAltiVec() ? "detected" : "not detected"); return(0); }