Mercurial > mplayer.hg
annotate cpudetect.c @ 10730:67449e5936f3
fix 10l (computation based on uninitialized data which led to
incorrect field matching) and greatly improve selection logic. the
pullup core should be very accurate now, so try throwing tough samples
at it and report any failures! :)
author | rfelker |
---|---|
date | Sun, 31 Aug 2003 17:46:32 +0000 |
parents | 890f35b31edd |
children | df1433f614f6 |
rev | line source |
---|---|
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
1 #include "config.h" |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
2 #include "cpudetect.h" |
5937 | 3 #include "mp_msg.h" |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
4 |
3146
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
5 CpuCaps gCpuCaps; |
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
6 |
3837 | 7 #ifdef HAVE_MALLOC_H |
8 #include <malloc.h> | |
9 #endif | |
10 #include <stdlib.h> | |
11 | |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
12 #ifdef ARCH_X86 |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
13 |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
14 #include <stdio.h> |
8123
9fc45fe0d444
*HUGE* set of compiler warning fixes, unused variables removal
arpi
parents:
6135
diff
changeset
|
15 #include <string.h> |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
16 |
8401
1b2fc92980d9
Runtime SSE detection for NEtBSD, patch by Nick Hudson <skrll at netbsd.org>
atmos4
parents:
8123
diff
changeset
|
17 #ifdef __NetBSD__ |
1b2fc92980d9
Runtime SSE detection for NEtBSD, patch by Nick Hudson <skrll at netbsd.org>
atmos4
parents:
8123
diff
changeset
|
18 #include <sys/param.h> |
8533
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
19 #include <sys/sysctl.h> |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
20 #include <machine/cpu.h> |
8401
1b2fc92980d9
Runtime SSE detection for NEtBSD, patch by Nick Hudson <skrll at netbsd.org>
atmos4
parents:
8123
diff
changeset
|
21 #endif |
1b2fc92980d9
Runtime SSE detection for NEtBSD, patch by Nick Hudson <skrll at netbsd.org>
atmos4
parents:
8123
diff
changeset
|
22 |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
23 #ifdef __FreeBSD__ |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
24 #include <sys/types.h> |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
25 #include <sys/sysctl.h> |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
26 #endif |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
27 |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
28 #ifdef __linux__ |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
29 #include <signal.h> |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
30 #endif |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
31 |
10440 | 32 #ifdef WIN32 |
33 #include <windows.h> | |
34 #endif | |
35 | |
2272 | 36 //#define X86_FXSR_MAGIC |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
37 /* Thanks to the FreeBSD project for some of this cpuid code, and |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
38 * help understanding how to use it. Thanks to the Mesa |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
39 * team for SSE support detection and more cpu detect code. |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
40 */ |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
41 |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
42 /* I believe this code works. However, it has only been used on a PII and PIII */ |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
43 |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
44 static void check_os_katmai_support( void ); |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
45 |
2272 | 46 #if 1 |
47 // return TRUE if cpuid supported | |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
48 static int has_cpuid() |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
49 { |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
50 int a, c; |
2272 | 51 |
52 // code from libavcodec: | |
53 __asm__ __volatile__ ( | |
54 /* See if CPUID instruction is supported ... */ | |
55 /* ... Get copies of EFLAGS into eax and ecx */ | |
56 "pushf\n\t" | |
57 "popl %0\n\t" | |
58 "movl %0, %1\n\t" | |
59 | |
60 /* ... Toggle the ID bit in one copy and store */ | |
61 /* to the EFLAGS reg */ | |
62 "xorl $0x200000, %0\n\t" | |
63 "push %0\n\t" | |
64 "popf\n\t" | |
65 | |
66 /* ... Get the (hopefully modified) EFLAGS */ | |
67 "pushf\n\t" | |
68 "popl %0\n\t" | |
69 : "=a" (a), "=c" (c) | |
70 : | |
71 : "cc" | |
72 ); | |
73 | |
74 return (a!=c); | |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
75 } |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
76 #endif |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
77 |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
78 static void |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
79 do_cpuid(unsigned int ax, unsigned int *p) |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
80 { |
2272 | 81 #if 0 |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
82 __asm __volatile( |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
83 "cpuid;" |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
84 : "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3]) |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
85 : "0" (ax) |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
86 ); |
2272 | 87 #else |
88 // code from libavcodec: | |
89 __asm __volatile | |
90 ("movl %%ebx, %%esi\n\t" | |
91 "cpuid\n\t" | |
92 "xchgl %%ebx, %%esi" | |
3403 | 93 : "=a" (p[0]), "=S" (p[1]), |
2272 | 94 "=c" (p[2]), "=d" (p[3]) |
95 : "0" (ax)); | |
96 #endif | |
97 | |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
98 } |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
99 |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
100 void GetCpuCaps( CpuCaps *caps) |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
101 { |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
102 unsigned int regs[4]; |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
103 unsigned int regs2[4]; |
3146
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
104 |
8860 | 105 memset(caps, 0, sizeof(*caps)); |
3146
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
106 caps->isX86=1; |
8860 | 107 caps->cl_size=32; /* default */ |
2288 | 108 if (!has_cpuid()) { |
6134 | 109 mp_msg(MSGT_CPUDETECT,MSGL_WARN,"CPUID not supported!??? (maybe an old 486?)\n"); |
2288 | 110 return; |
111 } | |
112 do_cpuid(0x00000000, regs); // get _max_ cpuid level and vendor name | |
6134 | 113 mp_msg(MSGT_CPUDETECT,MSGL_V,"CPU vendor name: %.4s%.4s%.4s max cpuid level: %d\n", |
3837 | 114 (char*) (regs+1),(char*) (regs+3),(char*) (regs+2), regs[0]); |
2288 | 115 if (regs[0]>=0x00000001) |
2280 | 116 { |
2303 | 117 char *tmpstr; |
8860 | 118 unsigned cl_size; |
3146
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
119 |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
120 do_cpuid(0x00000001, regs2); |
2301 | 121 |
2303 | 122 tmpstr=GetCpuFriendlyName(regs, regs2); |
5937 | 123 mp_msg(MSGT_CPUDETECT,MSGL_INFO,"CPU: %s ",tmpstr); |
2303 | 124 free(tmpstr); |
2301 | 125 |
2288 | 126 caps->cpuType=(regs2[0] >> 8)&0xf; |
127 if(caps->cpuType==0xf){ | |
128 // use extended family (P4, IA64) | |
129 caps->cpuType=8+((regs2[0]>>20)&255); | |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
130 } |
3403 | 131 caps->cpuStepping=regs2[0] & 0xf; |
6135 | 132 mp_msg(MSGT_CPUDETECT,MSGL_INFO,"(Family: %d, Stepping: %d)\n", |
3403 | 133 caps->cpuType, caps->cpuStepping); |
2288 | 134 |
135 // general feature flags: | |
2272 | 136 caps->hasMMX = (regs2[3] & (1 << 23 )) >> 23; // 0x0800000 |
137 caps->hasSSE = (regs2[3] & (1 << 25 )) >> 25; // 0x2000000 | |
138 caps->hasSSE2 = (regs2[3] & (1 << 26 )) >> 26; // 0x4000000 | |
2288 | 139 caps->hasMMX2 = caps->hasSSE; // SSE cpus supports mmxext too |
8860 | 140 cl_size = ((regs2[1] >> 8) & 0xFF)*8; |
141 if(cl_size) caps->cl_size = cl_size; | |
2288 | 142 } |
143 do_cpuid(0x80000000, regs); | |
144 if (regs[0]>=0x80000001) { | |
6134 | 145 mp_msg(MSGT_CPUDETECT,MSGL_V,"extended cpuid-level: %d\n",regs[0]&0x7FFFFFFF); |
2288 | 146 do_cpuid(0x80000001, regs2); |
3840 | 147 caps->hasMMX |= (regs2[3] & (1 << 23 )) >> 23; // 0x0800000 |
148 caps->hasMMX2 |= (regs2[3] & (1 << 22 )) >> 22; // 0x400000 | |
2288 | 149 caps->has3DNow = (regs2[3] & (1 << 31 )) >> 31; //0x80000000 |
150 caps->has3DNowExt = (regs2[3] & (1 << 30 )) >> 30; | |
151 } | |
8860 | 152 if(regs[0]>=0x80000006) |
153 { | |
154 do_cpuid(0x80000006, regs2); | |
155 mp_msg(MSGT_CPUDETECT,MSGL_V,"extended cache-info: %d\n",regs2[2]&0x7FFFFFFF); | |
156 caps->cl_size = regs2[2] & 0xFF; | |
157 } | |
158 mp_msg(MSGT_CPUDETECT,MSGL_INFO,"Detected cache-line size is %u bytes\n",caps->cl_size); | |
2288 | 159 #if 0 |
5937 | 160 mp_msg(MSGT_CPUDETECT,MSGL_INFO,"cpudetect: MMX=%d MMX2=%d SSE=%d SSE2=%d 3DNow=%d 3DNowExt=%d\n", |
2288 | 161 gCpuCaps.hasMMX, |
162 gCpuCaps.hasMMX2, | |
163 gCpuCaps.hasSSE, | |
164 gCpuCaps.hasSSE2, | |
165 gCpuCaps.has3DNow, | |
166 gCpuCaps.has3DNowExt ); | |
167 #endif | |
168 | |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
169 /* FIXME: Does SSE2 need more OS support, too? */ |
10440 | 170 #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(WIN32) |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
171 if (caps->hasSSE) |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
172 check_os_katmai_support(); |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
173 if (!caps->hasSSE) |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
174 caps->hasSSE2 = 0; |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
175 #else |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
176 caps->hasSSE=0; |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
177 caps->hasSSE2 = 0; |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
178 #endif |
3146
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
179 // caps->has3DNow=1; |
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
180 // caps->hasMMX2 = 0; |
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
181 // caps->hasMMX = 0; |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
182 |
4829 | 183 #ifndef HAVE_MMX |
6134 | 184 if(caps->hasMMX) mp_msg(MSGT_CPUDETECT,MSGL_WARN,"MMX supported but disabled\n"); |
4829 | 185 caps->hasMMX=0; |
186 #endif | |
187 #ifndef HAVE_MMX2 | |
6134 | 188 if(caps->hasMMX2) mp_msg(MSGT_CPUDETECT,MSGL_WARN,"MMX2 supported but disabled\n"); |
4829 | 189 caps->hasMMX2=0; |
190 #endif | |
191 #ifndef HAVE_SSE | |
6134 | 192 if(caps->hasSSE) mp_msg(MSGT_CPUDETECT,MSGL_WARN,"SSE supported but disabled\n"); |
4829 | 193 caps->hasSSE=0; |
194 #endif | |
195 #ifndef HAVE_SSE2 | |
6134 | 196 if(caps->hasSSE2) mp_msg(MSGT_CPUDETECT,MSGL_WARN,"SSE2 supported but disabled\n"); |
4829 | 197 caps->hasSSE2=0; |
198 #endif | |
199 #ifndef HAVE_3DNOW | |
6134 | 200 if(caps->has3DNow) mp_msg(MSGT_CPUDETECT,MSGL_WARN,"3DNow supported but disabled\n"); |
4829 | 201 caps->has3DNow=0; |
202 #endif | |
203 #ifndef HAVE_3DNOWEX | |
6134 | 204 if(caps->has3DNowExt) mp_msg(MSGT_CPUDETECT,MSGL_WARN,"3DNowExt supported but disabled\n"); |
4829 | 205 caps->has3DNowExt=0; |
206 #endif | |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
207 } |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
208 |
2301 | 209 |
210 #define CPUID_EXTFAMILY ((regs2[0] >> 20)&0xFF) /* 27..20 */ | |
211 #define CPUID_EXTMODEL ((regs2[0] >> 16)&0x0F) /* 19..16 */ | |
212 #define CPUID_TYPE ((regs2[0] >> 12)&0x04) /* 13..12 */ | |
213 #define CPUID_FAMILY ((regs2[0] >> 8)&0x0F) /* 11..08 */ | |
214 #define CPUID_MODEL ((regs2[0] >> 4)&0x0F) /* 07..04 */ | |
215 #define CPUID_STEPPING ((regs2[0] >> 0)&0x0F) /* 03..00 */ | |
216 | |
217 char *GetCpuFriendlyName(unsigned int regs[], unsigned int regs2[]){ | |
218 #include "cputable.h" /* get cpuname and cpuvendors */ | |
219 char vendor[17]; | |
2303 | 220 char *retname; |
2301 | 221 int i; |
222 | |
2417 | 223 if (NULL==(retname=(char*)malloc(256))) { |
5937 | 224 mp_msg(MSGT_CPUDETECT,MSGL_FATAL,"Error: GetCpuFriendlyName() not enough memory\n"); |
2303 | 225 exit(1); |
226 } | |
227 | |
3837 | 228 sprintf(vendor,"%.4s%.4s%.4s",(char*)(regs+1),(char*)(regs+3),(char*)(regs+2)); |
3146
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
229 |
2301 | 230 for(i=0; i<MAX_VENDORS; i++){ |
231 if(!strcmp(cpuvendors[i].string,vendor)){ | |
232 if(cpuname[i][CPUID_FAMILY][CPUID_MODEL]){ | |
2303 | 233 snprintf(retname,255,"%s %s",cpuvendors[i].name,cpuname[i][CPUID_FAMILY][CPUID_MODEL]); |
2301 | 234 } else { |
2303 | 235 snprintf(retname,255,"unknown %s %d. Generation CPU",cpuvendors[i].name,CPUID_FAMILY); |
5937 | 236 mp_msg(MSGT_CPUDETECT,MSGL_WARN,"unknown %s CPU:\n",cpuvendors[i].name); |
237 mp_msg(MSGT_CPUDETECT,MSGL_WARN,"Vendor: %s\n",cpuvendors[i].string); | |
238 mp_msg(MSGT_CPUDETECT,MSGL_WARN,"Type: %d\n",CPUID_TYPE); | |
239 mp_msg(MSGT_CPUDETECT,MSGL_WARN,"Family: %d (ext: %d)\n",CPUID_FAMILY,CPUID_EXTFAMILY); | |
240 mp_msg(MSGT_CPUDETECT,MSGL_WARN,"Model: %d (ext: %d)\n",CPUID_MODEL,CPUID_EXTMODEL); | |
241 mp_msg(MSGT_CPUDETECT,MSGL_WARN,"Stepping: %d\n",CPUID_STEPPING); | |
242 mp_msg(MSGT_CPUDETECT,MSGL_WARN,"Please send the above info along with the exact CPU name" | |
2301 | 243 "to the MPlayer-Developers, so we can add it to the list!\n"); |
244 } | |
245 } | |
246 } | |
247 | |
248 //printf("Detected CPU: %s\n", retname); | |
249 return retname; | |
250 } | |
251 | |
252 #undef CPUID_EXTFAMILY | |
253 #undef CPUID_EXTMODEL | |
254 #undef CPUID_TYPE | |
255 #undef CPUID_FAMILY | |
256 #undef CPUID_MODEL | |
257 #undef CPUID_STEPPING | |
258 | |
259 | |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
260 #if defined(__linux__) && defined(_POSIX_SOURCE) && defined(X86_FXSR_MAGIC) |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
261 static void sigill_handler_sse( int signal, struct sigcontext sc ) |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
262 { |
6134 | 263 mp_msg(MSGT_CPUDETECT,MSGL_V, "SIGILL, " ); |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
264 |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
265 /* Both the "xorps %%xmm0,%%xmm0" and "divps %xmm0,%%xmm1" |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
266 * instructions are 3 bytes long. We must increment the instruction |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
267 * pointer manually to avoid repeated execution of the offending |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
268 * instruction. |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
269 * |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
270 * If the SIGILL is caused by a divide-by-zero when unmasked |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
271 * exceptions aren't supported, the SIMD FPU status and control |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
272 * word will be restored at the end of the test, so we don't need |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
273 * to worry about doing it here. Besides, we may not be able to... |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
274 */ |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
275 sc.eip += 3; |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
276 |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
277 gCpuCaps.hasSSE=0; |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
278 } |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
279 |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
280 static void sigfpe_handler_sse( int signal, struct sigcontext sc ) |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
281 { |
6134 | 282 mp_msg(MSGT_CPUDETECT,MSGL_V, "SIGFPE, " ); |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
283 |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
284 if ( sc.fpstate->magic != 0xffff ) { |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
285 /* Our signal context has the extended FPU state, so reset the |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
286 * divide-by-zero exception mask and clear the divide-by-zero |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
287 * exception bit. |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
288 */ |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
289 sc.fpstate->mxcsr |= 0x00000200; |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
290 sc.fpstate->mxcsr &= 0xfffffffb; |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
291 } else { |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
292 /* If we ever get here, we're completely hosed. |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
293 */ |
6134 | 294 mp_msg(MSGT_CPUDETECT,MSGL_V, "\n\n" ); |
295 mp_msg(MSGT_CPUDETECT,MSGL_V, "SSE enabling test failed badly!" ); | |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
296 } |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
297 } |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
298 #endif /* __linux__ && _POSIX_SOURCE && X86_FXSR_MAGIC */ |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
299 |
10440 | 300 #ifdef WIN32 |
301 LONG CALLBACK win32_sig_handler_sse(EXCEPTION_POINTERS* ep) | |
302 { | |
303 if(ep->ExceptionRecord->ExceptionCode==EXCEPTION_ILLEGAL_INSTRUCTION){ | |
304 mp_msg(MSGT_CPUDETECT,MSGL_V, "SIGILL, " ); | |
305 ep->ContextRecord->Eip +=3; | |
306 gCpuCaps.hasSSE=0; | |
307 return EXCEPTION_CONTINUE_EXECUTION; | |
308 } | |
309 return EXCEPTION_CONTINUE_SEARCH; | |
310 } | |
311 #endif /* WIN32 */ | |
312 | |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
313 /* If we're running on a processor that can do SSE, let's see if we |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
314 * are allowed to or not. This will catch 2.4.0 or later kernels that |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
315 * haven't been configured for a Pentium III but are running on one, |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
316 * and RedHat patched 2.2 kernels that have broken exception handling |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
317 * support for user space apps that do SSE. |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
318 */ |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
319 static void check_os_katmai_support( void ) |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
320 { |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
321 #if defined(__FreeBSD__) |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
322 int has_sse=0, ret; |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
323 size_t len=sizeof(has_sse); |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
324 |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
325 ret = sysctlbyname("hw.instruction_sse", &has_sse, &len, NULL, 0); |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
326 if (ret || !has_sse) |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
327 gCpuCaps.hasSSE=0; |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
328 |
8401
1b2fc92980d9
Runtime SSE detection for NEtBSD, patch by Nick Hudson <skrll at netbsd.org>
atmos4
parents:
8123
diff
changeset
|
329 #elif defined(__NetBSD__) |
8533
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
330 #if __NetBSD_Version__ >= 105250000 |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
331 int has_sse, has_sse2, ret, mib[2]; |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
332 size_t varlen; |
8401
1b2fc92980d9
Runtime SSE detection for NEtBSD, patch by Nick Hudson <skrll at netbsd.org>
atmos4
parents:
8123
diff
changeset
|
333 |
8533
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
334 mib[0] = CTL_MACHDEP; |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
335 mib[1] = CPU_SSE; |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
336 varlen = sizeof(has_sse); |
8401
1b2fc92980d9
Runtime SSE detection for NEtBSD, patch by Nick Hudson <skrll at netbsd.org>
atmos4
parents:
8123
diff
changeset
|
337 |
8533
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
338 mp_msg(MSGT_CPUDETECT,MSGL_V, "Testing OS support for SSE... " ); |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
339 ret = sysctl(mib, 2, &has_sse, &varlen, NULL, 0); |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
340 if (ret < 0 || !has_sse) { |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
341 gCpuCaps.hasSSE=0; |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
342 mp_msg(MSGT_CPUDETECT,MSGL_V, "no!\n" ); |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
343 } else { |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
344 gCpuCaps.hasSSE=1; |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
345 mp_msg(MSGT_CPUDETECT,MSGL_V, "yes!\n" ); |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
346 } |
8401
1b2fc92980d9
Runtime SSE detection for NEtBSD, patch by Nick Hudson <skrll at netbsd.org>
atmos4
parents:
8123
diff
changeset
|
347 |
8533
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
348 mib[1] = CPU_SSE2; |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
349 varlen = sizeof(has_sse2); |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
350 mp_msg(MSGT_CPUDETECT,MSGL_V, "Testing OS support for SSE2... " ); |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
351 ret = sysctl(mib, 2, &has_sse2, &varlen, NULL, 0); |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
352 if (ret < 0 || !has_sse2) { |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
353 gCpuCaps.hasSSE2=0; |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
354 mp_msg(MSGT_CPUDETECT,MSGL_V, "no!\n" ); |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
355 } else { |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
356 gCpuCaps.hasSSE2=1; |
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
357 mp_msg(MSGT_CPUDETECT,MSGL_V, "yes!\n" ); |
8401
1b2fc92980d9
Runtime SSE detection for NEtBSD, patch by Nick Hudson <skrll at netbsd.org>
atmos4
parents:
8123
diff
changeset
|
358 } |
1b2fc92980d9
Runtime SSE detection for NEtBSD, patch by Nick Hudson <skrll at netbsd.org>
atmos4
parents:
8123
diff
changeset
|
359 #else |
8533
9b73b801af55
Ok, here is a better patch, which even adds a fix to compile it on older
arpi
parents:
8401
diff
changeset
|
360 gCpuCaps.hasSSE = 0; |
8401
1b2fc92980d9
Runtime SSE detection for NEtBSD, patch by Nick Hudson <skrll at netbsd.org>
atmos4
parents:
8123
diff
changeset
|
361 mp_msg(MSGT_CPUDETECT,MSGL_WARN, "No OS support for SSE, disabling to be safe.\n" ); |
1b2fc92980d9
Runtime SSE detection for NEtBSD, patch by Nick Hudson <skrll at netbsd.org>
atmos4
parents:
8123
diff
changeset
|
362 #endif |
10440 | 363 #elif defined(WIN32) |
364 LPTOP_LEVEL_EXCEPTION_FILTER exc_fil; | |
365 if ( gCpuCaps.hasSSE ) { | |
366 mp_msg(MSGT_CPUDETECT,MSGL_V, "Testing OS support for SSE... " ); | |
367 exc_fil = SetUnhandledExceptionFilter(win32_sig_handler_sse); | |
368 __asm __volatile ("xorps %xmm0, %xmm0"); | |
369 SetUnhandledExceptionFilter(exc_fil); | |
370 if ( gCpuCaps.hasSSE ) mp_msg(MSGT_CPUDETECT,MSGL_V, "yes.\n" ); | |
371 else mp_msg(MSGT_CPUDETECT,MSGL_V, "no!\n" ); | |
372 } | |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
373 #elif defined(__linux__) |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
374 #if defined(_POSIX_SOURCE) && defined(X86_FXSR_MAGIC) |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
375 struct sigaction saved_sigill; |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
376 struct sigaction saved_sigfpe; |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
377 |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
378 /* Save the original signal handlers. |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
379 */ |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
380 sigaction( SIGILL, NULL, &saved_sigill ); |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
381 sigaction( SIGFPE, NULL, &saved_sigfpe ); |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
382 |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
383 signal( SIGILL, (void (*)(int))sigill_handler_sse ); |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
384 signal( SIGFPE, (void (*)(int))sigfpe_handler_sse ); |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
385 |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
386 /* Emulate test for OSFXSR in CR4. The OS will set this bit if it |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
387 * supports the extended FPU save and restore required for SSE. If |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
388 * we execute an SSE instruction on a PIII and get a SIGILL, the OS |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
389 * doesn't support Streaming SIMD Exceptions, even if the processor |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
390 * does. |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
391 */ |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
392 if ( gCpuCaps.hasSSE ) { |
6134 | 393 mp_msg(MSGT_CPUDETECT,MSGL_V, "Testing OS support for SSE... " ); |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
394 |
2272 | 395 // __asm __volatile ("xorps %%xmm0, %%xmm0"); |
396 __asm __volatile ("xorps %xmm0, %xmm0"); | |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
397 |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
398 if ( gCpuCaps.hasSSE ) { |
6134 | 399 mp_msg(MSGT_CPUDETECT,MSGL_V, "yes.\n" ); |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
400 } else { |
6134 | 401 mp_msg(MSGT_CPUDETECT,MSGL_V, "no!\n" ); |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
402 } |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
403 } |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
404 |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
405 /* Emulate test for OSXMMEXCPT in CR4. The OS will set this bit if |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
406 * it supports unmasked SIMD FPU exceptions. If we unmask the |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
407 * exceptions, do a SIMD divide-by-zero and get a SIGILL, the OS |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
408 * doesn't support unmasked SIMD FPU exceptions. If we get a SIGFPE |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
409 * as expected, we're okay but we need to clean up after it. |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
410 * |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
411 * Are we being too stringent in our requirement that the OS support |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
412 * unmasked exceptions? Certain RedHat 2.2 kernels enable SSE by |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
413 * setting CR4.OSFXSR but don't support unmasked exceptions. Win98 |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
414 * doesn't even support them. We at least know the user-space SSE |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
415 * support is good in kernels that do support unmasked exceptions, |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
416 * and therefore to be safe I'm going to leave this test in here. |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
417 */ |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
418 if ( gCpuCaps.hasSSE ) { |
6134 | 419 mp_msg(MSGT_CPUDETECT,MSGL_V, "Testing OS support for SSE unmasked exceptions... " ); |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
420 |
2272 | 421 // test_os_katmai_exception_support(); |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
422 |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
423 if ( gCpuCaps.hasSSE ) { |
6134 | 424 mp_msg(MSGT_CPUDETECT,MSGL_V, "yes.\n" ); |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
425 } else { |
6134 | 426 mp_msg(MSGT_CPUDETECT,MSGL_V, "no!\n" ); |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
427 } |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
428 } |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
429 |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
430 /* Restore the original signal handlers. |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
431 */ |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
432 sigaction( SIGILL, &saved_sigill, NULL ); |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
433 sigaction( SIGFPE, &saved_sigfpe, NULL ); |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
434 |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
435 /* If we've gotten to here and the XMM CPUID bit is still set, we're |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
436 * safe to go ahead and hook out the SSE code throughout Mesa. |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
437 */ |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
438 if ( gCpuCaps.hasSSE ) { |
6134 | 439 mp_msg(MSGT_CPUDETECT,MSGL_V, "Tests of OS support for SSE passed.\n" ); |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
440 } else { |
6134 | 441 mp_msg(MSGT_CPUDETECT,MSGL_V, "Tests of OS support for SSE failed!\n" ); |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
442 } |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
443 #else |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
444 /* We can't use POSIX signal handling to test the availability of |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
445 * SSE, so we disable it by default. |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
446 */ |
5937 | 447 mp_msg(MSGT_CPUDETECT,MSGL_WARN, "Cannot test OS support for SSE, disabling to be safe.\n" ); |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
448 gCpuCaps.hasSSE=0; |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
449 #endif /* _POSIX_SOURCE && X86_FXSR_MAGIC */ |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
450 #else |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
451 /* Do nothing on other platforms for now. |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
452 */ |
6134 | 453 mp_msg(MSGT_CPUDETECT,MSGL_WARN, "Cannot test OS support for SSE, leaving disabled.\n" ); |
2268
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
454 gCpuCaps.hasSSE=0; |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
455 #endif /* __linux__ */ |
72ff2179d396
cpu detect code by Eric Anholt <eanholt@gladstone.uoregon.edu>
arpi
parents:
diff
changeset
|
456 } |
3146
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
457 #else /* ARCH_X86 */ |
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
458 |
9003 | 459 #ifdef SYS_DARWIN |
460 #include <sys/sysctl.h> | |
461 #else | |
462 #include <signal.h> | |
463 #include <setjmp.h> | |
464 | |
465 static sigjmp_buf jmpbuf; | |
466 static volatile sig_atomic_t canjump = 0; | |
467 | |
468 static void sigill_handler (int sig) | |
469 { | |
470 if (!canjump) { | |
471 signal (sig, SIG_DFL); | |
472 raise (sig); | |
473 } | |
474 | |
475 canjump = 0; | |
476 siglongjmp (jmpbuf, 1); | |
477 } | |
478 #endif | |
479 | |
3146
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
480 void GetCpuCaps( CpuCaps *caps) |
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
481 { |
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
482 caps->cpuType=0; |
3403 | 483 caps->cpuStepping=0; |
3146
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
484 caps->hasMMX=0; |
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
485 caps->hasMMX2=0; |
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
486 caps->has3DNow=0; |
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
487 caps->has3DNowExt=0; |
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
488 caps->hasSSE=0; |
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
489 caps->hasSSE2=0; |
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
490 caps->isX86=0; |
9003 | 491 caps->hasAltiVec = 0; |
492 #ifdef HAVE_ALTIVEC | |
493 #ifdef SYS_DARWIN | |
494 /* | |
495 rip-off from ffmpeg altivec detection code. | |
496 this code also appears on Apple's AltiVec pages. | |
497 */ | |
498 { | |
499 int sels[2] = {CTL_HW, HW_VECTORUNIT}; | |
500 int has_vu = 0; | |
501 size_t len = sizeof(has_vu); | |
502 int err; | |
503 | |
504 err = sysctl(sels, 2, &has_vu, &len, NULL, 0); | |
505 | |
506 if (err == 0) | |
507 if (has_vu != 0) | |
508 caps->hasAltiVec = 1; | |
509 } | |
510 #else /* SYS_DARWIN */ | |
511 /* no Darwin, do it the brute-force way */ | |
512 /* this is borrowed from the libmpeg2 library */ | |
513 { | |
514 signal (SIGILL, sigill_handler); | |
515 if (sigsetjmp (jmpbuf, 1)) { | |
516 signal (SIGILL, SIG_DFL); | |
517 } else { | |
518 canjump = 1; | |
519 | |
520 asm volatile ("mtspr 256, %0\n\t" | |
9122 | 521 "vand %%v0, %%v0, %%v0" |
9003 | 522 : |
523 : "r" (-1)); | |
524 | |
525 signal (SIGILL, SIG_DFL); | |
526 caps->hasAltiVec = 1; | |
527 } | |
528 } | |
529 #endif /* SYS_DARWIN */ | |
9324 | 530 mp_msg(MSGT_CPUDETECT,MSGL_INFO,"AltiVec %sfound\n", (caps->hasAltiVec ? "" : "not ")); |
9003 | 531 #endif /* HAVE_ALTIVEC */ |
3146
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
532 } |
3164eaa93396
non x86 fix (otherwise we would need #ifdef ARCH_X86 around every if(gCpuCaps.has...))
michael
parents:
2417
diff
changeset
|
533 #endif /* !ARCH_X86 */ |