Mercurial > hg > CbC > CbC_gcc
annotate gcc/config/i386/driver-i386.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | 58ad6c70ea60 |
children | b7f97abdc517 |
rev | line source |
---|---|
0 | 1 /* Subroutines for the gcc driver. |
2 Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc. | |
3 | |
4 This file is part of GCC. | |
5 | |
6 GCC is free software; you can redistribute it and/or modify | |
7 it under the terms of the GNU General Public License as published by | |
8 the Free Software Foundation; either version 3, or (at your option) | |
9 any later version. | |
10 | |
11 GCC is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 GNU General Public License for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with GCC; see the file COPYING3. If not see | |
18 <http://www.gnu.org/licenses/>. */ | |
19 | |
20 #include "config.h" | |
21 #include "system.h" | |
22 #include "coretypes.h" | |
23 #include "tm.h" | |
24 #include <stdlib.h> | |
25 | |
26 const char *host_detect_local_cpu (int argc, const char **argv); | |
27 | |
28 #ifdef __GNUC__ | |
29 #include "cpuid.h" | |
30 | |
31 struct cache_desc | |
32 { | |
33 unsigned sizekb; | |
34 unsigned assoc; | |
35 unsigned line; | |
36 }; | |
37 | |
38 /* Returns command line parameters that describe size and | |
39 cache line size of the processor caches. */ | |
40 | |
41 static char * | |
42 describe_cache (struct cache_desc level1, struct cache_desc level2) | |
43 { | |
44 char size[100], line[100], size2[100]; | |
45 | |
46 /* At the moment, gcc does not use the information | |
47 about the associativity of the cache. */ | |
48 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
49 snprintf (size, sizeof (size), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
50 "--param l1-cache-size=%u ", level1.sizekb); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
51 snprintf (line, sizeof (line), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
52 "--param l1-cache-line-size=%u ", level1.line); |
0 | 53 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
54 snprintf (size2, sizeof (size2), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
55 "--param l2-cache-size=%u ", level2.sizekb); |
0 | 56 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
57 return concat (size, line, size2, NULL); |
0 | 58 } |
59 | |
60 /* Detect L2 cache parameters using CPUID extended function 0x80000006. */ | |
61 | |
62 static void | |
63 detect_l2_cache (struct cache_desc *level2) | |
64 { | |
65 unsigned eax, ebx, ecx, edx; | |
66 unsigned assoc; | |
67 | |
68 __cpuid (0x80000006, eax, ebx, ecx, edx); | |
69 | |
70 level2->sizekb = (ecx >> 16) & 0xffff; | |
71 level2->line = ecx & 0xff; | |
72 | |
73 assoc = (ecx >> 12) & 0xf; | |
74 if (assoc == 6) | |
75 assoc = 8; | |
76 else if (assoc == 8) | |
77 assoc = 16; | |
78 else if (assoc >= 0xa && assoc <= 0xc) | |
79 assoc = 32 + (assoc - 0xa) * 16; | |
80 else if (assoc >= 0xd && assoc <= 0xe) | |
81 assoc = 96 + (assoc - 0xd) * 32; | |
82 | |
83 level2->assoc = assoc; | |
84 } | |
85 | |
86 /* Returns the description of caches for an AMD processor. */ | |
87 | |
88 static const char * | |
89 detect_caches_amd (unsigned max_ext_level) | |
90 { | |
91 unsigned eax, ebx, ecx, edx; | |
92 | |
93 struct cache_desc level1, level2 = {0, 0, 0}; | |
94 | |
95 if (max_ext_level < 0x80000005) | |
96 return ""; | |
97 | |
98 __cpuid (0x80000005, eax, ebx, ecx, edx); | |
99 | |
100 level1.sizekb = (ecx >> 24) & 0xff; | |
101 level1.assoc = (ecx >> 16) & 0xff; | |
102 level1.line = ecx & 0xff; | |
103 | |
104 if (max_ext_level >= 0x80000006) | |
105 detect_l2_cache (&level2); | |
106 | |
107 return describe_cache (level1, level2); | |
108 } | |
109 | |
110 /* Decodes the size, the associativity and the cache line size of | |
111 L1/L2 caches of an Intel processor. Values are based on | |
112 "Intel Processor Identification and the CPUID Instruction" | |
113 [Application Note 485], revision -032, December 2007. */ | |
114 | |
115 static void | |
116 decode_caches_intel (unsigned reg, bool xeon_mp, | |
117 struct cache_desc *level1, struct cache_desc *level2) | |
118 { | |
119 int i; | |
120 | |
121 for (i = 24; i >= 0; i -= 8) | |
122 switch ((reg >> i) & 0xff) | |
123 { | |
124 case 0x0a: | |
125 level1->sizekb = 8; level1->assoc = 2; level1->line = 32; | |
126 break; | |
127 case 0x0c: | |
128 level1->sizekb = 16; level1->assoc = 4; level1->line = 32; | |
129 break; | |
130 case 0x2c: | |
131 level1->sizekb = 32; level1->assoc = 8; level1->line = 64; | |
132 break; | |
133 case 0x39: | |
134 level2->sizekb = 128; level2->assoc = 4; level2->line = 64; | |
135 break; | |
136 case 0x3a: | |
137 level2->sizekb = 192; level2->assoc = 6; level2->line = 64; | |
138 break; | |
139 case 0x3b: | |
140 level2->sizekb = 128; level2->assoc = 2; level2->line = 64; | |
141 break; | |
142 case 0x3c: | |
143 level2->sizekb = 256; level2->assoc = 4; level2->line = 64; | |
144 break; | |
145 case 0x3d: | |
146 level2->sizekb = 384; level2->assoc = 6; level2->line = 64; | |
147 break; | |
148 case 0x3e: | |
149 level2->sizekb = 512; level2->assoc = 4; level2->line = 64; | |
150 break; | |
151 case 0x41: | |
152 level2->sizekb = 128; level2->assoc = 4; level2->line = 32; | |
153 break; | |
154 case 0x42: | |
155 level2->sizekb = 256; level2->assoc = 4; level2->line = 32; | |
156 break; | |
157 case 0x43: | |
158 level2->sizekb = 512; level2->assoc = 4; level2->line = 32; | |
159 break; | |
160 case 0x44: | |
161 level2->sizekb = 1024; level2->assoc = 4; level2->line = 32; | |
162 break; | |
163 case 0x45: | |
164 level2->sizekb = 2048; level2->assoc = 4; level2->line = 32; | |
165 break; | |
166 case 0x49: | |
167 if (xeon_mp) | |
168 break; | |
169 level2->sizekb = 4096; level2->assoc = 16; level2->line = 64; | |
170 break; | |
171 case 0x4e: | |
172 level2->sizekb = 6144; level2->assoc = 24; level2->line = 64; | |
173 break; | |
174 case 0x60: | |
175 level1->sizekb = 16; level1->assoc = 8; level1->line = 64; | |
176 break; | |
177 case 0x66: | |
178 level1->sizekb = 8; level1->assoc = 4; level1->line = 64; | |
179 break; | |
180 case 0x67: | |
181 level1->sizekb = 16; level1->assoc = 4; level1->line = 64; | |
182 break; | |
183 case 0x68: | |
184 level1->sizekb = 32; level1->assoc = 4; level1->line = 64; | |
185 break; | |
186 case 0x78: | |
187 level2->sizekb = 1024; level2->assoc = 4; level2->line = 64; | |
188 break; | |
189 case 0x79: | |
190 level2->sizekb = 128; level2->assoc = 8; level2->line = 64; | |
191 break; | |
192 case 0x7a: | |
193 level2->sizekb = 256; level2->assoc = 8; level2->line = 64; | |
194 break; | |
195 case 0x7b: | |
196 level2->sizekb = 512; level2->assoc = 8; level2->line = 64; | |
197 break; | |
198 case 0x7c: | |
199 level2->sizekb = 1024; level2->assoc = 8; level2->line = 64; | |
200 break; | |
201 case 0x7d: | |
202 level2->sizekb = 2048; level2->assoc = 8; level2->line = 64; | |
203 break; | |
204 case 0x7f: | |
205 level2->sizekb = 512; level2->assoc = 2; level2->line = 64; | |
206 break; | |
207 case 0x82: | |
208 level2->sizekb = 256; level2->assoc = 8; level2->line = 32; | |
209 break; | |
210 case 0x83: | |
211 level2->sizekb = 512; level2->assoc = 8; level2->line = 32; | |
212 break; | |
213 case 0x84: | |
214 level2->sizekb = 1024; level2->assoc = 8; level2->line = 32; | |
215 break; | |
216 case 0x85: | |
217 level2->sizekb = 2048; level2->assoc = 8; level2->line = 32; | |
218 break; | |
219 case 0x86: | |
220 level2->sizekb = 512; level2->assoc = 4; level2->line = 64; | |
221 break; | |
222 case 0x87: | |
223 level2->sizekb = 1024; level2->assoc = 8; level2->line = 64; | |
224 | |
225 default: | |
226 break; | |
227 } | |
228 } | |
229 | |
230 /* Detect cache parameters using CPUID function 2. */ | |
231 | |
232 static void | |
233 detect_caches_cpuid2 (bool xeon_mp, | |
234 struct cache_desc *level1, struct cache_desc *level2) | |
235 { | |
236 unsigned regs[4]; | |
237 int nreps, i; | |
238 | |
239 __cpuid (2, regs[0], regs[1], regs[2], regs[3]); | |
240 | |
241 nreps = regs[0] & 0x0f; | |
242 regs[0] &= ~0x0f; | |
243 | |
244 while (--nreps >= 0) | |
245 { | |
246 for (i = 0; i < 4; i++) | |
247 if (regs[i] && !((regs[i] >> 31) & 1)) | |
248 decode_caches_intel (regs[i], xeon_mp, level1, level2); | |
249 | |
250 if (nreps) | |
251 __cpuid (2, regs[0], regs[1], regs[2], regs[3]); | |
252 } | |
253 } | |
254 | |
255 /* Detect cache parameters using CPUID function 4. This | |
256 method doesn't require hardcoded tables. */ | |
257 | |
258 enum cache_type | |
259 { | |
260 CACHE_END = 0, | |
261 CACHE_DATA = 1, | |
262 CACHE_INST = 2, | |
263 CACHE_UNIFIED = 3 | |
264 }; | |
265 | |
266 static void | |
267 detect_caches_cpuid4 (struct cache_desc *level1, struct cache_desc *level2) | |
268 { | |
269 struct cache_desc *cache; | |
270 | |
271 unsigned eax, ebx, ecx, edx; | |
272 int count; | |
273 | |
274 for (count = 0;; count++) | |
275 { | |
276 __cpuid_count(4, count, eax, ebx, ecx, edx); | |
277 switch (eax & 0x1f) | |
278 { | |
279 case CACHE_END: | |
280 return; | |
281 case CACHE_DATA: | |
282 case CACHE_UNIFIED: | |
283 { | |
284 switch ((eax >> 5) & 0x07) | |
285 { | |
286 case 1: | |
287 cache = level1; | |
288 break; | |
289 case 2: | |
290 cache = level2; | |
291 break; | |
292 default: | |
293 cache = NULL; | |
294 } | |
295 | |
296 if (cache) | |
297 { | |
298 unsigned sets = ecx + 1; | |
299 unsigned part = ((ebx >> 12) & 0x03ff) + 1; | |
300 | |
301 cache->assoc = ((ebx >> 22) & 0x03ff) + 1; | |
302 cache->line = (ebx & 0x0fff) + 1; | |
303 | |
304 cache->sizekb = (cache->assoc * part | |
305 * cache->line * sets) / 1024; | |
306 } | |
307 } | |
308 default: | |
309 break; | |
310 } | |
311 } | |
312 } | |
313 | |
314 /* Returns the description of caches for an Intel processor. */ | |
315 | |
316 static const char * | |
317 detect_caches_intel (bool xeon_mp, unsigned max_level, unsigned max_ext_level) | |
318 { | |
319 struct cache_desc level1 = {0, 0, 0}, level2 = {0, 0, 0}; | |
320 | |
321 if (max_level >= 4) | |
322 detect_caches_cpuid4 (&level1, &level2); | |
323 else if (max_level >= 2) | |
324 detect_caches_cpuid2 (xeon_mp, &level1, &level2); | |
325 else | |
326 return ""; | |
327 | |
328 if (level1.sizekb == 0) | |
329 return ""; | |
330 | |
331 /* Intel CPUs are equipped with AMD style L2 cache info. Try this | |
332 method if other methods fail to provide L2 cache parameters. */ | |
333 if (level2.sizekb == 0 && max_ext_level >= 0x80000006) | |
334 detect_l2_cache (&level2); | |
335 | |
336 return describe_cache (level1, level2); | |
337 } | |
338 | |
339 enum vendor_signatures | |
340 { | |
341 SIG_INTEL = 0x756e6547 /* Genu */, | |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
342 SIG_AMD = 0x68747541 /* Auth */ |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
343 }; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
344 |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
345 enum processor_signatures |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
346 { |
0 | 347 SIG_GEODE = 0x646f6547 /* Geod */ |
348 }; | |
349 | |
350 /* This will be called by the spec parser in gcc.c when it sees | |
351 a %:local_cpu_detect(args) construct. Currently it will be called | |
352 with either "arch" or "tune" as argument depending on if -march=native | |
353 or -mtune=native is to be substituted. | |
354 | |
355 It returns a string containing new command line parameters to be | |
356 put at the place of the above two options, depending on what CPU | |
357 this is executed. E.g. "-march=k8" on an AMD64 machine | |
358 for -march=native. | |
359 | |
360 ARGC and ARGV are set depending on the actual arguments given | |
361 in the spec. */ | |
362 | |
363 const char *host_detect_local_cpu (int argc, const char **argv) | |
364 { | |
365 enum processor_type processor = PROCESSOR_I386; | |
366 const char *cpu = "i386"; | |
367 | |
368 const char *cache = ""; | |
369 const char *options = ""; | |
370 | |
371 unsigned int eax, ebx, ecx, edx; | |
372 | |
373 unsigned int max_level, ext_level; | |
374 | |
375 unsigned int vendor; | |
376 unsigned int model, family; | |
377 | |
378 unsigned int has_sse3, has_ssse3, has_cmpxchg16b; | |
379 unsigned int has_cmpxchg8b, has_cmov, has_mmx, has_sse, has_sse2; | |
380 | |
381 /* Extended features */ | |
382 unsigned int has_lahf_lm = 0, has_sse4a = 0; | |
383 unsigned int has_longmode = 0, has_3dnowp = 0, has_3dnow = 0; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
384 unsigned int has_movbe = 0, has_sse4_1 = 0, has_sse4_2 = 0; |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
385 unsigned int has_popcnt = 0, has_aes = 0, has_avx = 0; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
386 unsigned int has_pclmul = 0, has_abm = 0, has_lwp = 0; |
0 | 387 |
388 bool arch; | |
389 | |
390 if (argc < 1) | |
391 return NULL; | |
392 | |
393 arch = !strcmp (argv[0], "arch"); | |
394 | |
395 if (!arch && strcmp (argv[0], "tune")) | |
396 return NULL; | |
397 | |
398 max_level = __get_cpuid_max (0, &vendor); | |
399 if (max_level < 1) | |
400 goto done; | |
401 | |
402 __cpuid (1, eax, ebx, ecx, edx); | |
403 | |
404 model = (eax >> 4) & 0x0f; | |
405 family = (eax >> 8) & 0x0f; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
406 if (vendor == SIG_INTEL) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
407 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
408 unsigned int extended_model, extended_family; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
409 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
410 extended_model = (eax >> 12) & 0xf0; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
411 extended_family = (eax >> 20) & 0xff; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
412 if (family == 0x0f) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
413 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
414 family += extended_family; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
415 model += extended_model; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
416 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
417 else if (family == 0x06) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
418 model += extended_model; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
419 } |
0 | 420 |
421 has_sse3 = ecx & bit_SSE3; | |
422 has_ssse3 = ecx & bit_SSSE3; | |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
423 has_sse4_1 = ecx & bit_SSE4_1; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
424 has_sse4_2 = ecx & bit_SSE4_2; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
425 has_avx = ecx & bit_AVX; |
0 | 426 has_cmpxchg16b = ecx & bit_CMPXCHG16B; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
427 has_movbe = ecx & bit_MOVBE; |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
428 has_popcnt = ecx & bit_POPCNT; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
429 has_aes = ecx & bit_AES; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
430 has_pclmul = ecx & bit_PCLMUL; |
0 | 431 |
432 has_cmpxchg8b = edx & bit_CMPXCHG8B; | |
433 has_cmov = edx & bit_CMOV; | |
434 has_mmx = edx & bit_MMX; | |
435 has_sse = edx & bit_SSE; | |
436 has_sse2 = edx & bit_SSE2; | |
437 | |
438 /* Check cpuid level of extended features. */ | |
439 __cpuid (0x80000000, ext_level, ebx, ecx, edx); | |
440 | |
441 if (ext_level > 0x80000000) | |
442 { | |
443 __cpuid (0x80000001, eax, ebx, ecx, edx); | |
444 | |
445 has_lahf_lm = ecx & bit_LAHF_LM; | |
446 has_sse4a = ecx & bit_SSE4a; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
447 has_abm = ecx & bit_ABM; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
448 has_lwp = ecx & bit_LWP; |
0 | 449 |
450 has_longmode = edx & bit_LM; | |
451 has_3dnowp = edx & bit_3DNOWP; | |
452 has_3dnow = edx & bit_3DNOW; | |
453 } | |
454 | |
455 if (!arch) | |
456 { | |
457 if (vendor == SIG_AMD) | |
458 cache = detect_caches_amd (ext_level); | |
459 else if (vendor == SIG_INTEL) | |
460 { | |
461 bool xeon_mp = (family == 15 && model == 6); | |
462 cache = detect_caches_intel (xeon_mp, max_level, ext_level); | |
463 } | |
464 } | |
465 | |
466 if (vendor == SIG_AMD) | |
467 { | |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
468 unsigned int name; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
469 |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
470 /* Detect geode processor by its processor signature. */ |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
471 if (ext_level > 0x80000001) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
472 __cpuid (0x80000002, name, ebx, ecx, edx); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
473 else |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
474 name = 0; |
0 | 475 |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
476 if (name == SIG_GEODE) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
477 processor = PROCESSOR_GEODE; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
478 else if (has_sse4a) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
479 processor = PROCESSOR_AMDFAM10; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
480 else if (has_sse2 || has_longmode) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
481 processor = PROCESSOR_K8; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
482 else if (has_3dnowp) |
0 | 483 processor = PROCESSOR_ATHLON; |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
484 else if (has_mmx) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
485 processor = PROCESSOR_K6; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
486 else |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
487 processor = PROCESSOR_PENTIUM; |
0 | 488 } |
489 else | |
490 { | |
491 switch (family) | |
492 { | |
493 case 4: | |
494 processor = PROCESSOR_I486; | |
495 break; | |
496 case 5: | |
497 processor = PROCESSOR_PENTIUM; | |
498 break; | |
499 case 6: | |
500 processor = PROCESSOR_PENTIUMPRO; | |
501 break; | |
502 case 15: | |
503 processor = PROCESSOR_PENTIUM4; | |
504 break; | |
505 default: | |
506 /* We have no idea. */ | |
507 processor = PROCESSOR_GENERIC32; | |
508 } | |
509 } | |
510 | |
511 switch (processor) | |
512 { | |
513 case PROCESSOR_I386: | |
514 /* Default. */ | |
515 break; | |
516 case PROCESSOR_I486: | |
517 cpu = "i486"; | |
518 break; | |
519 case PROCESSOR_PENTIUM: | |
520 if (arch && has_mmx) | |
521 cpu = "pentium-mmx"; | |
522 else | |
523 cpu = "pentium"; | |
524 break; | |
525 case PROCESSOR_PENTIUMPRO: | |
526 if (has_longmode) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
527 /* It is Core 2 or Atom. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
528 cpu = (model == 28) ? "atom" : "core2"; |
0 | 529 else if (arch) |
530 { | |
531 if (has_sse3) | |
532 /* It is Core Duo. */ | |
533 cpu = "prescott"; | |
534 else if (has_sse2) | |
535 /* It is Pentium M. */ | |
536 cpu = "pentium-m"; | |
537 else if (has_sse) | |
538 /* It is Pentium III. */ | |
539 cpu = "pentium3"; | |
540 else if (has_mmx) | |
541 /* It is Pentium II. */ | |
542 cpu = "pentium2"; | |
543 else | |
544 /* Default to Pentium Pro. */ | |
545 cpu = "pentiumpro"; | |
546 } | |
547 else | |
548 /* For -mtune, we default to -mtune=generic. */ | |
549 cpu = "generic"; | |
550 break; | |
551 case PROCESSOR_PENTIUM4: | |
552 if (has_sse3) | |
553 { | |
554 if (has_longmode) | |
555 cpu = "nocona"; | |
556 else | |
557 cpu = "prescott"; | |
558 } | |
559 else | |
560 cpu = "pentium4"; | |
561 break; | |
562 case PROCESSOR_GEODE: | |
563 cpu = "geode"; | |
564 break; | |
565 case PROCESSOR_K6: | |
566 if (arch && has_3dnow) | |
567 cpu = "k6-3"; | |
568 else | |
569 cpu = "k6"; | |
570 break; | |
571 case PROCESSOR_ATHLON: | |
572 if (arch && has_sse) | |
573 cpu = "athlon-4"; | |
574 else | |
575 cpu = "athlon"; | |
576 break; | |
577 case PROCESSOR_K8: | |
578 if (arch && has_sse3) | |
579 cpu = "k8-sse3"; | |
580 else | |
581 cpu = "k8"; | |
582 break; | |
583 case PROCESSOR_AMDFAM10: | |
584 cpu = "amdfam10"; | |
585 break; | |
586 | |
587 default: | |
588 /* Use something reasonable. */ | |
589 if (arch) | |
590 { | |
591 if (has_ssse3) | |
592 cpu = "core2"; | |
593 else if (has_sse3) | |
594 { | |
595 if (has_longmode) | |
596 cpu = "nocona"; | |
597 else | |
598 cpu = "prescott"; | |
599 } | |
600 else if (has_sse2) | |
601 cpu = "pentium4"; | |
602 else if (has_cmov) | |
603 cpu = "pentiumpro"; | |
604 else if (has_mmx) | |
605 cpu = "pentium-mmx"; | |
606 else if (has_cmpxchg8b) | |
607 cpu = "pentium"; | |
608 } | |
609 else | |
610 cpu = "generic"; | |
611 } | |
612 | |
613 if (arch) | |
614 { | |
615 if (has_cmpxchg16b) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
616 options = concat (options, " -mcx16", NULL); |
0 | 617 if (has_lahf_lm) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
618 options = concat (options, " -msahf", NULL); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
619 if (has_movbe) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
620 options = concat (options, " -mmovbe", NULL); |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
621 if (has_aes) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
622 options = concat (options, " -maes", NULL); |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
623 if (has_pclmul) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
624 options = concat (options, " -mpclmul", NULL); |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
625 if (has_popcnt) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
626 options = concat (options, " -mpopcnt", NULL); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
627 if (has_abm) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
628 options = concat (options, " -mabm", NULL); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
629 if (has_lwp) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
630 options = concat (options, " -mlwp", NULL); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
631 |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
632 if (has_avx) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
633 options = concat (options, " -mavx", NULL); |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
634 else if (has_sse4_2) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
635 options = concat (options, " -msse4.2", NULL); |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
636 else if (has_sse4_1) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
637 options = concat (options, " -msse4.1", NULL); |
0 | 638 } |
639 | |
640 done: | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
641 return concat (cache, "-m", argv[0], "=", cpu, options, NULL); |
0 | 642 } |
643 #else | |
644 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
645 /* If we aren't compiling with GCC then the driver will just ignore |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
646 -march and -mtune "native" target and will leave to the newly |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
647 built compiler to generate code for its default target. */ |
0 | 648 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
649 const char *host_detect_local_cpu (int argc ATTRIBUTE_UNUSED, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
650 const char **argv ATTRIBUTE_UNUSED) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
651 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
652 return NULL; |
0 | 653 } |
654 #endif /* __GNUC__ */ |