diff --git a/include/SDL_cpuinfo.h b/include/SDL_cpuinfo.h index 95f304300..f931efd93 100644 --- a/include/SDL_cpuinfo.h +++ b/include/SDL_cpuinfo.h @@ -53,6 +53,10 @@ extern DECLSPEC SDL_bool SDLCALL SDL_Has3DNow(); */ extern DECLSPEC SDL_bool SDLCALL SDL_HasSSE(); +/* This function returns true if the CPU has AltiVec features + */ +extern DECLSPEC SDL_bool SDLCALL SDL_HasAltiVec(); + /* Ends C function definitions when using C++ */ #ifdef __cplusplus } diff --git a/src/cpuinfo/SDL_cpuinfo.c b/src/cpuinfo/SDL_cpuinfo.c index 119b37a0a..1c42511e8 100644 --- a/src/cpuinfo/SDL_cpuinfo.c +++ b/src/cpuinfo/SDL_cpuinfo.c @@ -30,10 +30,15 @@ static char rcsid = #include "SDL.h" #include "SDL_cpuinfo.h" +#ifdef MACOSX +#include /* For AltiVec check */ +#endif + #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 static __inline__ int CPU_haveCPUID() { @@ -186,6 +191,23 @@ static __inline__ int CPU_haveSSE() return 0; } +static __inline__ int CPU_haveAltiVec() +{ +#ifdef MACOSX + /* TODO: This check works on OS X. It would be nice to detect AltiVec + properly on for example Linux/PPC, too. But I don't know how that + is done in Linux (or FreeBSD, or whatever other OS you run PPC :-) + */ + int selectors[2] = { CTL_HW, HW_VECTORUNIT }; + int hasVectorUnit = 0; + size_t length = sizeof(hasVectorUnit); + int error = sysctl(selectors, 2, &hasVectorUnit, &length, NULL, 0); + if( 0 == error ) + return hasVectorUnit != 0; +#endif + return 0; +} + static Uint32 SDL_CPUFeatures = 0xFFFFFFFF; static Uint32 SDL_GetCPUFeatures() @@ -204,6 +226,9 @@ static Uint32 SDL_GetCPUFeatures() if ( CPU_haveSSE() ) { SDL_CPUFeatures |= CPU_HAS_SSE; } + if ( CPU_haveAltiVec() ) { + SDL_CPUFeatures |= CPU_HAS_ALTIVEC; + } } return SDL_CPUFeatures; } @@ -240,15 +265,25 @@ SDL_bool SDL_HasSSE() return SDL_FALSE; } +SDL_bool SDL_HasAltiVec() +{ + if ( SDL_GetCPUFeatures() & CPU_HAS_ALTIVEC ) { + return SDL_TRUE; + } + return SDL_FALSE; +} + #ifdef TEST_MAIN #include int main() { + printf("RDTSC: %d\n", SDL_HasRDTSC()); printf("MMX: %d\n", SDL_HasMMX()); printf("3DNow: %d\n", SDL_Has3DNow()); printf("SSE: %d\n", SDL_HasSSE()); + printf("AltiVec: %d\n", SDL_HasAltiVec()); return 0; } diff --git a/test/testcpuinfo.c b/test/testcpuinfo.c index 64d95116a..7e13e77c6 100644 --- a/test/testcpuinfo.c +++ b/test/testcpuinfo.c @@ -8,8 +8,10 @@ int main(int argc, char *argv[]) { + printf("RDTSC %s\n", SDL_HasRDTSC() ? "detected" : "not detected"); printf("MMX %s\n", SDL_HasMMX() ? "detected" : "not detected"); printf("3DNow %s\n", SDL_Has3DNow() ? "detected" : "not detected"); printf("SSE %s\n", SDL_HasSSE() ? "detected" : "not detected"); + printf("AltiVec %s\n", SDL_HasAltiVec() ? "detected" : "not detected"); return(0); }