comparison src/cpuinfo/SDL_cpuinfo.c @ 745:71ee03909f42

Greatly simplified the SDL CPU info code
author Sam Lantinga <slouken@libsdl.org>
date Mon, 24 Nov 2003 09:16:52 +0000
parents 22dbf364c017
children da36f59485da
comparison
equal deleted inserted replaced
744:f601f5c05045 745:71ee03909f42
26 #endif 26 #endif
27 27
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 #define CPU_HAS_MMX 0x00000001 33 #define CPU_HAS_RDTSC 0x00000001
34 #define CPU_HAS_3DNOW 0x00000002 34 #define CPU_HAS_MMX 0x00000002
35 #define CPU_HAS_SSE 0x00000004 35 #define CPU_HAS_3DNOW 0x00000004
36 36 #define CPU_HAS_SSE 0x00000008
37 /* These functions come from SciTech's PM library */ 37
38 extern int CPU_haveMMX(); 38 static __inline__ int CPU_haveCPUID()
39 extern int CPU_have3DNow(); 39 {
40 extern int CPU_haveSSE(); 40 int has_CPUID = 0;
41 #if defined(__GNUC__) && defined(i386)
42 __asm__ (
43 "push %%ecx\n"
44 " pushfl # Get original EFLAGS \n"
45 " popl %%eax \n"
46 " movl %%eax,%%ecx \n"
47 " xorl $0x200000,%%eax # Flip ID bit in EFLAGS \n"
48 " pushl %%eax # Save new EFLAGS value on stack \n"
49 " popfl # Replace current EFLAGS value \n"
50 " pushfl # Get new EFLAGS \n"
51 " popl %%eax # Store new EFLAGS in EAX \n"
52 " xorl %%ecx,%%eax # Can not toggle ID bit, \n"
53 " jz 1f # Processor=80486 \n"
54 " movl $1,%0 # We have CPUID support \n"
55 "1: \n"
56 "pop %%ecx\n"
57 : "=r" (has_CPUID)
58 :
59 : "%eax", "%ecx"
60 );
61 #elif defined(_MSC_VER)
62 __asm__ {
63 pushfd ; Get original EFLAGS
64 pop eax
65 mov ecx, eax
66 xor eax, 200000h ; Flip ID bit in EFLAGS
67 push eax ; Save new EFLAGS value on stack
68 popfd ; Replace current EFLAGS value
69 pushfd ; Get new EFLAGS
70 pop eax ; Store new EFLAGS in EAX
71 xor eax, ecx ; Can not toggle ID bit,
72 jz done ; Processor=80486
73 mov has_CPUID,1 ; We have CPUID support
74 done:
75 }
76 #endif
77 return has_CPUID;
78 }
79
80 static __inline__ int CPU_getCPUIDFeatures()
81 {
82 int features = 0;
83 #if defined(__GNUC__) && defined(i386)
84 __asm__ (
85 "push %%ebx\n"
86 "push %%ecx\n"
87 "push %%edx\n"
88 " xorl %%eax,%%eax # Set up for CPUID instruction \n"
89 " cpuid # Get and save vendor ID \n"
90 " cmpl $1,%%eax # Make sure 1 is valid input for CPUID\n"
91 " jl 1f # We dont have the CPUID instruction\n"
92 " xorl %%eax,%%eax \n"
93 " incl %%eax \n"
94 " cpuid # Get family/model/stepping/features\n"
95 " movl %%edx,%0 \n"
96 "1: \n"
97 "pop %%edx\n"
98 "pop %%ecx\n"
99 "pop %%ebx\n"
100 : "=r" (features)
101 :
102 : "%eax", "%ebx", "%ecx", "%edx"
103 );
104 #elif defined(_MSC_VER)
105 __asm__ {
106 xor eax, eax ; Set up for CPUID instruction
107 cpuid ; Get and save vendor ID
108 cmp eax, 1 ; Make sure 1 is valid input for CPUID
109 jl done ; We dont have the CPUID instruction
110 xor eax, eax
111 inc eax
112 cpuid ; Get family/model/stepping/features
113 mov features, edx
114 done:
115 }
116 #endif
117 return features;
118 }
119
120 static __inline__ int CPU_haveRDTSC()
121 {
122 if ( CPU_haveCPUID() ) {
123 return (CPU_getCPUIDFeatures() & 0x00000010);
124 }
125 return 0;
126 }
127
128 static __inline__ int CPU_haveMMX()
129 {
130 if ( CPU_haveCPUID() ) {
131 return (CPU_getCPUIDFeatures() & 0x00800000);
132 }
133 return 0;
134 }
135
136 static __inline__ int CPU_have3DNow()
137 {
138 int has_3DNow = 0;
139 #if defined(__GNUC__) && defined(i386)
140 __asm__ (
141 "push %%ebx\n"
142 "push %%ecx\n"
143 "push %%edx\n"
144 " movl $0x80000000,%%eax # Query for extended functions \n"
145 " cpuid # Get extended function limit \n"
146 " cmpl $0x80000001,%%eax \n"
147 " jbe 1f # Nope, we dont have function 800000001h\n"
148 " movl $0x80000001,%%eax # Setup extended function 800000001h\n"
149 " cpuid # and get the information \n"
150 " testl $0x80000000,%%edx # Bit 31 is set if 3DNow! present \n"
151 " jz 1f # Nope, we dont have 3DNow support\n"
152 " movl $1,%0 # Yep, we have 3DNow! support! \n"
153 "1: \n"
154 "pop %%edx\n"
155 "pop %%ecx\n"
156 "pop %%ebx\n"
157 : "=r" (has_3DNow)
158 :
159 : "%eax", "%ebx", "%ecx", "%edx"
160 );
161 #elif defined(_MSC_VER)
162 __asm__ {
163 mov eax,80000000h ; Query for extended functions
164 cpuid ; Get extended function limit
165 cmp eax,80000001h
166 jbe done ; Nope, we dont have function 800000001h
167 mov eax,80000001h ; Setup extended function 800000001h
168 cpuid ; and get the information
169 test edx,80000000h ; Bit 31 is set if 3DNow! present
170 jz done ; Nope, we dont have 3DNow support
171 mov has_3DNow,1 ; Yep, we have 3DNow! support!
172 done:
173 }
174 #endif
175 return has_3DNow;
176 }
177
178 static __inline__ int CPU_haveSSE()
179 {
180 if ( CPU_haveCPUID() ) {
181 return (CPU_getCPUIDFeatures() & 0x02000000);
182 }
183 return 0;
184 }
41 185
42 static Uint32 SDL_CPUFeatures = 0xFFFFFFFF; 186 static Uint32 SDL_CPUFeatures = 0xFFFFFFFF;
43 187
44 static Uint32 SDL_GetCPUFeatures() 188 static Uint32 SDL_GetCPUFeatures()
45 { 189 {
46 if ( SDL_CPUFeatures == 0xFFFFFFFF ) { 190 if ( SDL_CPUFeatures == 0xFFFFFFFF ) {
47 SDL_CPUFeatures = 0; 191 SDL_CPUFeatures = 0;
192 if ( CPU_haveRDTSC() ) {
193 SDL_CPUFeatures |= CPU_HAS_RDTSC;
194 }
48 if ( CPU_haveMMX() ) { 195 if ( CPU_haveMMX() ) {
49 SDL_CPUFeatures |= CPU_HAS_MMX; 196 SDL_CPUFeatures |= CPU_HAS_MMX;
50 } 197 }
51 if ( CPU_have3DNow() ) { 198 if ( CPU_have3DNow() ) {
52 SDL_CPUFeatures |= CPU_HAS_3DNOW; 199 SDL_CPUFeatures |= CPU_HAS_3DNOW;
54 if ( CPU_haveSSE() ) { 201 if ( CPU_haveSSE() ) {
55 SDL_CPUFeatures |= CPU_HAS_SSE; 202 SDL_CPUFeatures |= CPU_HAS_SSE;
56 } 203 }
57 } 204 }
58 return SDL_CPUFeatures; 205 return SDL_CPUFeatures;
206 }
207
208 SDL_bool SDL_HasRDTSC()
209 {
210 if ( SDL_GetCPUFeatures() & CPU_HAS_RDTSC ) {
211 return SDL_TRUE;
212 }
213 return SDL_FALSE;
59 } 214 }
60 215
61 SDL_bool SDL_HasMMX() 216 SDL_bool SDL_HasMMX()
62 { 217 {
63 if ( SDL_GetCPUFeatures() & CPU_HAS_MMX ) { 218 if ( SDL_GetCPUFeatures() & CPU_HAS_MMX ) {
89 int main() 244 int main()
90 { 245 {
91 printf("MMX: %d\n", SDL_HasMMX()); 246 printf("MMX: %d\n", SDL_HasMMX());
92 printf("3DNow: %d\n", SDL_Has3DNow()); 247 printf("3DNow: %d\n", SDL_Has3DNow());
93 printf("SSE: %d\n", SDL_HasSSE()); 248 printf("SSE: %d\n", SDL_HasSSE());
249 return 0;
94 } 250 }
95 251
96 #endif /* TEST_MAIN */ 252 #endif /* TEST_MAIN */