comparison src/cpuinfo/SDL_cpuinfo.c @ 793:c20f08c4f437

Altivec detection on non-MacOS X systems
author Sam Lantinga <slouken@libsdl.org>
date Thu, 29 Jan 2004 05:22:23 +0000
parents 07760c8854d1
children 275708f2e838
comparison
equal deleted inserted replaced
792:2cbb8eaa2c92 793:c20f08c4f437
24 static char rcsid = 24 static char rcsid =
25 "@(#) $Id$"; 25 "@(#) $Id$";
26 #endif 26 #endif
27 27
28 /* CPU feature detection for SDL */ 28 /* CPU feature detection for SDL */
29
30 #ifdef unix /* FIXME: Better setjmp detection? */
31 #define USE_SETJMP
32 #include <signal.h>
33 #include <setjmp.h>
34 #endif
29 35
30 #include "SDL.h" 36 #include "SDL.h"
31 #include "SDL_cpuinfo.h" 37 #include "SDL_cpuinfo.h"
32 38
33 #ifdef MACOSX 39 #ifdef MACOSX
40 #define CPU_HAS_3DNOW 0x00000010 46 #define CPU_HAS_3DNOW 0x00000010
41 #define CPU_HAS_3DNOWEXT 0x00000020 47 #define CPU_HAS_3DNOWEXT 0x00000020
42 #define CPU_HAS_SSE 0x00000040 48 #define CPU_HAS_SSE 0x00000040
43 #define CPU_HAS_SSE2 0x00000080 49 #define CPU_HAS_SSE2 0x00000080
44 #define CPU_HAS_ALTIVEC 0x00000100 50 #define CPU_HAS_ALTIVEC 0x00000100
51
52 #ifdef USE_SETJMP
53 /* This is the brute force way of detecting instruction sets...
54 the idea is borrowed from the libmpeg2 library - thanks!
55 */
56 static jmp_buf jmpbuf;
57 static void illegal_instruction(int sig)
58 {
59 longjmp(jmpbuf, 1);
60 }
61 #endif // USE_SETJMP
45 62
46 static __inline__ int CPU_haveCPUID() 63 static __inline__ int CPU_haveCPUID()
47 { 64 {
48 int has_CPUID = 0; 65 int has_CPUID = 0;
49 #if defined(__GNUC__) && defined(i386) 66 #if defined(__GNUC__) && defined(i386)
209 return 0; 226 return 0;
210 } 227 }
211 228
212 static __inline__ int CPU_haveAltiVec() 229 static __inline__ int CPU_haveAltiVec()
213 { 230 {
231 int altivec = 0;
214 #ifdef MACOSX 232 #ifdef MACOSX
215 /* TODO: This check works on OS X. It would be nice to detect AltiVec
216 properly on for example Linux/PPC, too. But I don't know how that
217 is done in Linux (or FreeBSD, or whatever other OS you run PPC :-)
218 */
219 int selectors[2] = { CTL_HW, HW_VECTORUNIT }; 233 int selectors[2] = { CTL_HW, HW_VECTORUNIT };
220 int hasVectorUnit = 0; 234 int hasVectorUnit = 0;
221 size_t length = sizeof(hasVectorUnit); 235 size_t length = sizeof(hasVectorUnit);
222 int error = sysctl(selectors, 2, &hasVectorUnit, &length, NULL, 0); 236 int error = sysctl(selectors, 2, &hasVectorUnit, &length, NULL, 0);
223 if( 0 == error ) 237 if( 0 == error )
224 return hasVectorUnit != 0; 238 altivec = (hasVectorUnit != 0);
225 #endif 239 #elseif defined(USE_SETJMP) && defined(__GNUC__) && defined(__powerpc__)
226 return 0; 240 void (*handler)(int sig);
241 handler = signal(SIGILL, illegal_instruction);
242 if ( setjmp(jmpbuf) == 0 ) {
243 asm volatile ("mtspr 256, %0\n\t"
244 "vand %%v0, %%v0, %%v0"
245 :
246 : "r" (-1));
247 altivec = 1;
248 }
249 signal(SIGILL, handler);
250 #endif
251 return altivec;
227 } 252 }
228 253
229 static Uint32 SDL_CPUFeatures = 0xFFFFFFFF; 254 static Uint32 SDL_CPUFeatures = 0xFFFFFFFF;
230 255
231 static Uint32 SDL_GetCPUFeatures() 256 static Uint32 SDL_GetCPUFeatures()