Mercurial > sdl-ios-xcode
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 */ |