Mercurial > sdl-ios-xcode
comparison src/cpuinfo/SDL_cpuinfo.c @ 4386:dcb26ac38e6b SDL-1.2
Fixed crash - need to save and restore rbx around cpuid, since the compiler may be assuming the stack pointer isn't being modified when filling in %0.
I did it around each call to cpuid which isn't strictly necessary, but is definitely future proof. :)
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 02 Dec 2009 16:24:21 +0000 |
parents | ca91f36ef3de |
children | 72d3b4fd918b |
comparison
equal
deleted
inserted
replaced
4385:a2bb14457446 | 4386:dcb26ac38e6b |
---|---|
24 /* CPU feature detection for SDL */ | 24 /* CPU feature detection for SDL */ |
25 | 25 |
26 #include "SDL.h" | 26 #include "SDL.h" |
27 #include "SDL_cpuinfo.h" | 27 #include "SDL_cpuinfo.h" |
28 | 28 |
29 #if defined(__MACOSX__) && defined(__ppc__) | 29 #if defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__)) |
30 #include <sys/sysctl.h> /* For AltiVec check */ | 30 #include <sys/sysctl.h> /* For AltiVec check */ |
31 #elif SDL_ALTIVEC_BLITTERS && HAVE_SETJMP | 31 #elif SDL_ALTIVEC_BLITTERS && HAVE_SETJMP |
32 #include <signal.h> | 32 #include <signal.h> |
33 #include <setjmp.h> | 33 #include <setjmp.h> |
34 #endif | 34 #endif |
146 static __inline__ int CPU_getCPUIDFeatures(void) | 146 static __inline__ int CPU_getCPUIDFeatures(void) |
147 { | 147 { |
148 int features = 0; | 148 int features = 0; |
149 #if defined(__GNUC__) && defined(i386) | 149 #if defined(__GNUC__) && defined(i386) |
150 __asm__ ( | 150 __asm__ ( |
151 " pushl %%ebx\n" | |
152 " xorl %%eax,%%eax # Set up for CPUID instruction \n" | 151 " xorl %%eax,%%eax # Set up for CPUID instruction \n" |
152 " pushl %%ebx \n" | |
153 " cpuid # Get and save vendor ID \n" | 153 " cpuid # Get and save vendor ID \n" |
154 " cmpl $1,%%eax # Make sure 1 is valid input for CPUID\n" | 154 " cmpl $1,%%eax # Make sure 1 is valid input for CPUID\n" |
155 " jl 1f # We dont have the CPUID instruction\n" | 155 " jl 1f # We dont have the CPUID instruction\n" |
156 " xorl %%eax,%%eax \n" | 156 " xorl %%eax,%%eax \n" |
157 " incl %%eax \n" | 157 " incl %%eax \n" |
158 " cpuid # Get family/model/stepping/features\n" | 158 " cpuid # Get family/model/stepping/features\n" |
159 " popl %%ebx \n" | |
159 " movl %%edx,%0 \n" | 160 " movl %%edx,%0 \n" |
160 "1: \n" | 161 "1: \n" |
161 " popl %%ebx\n" | |
162 : "=m" (features) | 162 : "=m" (features) |
163 : | 163 : |
164 : "%eax", "%ecx", "%edx" | 164 : "%eax", "%ecx", "%edx" |
165 ); | 165 ); |
166 #elif defined(__GNUC__) && defined(__x86_64__) | 166 #elif defined(__GNUC__) && defined(__x86_64__) |
167 __asm__ ( | 167 __asm__ ( |
168 " xorl %%eax,%%eax # Set up for CPUID instruction \n" | |
168 " pushq %%rbx\n" | 169 " pushq %%rbx\n" |
169 " xorl %%eax,%%eax # Set up for CPUID instruction \n" | |
170 " cpuid # Get and save vendor ID \n" | 170 " cpuid # Get and save vendor ID \n" |
171 " cmpl $1,%%eax # Make sure 1 is valid input for CPUID\n" | 171 " cmpl $1,%%eax # Make sure 1 is valid input for CPUID\n" |
172 " jl 1f # We dont have the CPUID instruction\n" | 172 " jl 1f # We dont have the CPUID instruction\n" |
173 " xorl %%eax,%%eax \n" | 173 " xorl %%eax,%%eax \n" |
174 " incl %%eax \n" | 174 " incl %%eax \n" |
175 " cpuid # Get family/model/stepping/features\n" | 175 " cpuid # Get family/model/stepping/features\n" |
176 " popq %%rbx\n" | |
176 " movl %%edx,%0 \n" | 177 " movl %%edx,%0 \n" |
177 "1: \n" | 178 "1: \n" |
178 " popq %%rbx\n" | |
179 : "=m" (features) | 179 : "=m" (features) |
180 : | 180 : |
181 : "%rax", "%rcx", "%rdx" | 181 : "%rax", "%rcx", "%rdx" |
182 ); | 182 ); |
183 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) | 183 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) |
184 __asm { | 184 __asm { |
185 xor eax, eax ; Set up for CPUID instruction | 185 xor eax, eax ; Set up for CPUID instruction |
186 push ebx | |
186 cpuid ; Get and save vendor ID | 187 cpuid ; Get and save vendor ID |
187 cmp eax, 1 ; Make sure 1 is valid input for CPUID | 188 cmp eax, 1 ; Make sure 1 is valid input for CPUID |
188 jl done ; We dont have the CPUID instruction | 189 jl done ; We dont have the CPUID instruction |
189 xor eax, eax | 190 xor eax, eax |
190 inc eax | 191 inc eax |
191 cpuid ; Get family/model/stepping/features | 192 cpuid ; Get family/model/stepping/features |
193 pop ebx | |
192 mov features, edx | 194 mov features, edx |
193 done: | 195 done: |
194 } | 196 } |
195 #elif defined(__sun) && (defined(__i386) || defined(__amd64)) | 197 #elif defined(__sun) && (defined(__i386) || defined(__amd64)) |
196 __asm( | 198 __asm( |
197 " pushl %ebx\n" | |
198 " xorl %eax,%eax \n" | 199 " xorl %eax,%eax \n" |
200 " pushl %ebx \n" | |
199 " cpuid \n" | 201 " cpuid \n" |
200 " cmpl $1,%eax \n" | 202 " cmpl $1,%eax \n" |
201 " jl 1f \n" | 203 " jl 1f \n" |
202 " xorl %eax,%eax \n" | 204 " xorl %eax,%eax \n" |
203 " incl %eax \n" | 205 " incl %eax \n" |
204 " cpuid \n" | 206 " cpuid \n" |
207 " popl %ebx \n" | |
205 #ifdef __i386 | 208 #ifdef __i386 |
206 " movl %edx,-8(%ebp) \n" | 209 " movl %edx,-8(%ebp) \n" |
207 #else | 210 #else |
208 " movl %edx,-8(%rbp) \n" | 211 " movl %edx,-8(%rbp) \n" |
209 #endif | 212 #endif |
210 "1: \n" | 213 "1: \n" |
211 " popl %ebx\n" ); | |
212 #endif | 214 #endif |
213 return features; | 215 return features; |
214 } | 216 } |
215 | 217 |
216 static __inline__ int CPU_getCPUIDFeaturesExt(void) | 218 static __inline__ int CPU_getCPUIDFeaturesExt(void) |
217 { | 219 { |
218 int features = 0; | 220 int features = 0; |
219 #if defined(__GNUC__) && defined(i386) | 221 #if defined(__GNUC__) && defined(i386) |
220 __asm__ ( | 222 __asm__ ( |
221 " pushl %%ebx\n" | |
222 " movl $0x80000000,%%eax # Query for extended functions \n" | 223 " movl $0x80000000,%%eax # Query for extended functions \n" |
224 " pushl %%ebx \n" | |
223 " cpuid # Get extended function limit \n" | 225 " cpuid # Get extended function limit \n" |
224 " cmpl $0x80000001,%%eax \n" | 226 " cmpl $0x80000001,%%eax \n" |
225 " jl 1f # Nope, we dont have function 800000001h\n" | 227 " jl 1f # Nope, we dont have function 800000001h\n" |
226 " movl $0x80000001,%%eax # Setup extended function 800000001h\n" | 228 " movl $0x80000001,%%eax # Setup extended function 800000001h\n" |
227 " cpuid # and get the information \n" | 229 " cpuid # and get the information \n" |
230 " popl %%ebx \n" | |
228 " movl %%edx,%0 \n" | 231 " movl %%edx,%0 \n" |
229 "1: \n" | 232 "1: \n" |
230 " popl %%ebx\n" | |
231 : "=m" (features) | 233 : "=m" (features) |
232 : | 234 : |
233 : "%eax", "%ecx", "%edx" | 235 : "%eax", "%ecx", "%edx" |
234 ); | 236 ); |
235 #elif defined(__GNUC__) && defined (__x86_64__) | 237 #elif defined(__GNUC__) && defined (__x86_64__) |
236 __asm__ ( | 238 __asm__ ( |
237 " pushq %%rbx\n" | |
238 " movl $0x80000000,%%eax # Query for extended functions \n" | 239 " movl $0x80000000,%%eax # Query for extended functions \n" |
240 " pushq %%rbx \n" | |
239 " cpuid # Get extended function limit \n" | 241 " cpuid # Get extended function limit \n" |
240 " cmpl $0x80000001,%%eax \n" | 242 " cmpl $0x80000001,%%eax \n" |
241 " jl 1f # Nope, we dont have function 800000001h\n" | 243 " jl 1f # Nope, we dont have function 800000001h\n" |
242 " movl $0x80000001,%%eax # Setup extended function 800000001h\n" | 244 " movl $0x80000001,%%eax # Setup extended function 800000001h\n" |
243 " cpuid # and get the information \n" | 245 " cpuid # and get the information \n" |
246 " popq %%rbx \n" | |
244 " movl %%edx,%0 \n" | 247 " movl %%edx,%0 \n" |
245 "1: \n" | 248 "1: \n" |
246 " popq %%rbx\n" | |
247 : "=m" (features) | 249 : "=m" (features) |
248 : | 250 : |
249 : "%rax", "%rcx", "%rdx" | 251 : "%rax", "%rcx", "%rdx" |
250 ); | 252 ); |
251 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) | 253 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) |
252 __asm { | 254 __asm { |
253 mov eax,80000000h ; Query for extended functions | 255 mov eax,80000000h ; Query for extended functions |
256 push ebx | |
254 cpuid ; Get extended function limit | 257 cpuid ; Get extended function limit |
255 cmp eax,80000001h | 258 cmp eax,80000001h |
256 jl done ; Nope, we dont have function 800000001h | 259 jl done ; Nope, we dont have function 800000001h |
257 mov eax,80000001h ; Setup extended function 800000001h | 260 mov eax,80000001h ; Setup extended function 800000001h |
258 cpuid ; and get the information | 261 cpuid ; and get the information |
262 pop ebx | |
259 mov features,edx | 263 mov features,edx |
260 done: | 264 done: |
261 } | 265 } |
262 #elif defined(__sun) && ( defined(__i386) || defined(__amd64) ) | 266 #elif defined(__sun) && ( defined(__i386) || defined(__amd64) ) |
263 __asm ( | 267 __asm ( |
264 " pushl %ebx\n" | |
265 " movl $0x80000000,%eax \n" | 268 " movl $0x80000000,%eax \n" |
269 " pushl %ebx \n" | |
266 " cpuid \n" | 270 " cpuid \n" |
267 " cmpl $0x80000001,%eax \n" | 271 " cmpl $0x80000001,%eax \n" |
268 " jl 1f \n" | 272 " jl 1f \n" |
269 " movl $0x80000001,%eax \n" | 273 " movl $0x80000001,%eax \n" |
270 " cpuid \n" | 274 " cpuid \n" |
275 " popl %ebx \n" | |
271 #ifdef __i386 | 276 #ifdef __i386 |
272 " movl %edx,-8(%ebp) \n" | 277 " movl %edx,-8(%ebp) \n" |
273 #else | 278 #else |
274 " movl %edx,-8(%rbp) \n" | 279 " movl %edx,-8(%rbp) \n" |
275 #endif | 280 #endif |
276 "1: \n" | 281 "1: \n" |
277 " popl %ebx\n" | |
278 ); | 282 ); |
279 #endif | 283 #endif |
280 return features; | 284 return features; |
281 } | 285 } |
282 | 286 |
337 } | 341 } |
338 | 342 |
339 static __inline__ int CPU_haveAltiVec(void) | 343 static __inline__ int CPU_haveAltiVec(void) |
340 { | 344 { |
341 volatile int altivec = 0; | 345 volatile int altivec = 0; |
342 #if defined(__MACOSX__) && defined(__ppc__) | 346 #if defined(__MACOSX__) && (defined(__ppc__) || defined(__ppc64__)) |
343 int selectors[2] = { CTL_HW, HW_VECTORUNIT }; | 347 int selectors[2] = { CTL_HW, HW_VECTORUNIT }; |
344 int hasVectorUnit = 0; | 348 int hasVectorUnit = 0; |
345 size_t length = sizeof(hasVectorUnit); | 349 size_t length = sizeof(hasVectorUnit); |
346 int error = sysctl(selectors, 2, &hasVectorUnit, &length, NULL, 0); | 350 int error = sysctl(selectors, 2, &hasVectorUnit, &length, NULL, 0); |
347 if( 0 == error ) | 351 if( 0 == error ) |