From 798506ee1ce1bc0ec63a4320d6684d8f85db4a7f Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 6 Jan 2004 17:18:38 +0000 Subject: [PATCH] Date: Tue, 6 Jan 2004 12:42:19 +0100 From: Max Horn Subject: SDL_HasAltiVec; BUGS file the attached patch adds SDL_HasAltiVec to SDL CVS. Note that at this point, this only works on MacOSX (and maybe darwin). I don't know how to properly add a test for e.g. Linux/PPC at this point. I found an email which might help in doing so: http://zebra.fh-weingarten.de/~maxi/html/mplayer-dev-eng/2003-01msg00783.html However, since I have no way to test on a non-OSX PowerPC system, I am not comfortable blindly adding such code... I just hope that if somebody from the Linux/PPC (or FreeBSD/PPC, or whatever) community notices this, they'll jump up and provide a patch for us ;-) --- include/SDL_cpuinfo.h | 4 ++++ src/cpuinfo/SDL_cpuinfo.c | 35 +++++++++++++++++++++++++++++++++++ test/testcpuinfo.c | 2 ++ 3 files changed, 41 insertions(+) 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); }