src/cpuinfo/SDL_cpuinfo.c
changeset 778 8ac3f46f9d09
parent 769 b8d311d90021
child 784 a2dde6aff60e
equal deleted inserted replaced
777:6f4fe7f2063b 778:8ac3f46f9d09
    28 /* CPU feature detection for SDL */
    28 /* CPU feature detection for SDL */
    29 
    29 
    30 #include "SDL.h"
    30 #include "SDL.h"
    31 #include "SDL_cpuinfo.h"
    31 #include "SDL_cpuinfo.h"
    32 
    32 
       
    33 #ifdef MACOSX
       
    34 #include <sys/sysctl.h> /* For AltiVec check */
       
    35 #endif
       
    36 
    33 #define CPU_HAS_RDTSC	0x00000001
    37 #define CPU_HAS_RDTSC	0x00000001
    34 #define CPU_HAS_MMX	0x00000002
    38 #define CPU_HAS_MMX	0x00000002
    35 #define CPU_HAS_3DNOW	0x00000004
    39 #define CPU_HAS_3DNOW	0x00000004
    36 #define CPU_HAS_SSE	0x00000008
    40 #define CPU_HAS_SSE	0x00000008
       
    41 #define CPU_HAS_ALTIVEC	0x00000010
    37 
    42 
    38 static __inline__ int CPU_haveCPUID()
    43 static __inline__ int CPU_haveCPUID()
    39 {
    44 {
    40 	int has_CPUID = 0;
    45 	int has_CPUID = 0;
    41 #if defined(__GNUC__) && defined(i386)
    46 #if defined(__GNUC__) && defined(i386)
   184 		return (CPU_getCPUIDFeatures() & 0x02000000);
   189 		return (CPU_getCPUIDFeatures() & 0x02000000);
   185 	}
   190 	}
   186 	return 0;
   191 	return 0;
   187 }
   192 }
   188 
   193 
       
   194 static __inline__ int CPU_haveAltiVec()
       
   195 {
       
   196 #ifdef MACOSX
       
   197 	/* TODO: This check works on OS X. It would be nice to detect AltiVec
       
   198 	   properly on for example Linux/PPC, too. But I don't know how that
       
   199 	   is done in Linux (or FreeBSD, or whatever other OS you run PPC :-)
       
   200 	 */
       
   201 	int selectors[2] = { CTL_HW, HW_VECTORUNIT }; 
       
   202 	int hasVectorUnit = 0; 
       
   203 	size_t length = sizeof(hasVectorUnit); 
       
   204 	int error = sysctl(selectors, 2, &hasVectorUnit, &length, NULL, 0); 
       
   205 	if( 0 == error )
       
   206 		return hasVectorUnit != 0; 
       
   207 #endif
       
   208 	return 0; 
       
   209 }
       
   210 
   189 static Uint32 SDL_CPUFeatures = 0xFFFFFFFF;
   211 static Uint32 SDL_CPUFeatures = 0xFFFFFFFF;
   190 
   212 
   191 static Uint32 SDL_GetCPUFeatures()
   213 static Uint32 SDL_GetCPUFeatures()
   192 {
   214 {
   193 	if ( SDL_CPUFeatures == 0xFFFFFFFF ) {
   215 	if ( SDL_CPUFeatures == 0xFFFFFFFF ) {
   202 			SDL_CPUFeatures |= CPU_HAS_3DNOW;
   224 			SDL_CPUFeatures |= CPU_HAS_3DNOW;
   203 		}
   225 		}
   204 		if ( CPU_haveSSE() ) {
   226 		if ( CPU_haveSSE() ) {
   205 			SDL_CPUFeatures |= CPU_HAS_SSE;
   227 			SDL_CPUFeatures |= CPU_HAS_SSE;
   206 		}
   228 		}
       
   229 		if ( CPU_haveAltiVec() ) {
       
   230 			SDL_CPUFeatures |= CPU_HAS_ALTIVEC;
       
   231 		}
   207 	}
   232 	}
   208 	return SDL_CPUFeatures;
   233 	return SDL_CPUFeatures;
   209 }
   234 }
   210 
   235 
   211 SDL_bool SDL_HasRDTSC()
   236 SDL_bool SDL_HasRDTSC()
   238 		return SDL_TRUE;
   263 		return SDL_TRUE;
   239 	}
   264 	}
   240 	return SDL_FALSE;
   265 	return SDL_FALSE;
   241 }
   266 }
   242 
   267 
       
   268 SDL_bool SDL_HasAltiVec()
       
   269 {
       
   270 	if ( SDL_GetCPUFeatures() & CPU_HAS_ALTIVEC ) {
       
   271 		return SDL_TRUE;
       
   272 	}
       
   273 	return SDL_FALSE;
       
   274 }
       
   275 
   243 #ifdef TEST_MAIN
   276 #ifdef TEST_MAIN
   244 
   277 
   245 #include <stdio.h>
   278 #include <stdio.h>
   246 
   279 
   247 int main()
   280 int main()
   248 {
   281 {
       
   282 	printf("RDTSC: %d\n", SDL_HasRDTSC());
   249 	printf("MMX: %d\n", SDL_HasMMX());
   283 	printf("MMX: %d\n", SDL_HasMMX());
   250 	printf("3DNow: %d\n", SDL_Has3DNow());
   284 	printf("3DNow: %d\n", SDL_Has3DNow());
   251 	printf("SSE: %d\n", SDL_HasSSE());
   285 	printf("SSE: %d\n", SDL_HasSSE());
       
   286 	printf("AltiVec: %d\n", SDL_HasAltiVec());
   252 	return 0;
   287 	return 0;
   253 }
   288 }
   254 
   289 
   255 #endif /* TEST_MAIN */
   290 #endif /* TEST_MAIN */