comparison src/cpuinfo/SDL_cpuinfo.c @ 1691:c901fd2a42da SDL-1.3

I think this fixes bug #244
author Sam Lantinga <slouken@libsdl.org>
date Tue, 20 Jun 2006 05:40:57 +0000
parents 4da1ee79c9af
children
comparison
equal deleted inserted replaced
1690:43ba677b4f62 1691:c901fd2a42da
56 56
57 static __inline__ int 57 static __inline__ int
58 CPU_haveCPUID(void) 58 CPU_haveCPUID(void)
59 { 59 {
60 int has_CPUID = 0; 60 int has_CPUID = 0;
61 /* *INDENT-OFF* */
61 #if defined(__GNUC__) && defined(i386) 62 #if defined(__GNUC__) && defined(i386)
62 __asm__(" pushfl # Get original EFLAGS \n" " popl %%eax \n" " movl %%eax,%%ecx \n" " xorl $0x200000,%%eax # Flip ID bit in EFLAGS \n" " pushl %%eax # Save new EFLAGS value on stack \n" " popfl # Replace current EFLAGS value \n" " pushfl # Get new EFLAGS \n" " popl %%eax # Store new EFLAGS in EAX \n" " xorl %%ecx,%%eax # Can not toggle ID bit, \n" " jz 1f # Processor=80486 \n" " movl $1,%0 # We have CPUID support \n" "1: \n": "=m"(has_CPUID): 63 __asm__ (
63 :"%eax", "%ecx"); 64 " pushfl # Get original EFLAGS \n"
65 " popl %%eax \n"
66 " movl %%eax,%%ecx \n"
67 " xorl $0x200000,%%eax # Flip ID bit in EFLAGS \n"
68 " pushl %%eax # Save new EFLAGS value on stack \n"
69 " popfl # Replace current EFLAGS value \n"
70 " pushfl # Get new EFLAGS \n"
71 " popl %%eax # Store new EFLAGS in EAX \n"
72 " xorl %%ecx,%%eax # Can not toggle ID bit, \n"
73 " jz 1f # Processor=80486 \n"
74 " movl $1,%0 # We have CPUID support \n"
75 "1: \n"
76 : "=m" (has_CPUID)
77 :
78 : "%eax", "%ecx"
79 );
64 #elif defined(__GNUC__) && defined(__x86_64__) 80 #elif defined(__GNUC__) && defined(__x86_64__)
65 /* Technically, if this is being compiled under __x86_64__ then it has 81 /* Technically, if this is being compiled under __x86_64__ then it has
66 CPUid by definition. But it's nice to be able to prove it. :) */ 82 CPUid by definition. But it's nice to be able to prove it. :) */
67 __asm__(" pushfq # Get original EFLAGS \n" " popq %%rax \n" " movq %%rax,%%rcx \n" " xorl $0x200000,%%eax # Flip ID bit in EFLAGS \n" " pushq %%rax # Save new EFLAGS value on stack \n" " popfq # Replace current EFLAGS value \n" " pushfq # Get new EFLAGS \n" " popq %%rax # Store new EFLAGS in EAX \n" " xorl %%ecx,%%eax # Can not toggle ID bit, \n" " jz 1f # Processor=80486 \n" " movl $1,%0 # We have CPUID support \n" "1: \n": "=m"(has_CPUID): 83 __asm__ (
68 :"%rax", "%rcx"); 84 " pushfq # Get original EFLAGS \n"
85 " popq %%rax \n"
86 " movq %%rax,%%rcx \n"
87 " xorl $0x200000,%%eax # Flip ID bit in EFLAGS \n"
88 " pushq %%rax # Save new EFLAGS value on stack \n"
89 " popfq # Replace current EFLAGS value \n"
90 " pushfq # Get new EFLAGS \n"
91 " popq %%rax # Store new EFLAGS in EAX \n"
92 " xorl %%ecx,%%eax # Can not toggle ID bit, \n"
93 " jz 1f # Processor=80486 \n"
94 " movl $1,%0 # We have CPUID support \n"
95 "1: \n"
96 : "=m" (has_CPUID)
97 :
98 : "%rax", "%rcx"
99 );
69 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) 100 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
70 __asm { 101 __asm {
71 pushfd; 102 pushfd ; Get original EFLAGS
72 Get original EFLAGS pop eax mov ecx, eax xor eax, 200000 h; 103 pop eax
73 Flip ID bit in EFLAGS push eax; 104 mov ecx, eax
74 Save new EFLAGS value on stack popfd; 105 xor eax, 200000h ; Flip ID bit in EFLAGS
75 Replace current EFLAGS value pushfd; 106 push eax ; Save new EFLAGS value on stack
76 Get new EFLAGS pop eax; 107 popfd ; Replace current EFLAGS value
77 Store new EFLAGS in EAX xor eax, ecx; 108 pushfd ; Get new EFLAGS
78 Can not toggle ID bit, jz done; 109 pop eax ; Store new EFLAGS in EAX
79 Processor = 80486 mov has_CPUID, 1; 110 xor eax, ecx ; Can not toggle ID bit,
80 We have CPUID support done:} 111 jz done ; Processor=80486
81 #elif defined(__sun) && defined(__x86) 112 mov has_CPUID,1 ; We have CPUID support
82 __asm(" pushfl \n" 113 done:
83 " popl %eax \n" 114 }
84 " movl %eax,%ecx \n" 115 #elif defined(__sun) && defined(__i386)
85 " xorl $0x200000,%eax \n" 116 __asm (
86 " pushl %eax \n" 117 " pushfl \n"
87 " popfl \n" 118 " popl %eax \n"
88 " pushfl \n" 119 " movl %eax,%ecx \n"
89 " popl %eax \n" 120 " xorl $0x200000,%eax \n"
90 " xorl %ecx,%eax \n" 121 " pushl %eax \n"
91 " jz 1f \n" 122 " popfl \n"
92 " movl $1,-8(%ebp) \n" 123 " pushfl \n"
93 "1: \n"); 124 " popl %eax \n"
125 " xorl %ecx,%eax \n"
126 " jz 1f \n"
127 " movl $1,-8(%ebp) \n"
128 "1: \n"
129 );
94 #elif defined(__sun) && defined(__amd64) 130 #elif defined(__sun) && defined(__amd64)
95 __asm(" pushfq \n" 131 __asm (
96 " popq %rax \n" 132 " pushfq \n"
97 " movq %rax,%rcx \n" 133 " popq %rax \n"
98 " xorl $0x200000,%eax \n" 134 " movq %rax,%rcx \n"
99 " pushq %rax \n" 135 " xorl $0x200000,%eax \n"
100 " popfq \n" 136 " pushq %rax \n"
101 " pushfq \n" 137 " popfq \n"
102 " popq %rax \n" 138 " pushfq \n"
103 " xorl %ecx,%eax \n" 139 " popq %rax \n"
104 " jz 1f \n" 140 " xorl %ecx,%eax \n"
105 " movl $1,-8(%rbp) \n" 141 " jz 1f \n"
106 "1: \n"); 142 " movl $1,-8(%rbp) \n"
107 #endif 143 "1: \n"
144 );
145 #endif
146 /* *INDENT-ON* */
108 return has_CPUID; 147 return has_CPUID;
109 } 148 }
110 149
111 static __inline__ int 150 static __inline__ int
112 CPU_getCPUIDFeatures(void) 151 CPU_getCPUIDFeatures(void)
113 { 152 {
114 int features = 0; 153 int features = 0;
154 /* *INDENT-OFF* */
115 #if defined(__GNUC__) && ( defined(i386) || defined(__x86_64__) ) 155 #if defined(__GNUC__) && ( defined(i386) || defined(__x86_64__) )
116 __asm__(" movl %%ebx,%%edi\n" " xorl %%eax,%%eax # Set up for CPUID instruction \n" " cpuid # Get and save vendor ID \n" " cmpl $1,%%eax # Make sure 1 is valid input for CPUID\n" " jl 1f # We dont have the CPUID instruction\n" " xorl %%eax,%%eax \n" " incl %%eax \n" " cpuid # Get family/model/stepping/features\n" " movl %%edx,%0 \n" "1: \n" " movl %%edi,%%ebx\n": "=m"(features): 156 __asm__ (
117 :"%eax", "%ecx", "%edx", "%edi"); 157 " movl %%ebx,%%edi\n"
158 " xorl %%eax,%%eax # Set up for CPUID instruction \n"
159 " cpuid # Get and save vendor ID \n"
160 " cmpl $1,%%eax # Make sure 1 is valid input for CPUID\n"
161 " jl 1f # We dont have the CPUID instruction\n"
162 " xorl %%eax,%%eax \n"
163 " incl %%eax \n"
164 " cpuid # Get family/model/stepping/features\n"
165 " movl %%edx,%0 \n"
166 "1: \n"
167 " movl %%edi,%%ebx\n"
168 : "=m" (features)
169 :
170 : "%eax", "%ecx", "%edx", "%edi"
171 );
118 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) 172 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
119 __asm { 173 __asm {
120 xor eax, eax; 174 xor eax, eax ; Set up for CPUID instruction
121 Set up for CPUID instruction 175 cpuid ; Get and save vendor ID
122 cpuid; Get and save vendor ID 176 cmp eax, 1 ; Make sure 1 is valid input for CPUID
123 cmp eax, 1; Make sure 1 is valid input for CPUID 177 jl done ; We dont have the CPUID instruction
124 jl done; We dont have the CPUID instruction 178 xor eax, eax
125 xor eax, eax 179 inc eax
126 inc eax 180 cpuid ; Get family/model/stepping/features
127 cpuid; Get family / model / stepping / features 181 mov features, edx
128 mov features, edx done:} 182 done:
129 #elif defined(__sun) && (defined(__x86) || defined(__amd64)) 183 }
130 __asm 184 #elif defined(__sun) && (defined(__i386) || defined(__amd64))
131 (" movl %ebx,%edi\n" 185 __asm(
132 " xorl %eax,%eax \n" 186 " movl %ebx,%edi\n"
133 " cpuid \n" 187 " xorl %eax,%eax \n"
134 " cmpl $1,%eax \n" 188 " cpuid \n"
135 " jl 1f \n" 189 " cmpl $1,%eax \n"
136 " xorl %eax,%eax \n" 190 " jl 1f \n"
137 " incl %eax \n" 191 " xorl %eax,%eax \n"
138 " cpuid \n" 192 " incl %eax \n"
193 " cpuid \n"
139 #ifdef __i386 194 #ifdef __i386
140 " movl %edx,-8(%ebp) \n" 195 " movl %edx,-8(%ebp) \n"
141 #else 196 #else
142 " movl %edx,-8(%rbp) \n" 197 " movl %edx,-8(%rbp) \n"
143 #endif 198 #endif
144 "1: \n" 199 "1: \n"
145 " movl %edi,%ebx\n"); 200 " movl %edi,%ebx\n" );
146 #endif 201 #endif
202 /* *INDENT-ON* */
147 return features; 203 return features;
148 } 204 }
149 205
150 static __inline__ int 206 static __inline__ int
151 CPU_getCPUIDFeaturesExt(void) 207 CPU_getCPUIDFeaturesExt(void)
152 { 208 {
153 int features = 0; 209 int features = 0;
210 /* *INDENT-OFF* */
154 #if defined(__GNUC__) && (defined(i386) || defined (__x86_64__) ) 211 #if defined(__GNUC__) && (defined(i386) || defined (__x86_64__) )
155 __asm__(" movl %%ebx,%%edi\n" " movl $0x80000000,%%eax # Query for extended functions \n" " cpuid # Get extended function limit \n" " cmpl $0x80000001,%%eax \n" " jl 1f # Nope, we dont have function 800000001h\n" " movl $0x80000001,%%eax # Setup extended function 800000001h\n" " cpuid # and get the information \n" " movl %%edx,%0 \n" "1: \n" " movl %%edi,%%ebx\n": "=m"(features): 212 __asm__ (
156 :"%eax", "%ecx", "%edx", "%edi"); 213 " movl %%ebx,%%edi\n"
214 " movl $0x80000000,%%eax # Query for extended functions \n"
215 " cpuid # Get extended function limit \n"
216 " cmpl $0x80000001,%%eax \n"
217 " jl 1f # Nope, we dont have function 800000001h\n"
218 " movl $0x80000001,%%eax # Setup extended function 800000001h\n"
219 " cpuid # and get the information \n"
220 " movl %%edx,%0 \n"
221 "1: \n"
222 " movl %%edi,%%ebx\n"
223 : "=m" (features)
224 :
225 : "%eax", "%ecx", "%edx", "%edi"
226 );
157 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__) 227 #elif (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
158 __asm { 228 __asm {
159 mov eax, 80000000 h; 229 mov eax,80000000h ; Query for extended functions
160 Query for extended functions 230 cpuid ; Get extended function limit
161 cpuid; Get extended function limit 231 cmp eax,80000001h
162 cmp eax, 80000001 h jl done; Nope 232 jl done ; Nope, we dont have function 800000001h
163 , we dont have function 800000001 h mov eax, 80000001 h; 233 mov eax,80000001h ; Setup extended function 800000001h
164 Setup extended function 800000001 h cpuid; 234 cpuid ; and get the information
165 and get the information mov features, edx done:} 235 mov features,edx
236 done:
237 }
166 #elif defined(__sun) && ( defined(__i386) || defined(__amd64) ) 238 #elif defined(__sun) && ( defined(__i386) || defined(__amd64) )
167 __asm(" movl %ebx,%edi\n" 239 __asm (
168 " movl $0x80000000,%eax \n" 240 " movl %ebx,%edi\n"
169 " cpuid \n" 241 " movl $0x80000000,%eax \n"
170 " cmpl $0x80000001,%eax \n" 242 " cpuid \n"
171 " jl 1f \n" 243 " cmpl $0x80000001,%eax \n"
172 " movl $0x80000001,%eax \n" 244 " jl 1f \n"
173 " cpuid \n" 245 " movl $0x80000001,%eax \n"
246 " cpuid \n"
174 #ifdef __i386 247 #ifdef __i386
175 " movl %edx,-8(%ebp) \n" 248 " movl %edx,-8(%ebp) \n"
176 #else 249 #else
177 " movl %edx,-8(%rbp) \n" 250 " movl %edx,-8(%rbp) \n"
178 #endif 251 #endif
179 "1: \n" 252 "1: \n"
180 " movl %edi,%ebx\n"); 253 " movl %edi,%ebx\n"
181 #endif 254 );
255 #endif
256 /* *INDENT-ON* */
182 return features; 257 return features;
183 } 258 }
184 259
185 static __inline__ int 260 static __inline__ int
186 CPU_haveRDTSC(void) 261 CPU_haveRDTSC(void)
392 printf("AltiVec: %d\n", SDL_HasAltiVec()); 467 printf("AltiVec: %d\n", SDL_HasAltiVec());
393 return 0; 468 return 0;
394 } 469 }
395 470
396 #endif /* TEST_MAIN */ 471 #endif /* TEST_MAIN */
472
397 /* vi: set ts=4 sw=4 expandtab: */ 473 /* vi: set ts=4 sw=4 expandtab: */