Line data Source code
1 : /* Subroutines for the gcc driver.
2 : Copyright (C) 2006-2026 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 : #define IN_TARGET_CODE 1
21 :
22 : #include "config.h"
23 : #include "system.h"
24 : #include "coretypes.h"
25 : #include "tm.h"
26 : #include "diagnostic.h"
27 :
28 : const char *host_detect_local_cpu (int argc, const char **argv);
29 :
30 : #if defined(__GNUC__) && (__GNUC__ >= 5 || !defined(__PIC__))
31 : #include "cpuid.h"
32 : #include "common/config/i386/cpuinfo.h"
33 : #include "common/config/i386/i386-isas.h"
34 :
35 : struct cache_desc
36 : {
37 : unsigned sizekb;
38 : unsigned assoc;
39 : unsigned line;
40 : };
41 :
42 : /* Returns command line parameters that describe size and
43 : cache line size of the processor caches. */
44 :
45 : static char *
46 11 : describe_cache (struct cache_desc level1, struct cache_desc level2)
47 : {
48 11 : char size[100], line[100], size2[100];
49 :
50 : /* At the moment, gcc does not use the information
51 : about the associativity of the cache. */
52 :
53 11 : snprintf (size, sizeof (size),
54 : "--param l1-cache-size=%u ", level1.sizekb);
55 11 : snprintf (line, sizeof (line),
56 : "--param l1-cache-line-size=%u ", level1.line);
57 :
58 11 : snprintf (size2, sizeof (size2),
59 : "--param l2-cache-size=%u ", level2.sizekb);
60 :
61 11 : return concat (size, line, size2, NULL);
62 : }
63 :
64 : /* Detect L2 cache parameters using CPUID extended function 0x80000006. */
65 :
66 : static void
67 11 : detect_l2_cache (struct cache_desc *level2)
68 : {
69 11 : unsigned eax, ebx, ecx, edx;
70 11 : unsigned assoc;
71 :
72 11 : __cpuid (0x80000006, eax, ebx, ecx, edx);
73 :
74 11 : level2->sizekb = (ecx >> 16) & 0xffff;
75 11 : level2->line = ecx & 0xff;
76 :
77 11 : assoc = (ecx >> 12) & 0xf;
78 11 : if (assoc == 6)
79 : assoc = 8;
80 0 : else if (assoc == 8)
81 : assoc = 16;
82 0 : else if (assoc >= 0xa && assoc <= 0xc)
83 0 : assoc = 32 + (assoc - 0xa) * 16;
84 0 : else if (assoc >= 0xd && assoc <= 0xe)
85 0 : assoc = 96 + (assoc - 0xd) * 32;
86 :
87 11 : level2->assoc = assoc;
88 11 : }
89 :
90 : /* Returns the description of caches for an AMD processor. */
91 :
92 : static const char *
93 11 : detect_caches_amd (unsigned max_ext_level)
94 : {
95 11 : unsigned eax, ebx, ecx, edx;
96 :
97 11 : struct cache_desc level1, level2 = {0, 0, 0};
98 :
99 11 : if (max_ext_level < 0x80000005)
100 : return "";
101 :
102 11 : __cpuid (0x80000005, eax, ebx, ecx, edx);
103 :
104 11 : level1.sizekb = (ecx >> 24) & 0xff;
105 11 : level1.assoc = (ecx >> 16) & 0xff;
106 11 : level1.line = ecx & 0xff;
107 :
108 11 : if (max_ext_level >= 0x80000006)
109 11 : detect_l2_cache (&level2);
110 :
111 11 : return describe_cache (level1, level2);
112 : }
113 :
114 : /* Decodes the size, the associativity and the cache line size of
115 : L1/L2 caches of an Intel processor. Values are based on
116 : "Intel Processor Identification and the CPUID Instruction"
117 : [Application Note 485], revision -032, December 2007. */
118 :
119 : static void
120 0 : decode_caches_intel (unsigned reg, bool xeon_mp,
121 : struct cache_desc *level1, struct cache_desc *level2)
122 : {
123 0 : int i;
124 :
125 0 : for (i = 24; i >= 0; i -= 8)
126 0 : switch ((reg >> i) & 0xff)
127 : {
128 0 : case 0x0a:
129 0 : level1->sizekb = 8; level1->assoc = 2; level1->line = 32;
130 0 : break;
131 0 : case 0x0c:
132 0 : level1->sizekb = 16; level1->assoc = 4; level1->line = 32;
133 0 : break;
134 0 : case 0x0d:
135 0 : level1->sizekb = 16; level1->assoc = 4; level1->line = 64;
136 0 : break;
137 0 : case 0x0e:
138 0 : level1->sizekb = 24; level1->assoc = 6; level1->line = 64;
139 0 : break;
140 0 : case 0x21:
141 0 : level2->sizekb = 256; level2->assoc = 8; level2->line = 64;
142 0 : break;
143 0 : case 0x24:
144 0 : level2->sizekb = 1024; level2->assoc = 16; level2->line = 64;
145 0 : break;
146 0 : case 0x2c:
147 0 : level1->sizekb = 32; level1->assoc = 8; level1->line = 64;
148 0 : break;
149 0 : case 0x39:
150 0 : level2->sizekb = 128; level2->assoc = 4; level2->line = 64;
151 0 : break;
152 0 : case 0x3a:
153 0 : level2->sizekb = 192; level2->assoc = 6; level2->line = 64;
154 0 : break;
155 0 : case 0x3b:
156 0 : level2->sizekb = 128; level2->assoc = 2; level2->line = 64;
157 0 : break;
158 0 : case 0x3c:
159 0 : level2->sizekb = 256; level2->assoc = 4; level2->line = 64;
160 0 : break;
161 0 : case 0x3d:
162 0 : level2->sizekb = 384; level2->assoc = 6; level2->line = 64;
163 0 : break;
164 0 : case 0x3e:
165 0 : level2->sizekb = 512; level2->assoc = 4; level2->line = 64;
166 0 : break;
167 0 : case 0x41:
168 0 : level2->sizekb = 128; level2->assoc = 4; level2->line = 32;
169 0 : break;
170 0 : case 0x42:
171 0 : level2->sizekb = 256; level2->assoc = 4; level2->line = 32;
172 0 : break;
173 0 : case 0x43:
174 0 : level2->sizekb = 512; level2->assoc = 4; level2->line = 32;
175 0 : break;
176 0 : case 0x44:
177 0 : level2->sizekb = 1024; level2->assoc = 4; level2->line = 32;
178 0 : break;
179 0 : case 0x45:
180 0 : level2->sizekb = 2048; level2->assoc = 4; level2->line = 32;
181 0 : break;
182 0 : case 0x48:
183 0 : level2->sizekb = 3072; level2->assoc = 12; level2->line = 64;
184 0 : break;
185 0 : case 0x49:
186 0 : if (xeon_mp)
187 : break;
188 0 : level2->sizekb = 4096; level2->assoc = 16; level2->line = 64;
189 0 : break;
190 0 : case 0x4e:
191 0 : level2->sizekb = 6144; level2->assoc = 24; level2->line = 64;
192 0 : break;
193 0 : case 0x60:
194 0 : level1->sizekb = 16; level1->assoc = 8; level1->line = 64;
195 0 : break;
196 0 : case 0x66:
197 0 : level1->sizekb = 8; level1->assoc = 4; level1->line = 64;
198 0 : break;
199 0 : case 0x67:
200 0 : level1->sizekb = 16; level1->assoc = 4; level1->line = 64;
201 0 : break;
202 0 : case 0x68:
203 0 : level1->sizekb = 32; level1->assoc = 4; level1->line = 64;
204 0 : break;
205 0 : case 0x78:
206 0 : level2->sizekb = 1024; level2->assoc = 4; level2->line = 64;
207 0 : break;
208 0 : case 0x79:
209 0 : level2->sizekb = 128; level2->assoc = 8; level2->line = 64;
210 0 : break;
211 0 : case 0x7a:
212 0 : level2->sizekb = 256; level2->assoc = 8; level2->line = 64;
213 0 : break;
214 0 : case 0x7b:
215 0 : level2->sizekb = 512; level2->assoc = 8; level2->line = 64;
216 0 : break;
217 0 : case 0x7c:
218 0 : level2->sizekb = 1024; level2->assoc = 8; level2->line = 64;
219 0 : break;
220 0 : case 0x7d:
221 0 : level2->sizekb = 2048; level2->assoc = 8; level2->line = 64;
222 0 : break;
223 0 : case 0x7f:
224 0 : level2->sizekb = 512; level2->assoc = 2; level2->line = 64;
225 0 : break;
226 0 : case 0x80:
227 0 : level2->sizekb = 512; level2->assoc = 8; level2->line = 64;
228 0 : break;
229 0 : case 0x82:
230 0 : level2->sizekb = 256; level2->assoc = 8; level2->line = 32;
231 0 : break;
232 0 : case 0x83:
233 0 : level2->sizekb = 512; level2->assoc = 8; level2->line = 32;
234 0 : break;
235 0 : case 0x84:
236 0 : level2->sizekb = 1024; level2->assoc = 8; level2->line = 32;
237 0 : break;
238 0 : case 0x85:
239 0 : level2->sizekb = 2048; level2->assoc = 8; level2->line = 32;
240 0 : break;
241 0 : case 0x86:
242 0 : level2->sizekb = 512; level2->assoc = 4; level2->line = 64;
243 0 : break;
244 0 : case 0x87:
245 0 : level2->sizekb = 1024; level2->assoc = 8; level2->line = 64;
246 :
247 : default:
248 : break;
249 : }
250 0 : }
251 :
252 : /* Detect cache parameters using CPUID function 2. */
253 :
254 : static void
255 0 : detect_caches_cpuid2 (bool xeon_mp,
256 : struct cache_desc *level1, struct cache_desc *level2)
257 : {
258 0 : unsigned regs[4];
259 0 : int nreps, i;
260 :
261 0 : __cpuid (2, regs[0], regs[1], regs[2], regs[3]);
262 :
263 0 : nreps = regs[0] & 0x0f;
264 0 : regs[0] &= ~0x0f;
265 :
266 0 : while (--nreps >= 0)
267 : {
268 0 : for (i = 0; i < 4; i++)
269 0 : if (regs[i] && !((regs[i] >> 31) & 1))
270 0 : decode_caches_intel (regs[i], xeon_mp, level1, level2);
271 :
272 0 : if (nreps)
273 0 : __cpuid (2, regs[0], regs[1], regs[2], regs[3]);
274 : }
275 0 : }
276 :
277 : /* Detect cache parameters using CPUID function 4. This
278 : method doesn't require hardcoded tables. */
279 :
280 : enum cache_type
281 : {
282 : CACHE_END = 0,
283 : CACHE_DATA = 1,
284 : CACHE_INST = 2,
285 : CACHE_UNIFIED = 3
286 : };
287 :
288 : static void
289 0 : detect_caches_cpuid4 (struct cache_desc *level1, struct cache_desc *level2,
290 : struct cache_desc *level3)
291 : {
292 0 : struct cache_desc *cache;
293 :
294 0 : unsigned eax, ebx, ecx, edx;
295 0 : int count;
296 :
297 0 : for (count = 0;; count++)
298 : {
299 0 : __cpuid_count(4, count, eax, ebx, ecx, edx);
300 0 : switch (eax & 0x1f)
301 : {
302 0 : case CACHE_END:
303 0 : return;
304 0 : case CACHE_DATA:
305 0 : case CACHE_UNIFIED:
306 0 : {
307 0 : switch ((eax >> 5) & 0x07)
308 : {
309 : case 1:
310 : cache = level1;
311 : break;
312 0 : case 2:
313 0 : cache = level2;
314 0 : break;
315 0 : case 3:
316 0 : cache = level3;
317 0 : break;
318 : default:
319 : cache = NULL;
320 : }
321 :
322 0 : if (cache)
323 : {
324 0 : unsigned sets = ecx + 1;
325 0 : unsigned part = ((ebx >> 12) & 0x03ff) + 1;
326 :
327 0 : cache->assoc = ((ebx >> 22) & 0x03ff) + 1;
328 0 : cache->line = (ebx & 0x0fff) + 1;
329 :
330 0 : cache->sizekb = (cache->assoc * part
331 0 : * cache->line * sets) / 1024;
332 : }
333 : }
334 0 : default:
335 0 : break;
336 : }
337 0 : }
338 : }
339 :
340 : /* Returns the description of caches for an Intel processor. */
341 :
342 : static const char *
343 0 : detect_caches_intel (bool xeon_mp, unsigned max_level,
344 : unsigned max_ext_level, unsigned *l2sizekb)
345 : {
346 0 : struct cache_desc level1 = {0, 0, 0}, level2 = {0, 0, 0}, level3 = {0, 0, 0};
347 :
348 0 : if (max_level >= 4)
349 0 : detect_caches_cpuid4 (&level1, &level2, &level3);
350 0 : else if (max_level >= 2)
351 0 : detect_caches_cpuid2 (xeon_mp, &level1, &level2);
352 : else
353 : return "";
354 :
355 0 : if (level1.sizekb == 0)
356 : return "";
357 :
358 : /* Let the L3 replace the L2. This assumes inclusive caches
359 : and single threaded program for now. */
360 0 : if (level3.sizekb)
361 0 : level2 = level3;
362 :
363 : /* Intel CPUs are equipped with AMD style L2 cache info. Try this
364 : method if other methods fail to provide L2 cache parameters. */
365 0 : if (level2.sizekb == 0 && max_ext_level >= 0x80000006)
366 0 : detect_l2_cache (&level2);
367 :
368 0 : *l2sizekb = level2.sizekb;
369 :
370 0 : return describe_cache (level1, level2);
371 : }
372 :
373 : /* Extended features */
374 : #define has_feature(f) \
375 : has_cpu_feature (&cpu_model, cpu_features2, f)
376 :
377 : /* This will be called by the spec parser in gcc.cc when it sees
378 : a %:local_cpu_detect(args) construct. Currently it will be
379 : called with either "arch [32|64]" or "tune [32|64]" as argument
380 : depending on if -march=native or -mtune=native is to be substituted.
381 :
382 : It returns a string containing new command line parameters to be
383 : put at the place of the above two options, depending on what CPU
384 : this is executed. E.g. "-march=k8" on an AMD64 machine
385 : for -march=native.
386 :
387 : ARGC and ARGV are set depending on the actual arguments given
388 : in the spec. */
389 :
390 1348 : const char *host_detect_local_cpu (int argc, const char **argv)
391 : {
392 1348 : enum processor_type processor = PROCESSOR_I386;
393 1348 : const char *cpu = "i386";
394 :
395 1348 : const char *cache = "";
396 1348 : const char *options = "";
397 :
398 1348 : unsigned int ebx, ecx, edx;
399 :
400 1348 : unsigned int max_level, ext_level;
401 :
402 1348 : unsigned int vendor;
403 1348 : unsigned int model, family;
404 :
405 1348 : bool arch;
406 :
407 1348 : unsigned int l2sizekb = 0;
408 :
409 1348 : if (argc < 2)
410 : return NULL;
411 :
412 1348 : arch = !strcmp (argv[0], "arch");
413 :
414 1348 : if (!arch && strcmp (argv[0], "tune"))
415 : return NULL;
416 :
417 1348 : bool codegen_x86_64;
418 :
419 1348 : if (!strcmp (argv[1], "32"))
420 : codegen_x86_64 = false;
421 1348 : else if (!strcmp (argv[1], "64"))
422 : codegen_x86_64 = true;
423 : else
424 : return NULL;
425 :
426 1348 : struct __processor_model cpu_model = { };
427 1348 : struct __processor_model2 cpu_model2 = { };
428 1348 : unsigned int cpu_features2[SIZE_OF_CPU_FEATURES] = { };
429 :
430 1348 : if (cpu_indicator_init (&cpu_model, &cpu_model2, cpu_features2) != 0)
431 0 : goto done;
432 :
433 1348 : vendor = cpu_model.__cpu_vendor;
434 1348 : family = cpu_model2.__cpu_family;
435 1348 : model = cpu_model2.__cpu_model;
436 1348 : max_level = cpu_model2.__cpu_max_level;
437 1348 : ext_level = cpu_model2.__cpu_ext_level;
438 :
439 1348 : if (!arch)
440 : {
441 11 : if (vendor == VENDOR_AMD
442 11 : || vendor == VENDOR_CENTAUR
443 : || vendor == VENDOR_CYRIX
444 0 : || vendor == VENDOR_NSC)
445 11 : cache = detect_caches_amd (ext_level);
446 0 : else if (vendor == VENDOR_INTEL
447 0 : || vendor == VENDOR_ZHAOXIN)
448 : {
449 0 : bool xeon_mp = (family == 15 && model == 6);
450 0 : cache = detect_caches_intel (xeon_mp, max_level,
451 : ext_level, &l2sizekb);
452 : }
453 : }
454 :
455 1348 : if (vendor == VENDOR_AMD)
456 : {
457 1348 : unsigned int name;
458 :
459 : /* Detect geode processor by its processor signature. */
460 1348 : if (ext_level >= 0x80000002)
461 1348 : __cpuid (0x80000002, name, ebx, ecx, edx);
462 : else
463 : name = 0;
464 :
465 1348 : if (name == signature_NSC_ebx)
466 : processor = PROCESSOR_GEODE;
467 1348 : else if (has_feature (FEATURE_MOVBE) && family == 22)
468 : processor = PROCESSOR_BTVER2;
469 1348 : else if (has_feature (FEATURE_AVX512BMM))
470 : processor = PROCESSOR_ZNVER6;
471 1348 : else if (has_feature (FEATURE_AVX512VP2INTERSECT))
472 : processor = PROCESSOR_ZNVER5;
473 1348 : else if (has_feature (FEATURE_AVX512F))
474 : processor = PROCESSOR_ZNVER4;
475 1348 : else if (has_feature (FEATURE_VAES))
476 : processor = PROCESSOR_ZNVER3;
477 1348 : else if (has_feature (FEATURE_CLWB))
478 : processor = PROCESSOR_ZNVER2;
479 0 : else if (has_feature (FEATURE_CLZERO))
480 : processor = PROCESSOR_ZNVER1;
481 0 : else if (has_feature (FEATURE_AVX2))
482 : processor = PROCESSOR_BDVER4;
483 0 : else if (has_feature (FEATURE_XSAVEOPT))
484 : processor = PROCESSOR_BDVER3;
485 0 : else if (has_feature (FEATURE_BMI))
486 : processor = PROCESSOR_BDVER2;
487 0 : else if (has_feature (FEATURE_XOP))
488 : processor = PROCESSOR_BDVER1;
489 0 : else if (has_feature (FEATURE_SSE4_A)
490 0 : && has_feature (FEATURE_SSSE3))
491 : processor = PROCESSOR_BTVER1;
492 0 : else if (has_feature (FEATURE_SSE4_A))
493 : processor = PROCESSOR_AMDFAM10;
494 0 : else if (has_feature (FEATURE_SSE2)
495 0 : || has_feature (FEATURE_LM))
496 : processor = PROCESSOR_K8;
497 0 : else if (has_feature (FEATURE_3DNOWP) && family == 6)
498 : processor = PROCESSOR_ATHLON;
499 0 : else if (has_feature (FEATURE_MMX))
500 : processor = PROCESSOR_K6;
501 : else
502 : processor = PROCESSOR_PENTIUM;
503 : }
504 0 : else if (vendor == VENDOR_CENTAUR)
505 : {
506 0 : processor = PROCESSOR_GENERIC;
507 :
508 0 : switch (family)
509 : {
510 : default:
511 : /* We have no idea. */
512 : break;
513 :
514 0 : case 5:
515 0 : if (has_feature (FEATURE_3DNOW)
516 0 : || has_feature (FEATURE_MMX))
517 : processor = PROCESSOR_I486;
518 : break;
519 :
520 0 : case 6:
521 0 : if (has_feature (FEATURE_LM))
522 : processor = PROCESSOR_K8;
523 0 : else if (model >= 9)
524 : processor = PROCESSOR_PENTIUMPRO;
525 0 : else if (model >= 6)
526 : processor = PROCESSOR_I486;
527 : }
528 : }
529 0 : else if (vendor == VENDOR_ZHAOXIN)
530 : {
531 0 : processor = PROCESSOR_GENERIC;
532 :
533 0 : switch (family)
534 : {
535 0 : case 7:
536 0 : if (model >= 0x6b)
537 : processor = PROCESSOR_SHIJIDADAO;
538 0 : else if (model == 0x5b)
539 : processor = PROCESSOR_YONGFENG;
540 0 : else if (model == 0x3b)
541 : processor = PROCESSOR_LUJIAZUI;
542 : break;
543 : default:
544 : break;
545 : }
546 : }
547 : else
548 : {
549 0 : switch (family)
550 : {
551 : case 4:
552 : processor = PROCESSOR_I486;
553 : break;
554 : case 5:
555 : processor = PROCESSOR_PENTIUM;
556 : break;
557 : case 6:
558 : case 18:
559 : case 19:
560 : processor = PROCESSOR_PENTIUMPRO;
561 : break;
562 0 : case 15:
563 0 : processor = PROCESSOR_PENTIUM4;
564 0 : break;
565 : default:
566 : /* We have no idea. */
567 : processor = PROCESSOR_GENERIC;
568 : }
569 : }
570 :
571 0 : switch (processor)
572 : {
573 : case PROCESSOR_I386:
574 : /* Default. */
575 : break;
576 0 : case PROCESSOR_I486:
577 0 : if (arch && vendor == VENDOR_CENTAUR)
578 : {
579 0 : if (model >= 6)
580 : cpu = "c3";
581 0 : else if (has_feature (FEATURE_3DNOW))
582 : cpu = "winchip2";
583 : else
584 : /* Assume WinChip C6. */
585 0 : cpu = "winchip-c6";
586 : }
587 : else
588 : cpu = "i486";
589 : break;
590 0 : case PROCESSOR_PENTIUM:
591 0 : if (arch && has_feature (FEATURE_MMX))
592 : cpu = "pentium-mmx";
593 : else
594 : cpu = "pentium";
595 : break;
596 0 : case PROCESSOR_PENTIUMPRO:
597 0 : cpu = get_intel_cpu (&cpu_model, &cpu_model2, cpu_features2);
598 0 : if (cpu == NULL)
599 : {
600 0 : if (arch)
601 : {
602 : /* This is unknown CPU. */
603 0 : if (has_feature (FEATURE_AVX512F))
604 : {
605 : /* Assume Diamond Rapids. */
606 0 : if (has_feature (FEATURE_AMX_FP8))
607 : cpu = "diamondrapids";
608 : /* Assume Nova Lake. */
609 0 : else if (has_feature (FEATURE_AVX10_2))
610 : cpu = "novalake";
611 : /* Assume Granite Rapids D. */
612 0 : else if (has_feature (FEATURE_AMX_COMPLEX))
613 : cpu = "graniterapids-d";
614 : /* Assume Granite Rapids. */
615 0 : else if (has_feature (FEATURE_AMX_FP16))
616 : cpu = "graniterapids";
617 : /* Assume Tiger Lake */
618 0 : else if (has_feature (FEATURE_AVX512VP2INTERSECT))
619 : cpu = "tigerlake";
620 : /* Assume Sapphire Rapids. */
621 0 : else if (has_feature (FEATURE_TSXLDTRK))
622 : cpu = "sapphirerapids";
623 : /* Assume Cooper Lake */
624 0 : else if (has_feature (FEATURE_AVX512BF16))
625 : cpu = "cooperlake";
626 : /* Assume Ice Lake Server. */
627 0 : else if (has_feature (FEATURE_WBNOINVD))
628 : cpu = "icelake-server";
629 : /* Assume Ice Lake. */
630 0 : else if (has_feature (FEATURE_AVX512BITALG))
631 : cpu = "icelake-client";
632 : /* Assume Cannon Lake. */
633 0 : else if (has_feature (FEATURE_AVX512VBMI))
634 : cpu = "cannonlake";
635 : /* Assume Xeon Phi Processors. Support has been removed
636 : since GCC 15. */
637 0 : else if (!has_feature (FEATURE_AVX512VL))
638 0 : error ("Xeon Phi ISA support has been removed since "
639 : "GCC 15, use GCC 14 for the Xeon Phi ISAs or "
640 : "%<-march=broadwell%> for all the other ISAs "
641 : "supported on this machine.");
642 : /* Assume Skylake with AVX-512. */
643 : else
644 : cpu = "skylake-avx512";
645 : }
646 0 : else if (has_feature (FEATURE_AVX))
647 : {
648 : /* Assume Clearwater Forest. */
649 0 : if (has_feature (FEATURE_USER_MSR))
650 : cpu = "clearwaterforest";
651 0 : else if (has_feature (FEATURE_SM3))
652 : {
653 0 : if (has_feature (FEATURE_KL))
654 : /* Assume Arrow Lake S. */
655 : cpu = "arrowlake-s";
656 : else
657 : /* Assume Panther Lake. */
658 0 : cpu = "pantherlake";
659 : }
660 : /* Assume Sierra Forest. */
661 0 : else if (has_feature (FEATURE_CLDEMOTE))
662 : cpu = "sierraforest";
663 : /* Assume Arrow Lake. */
664 0 : else if (has_feature (FEATURE_AVXVNNIINT8))
665 : cpu = "arrowlake";
666 : /* Assume Alder Lake. */
667 0 : else if (has_feature (FEATURE_SERIALIZE))
668 : cpu = "alderlake";
669 : /* Assume Skylake. */
670 0 : else if (has_feature (FEATURE_CLFLUSHOPT))
671 : cpu = "skylake";
672 : /* Assume Broadwell. */
673 0 : else if (has_feature (FEATURE_ADX))
674 : cpu = "broadwell";
675 : /* Assume Haswell. */
676 0 : else if (has_feature (FEATURE_AVX2))
677 : cpu = "haswell";
678 : /* Assume Sandy Bridge. */
679 : else
680 0 : cpu = "sandybridge";
681 : }
682 0 : else if (has_feature (FEATURE_SSE4_2))
683 : {
684 0 : if (has_feature (FEATURE_GFNI))
685 : /* Assume Tremont. */
686 : cpu = "tremont";
687 0 : else if (has_feature (FEATURE_SGX))
688 : /* Assume Goldmont Plus. */
689 : cpu = "goldmont-plus";
690 0 : else if (has_feature (FEATURE_XSAVE))
691 : /* Assume Goldmont. */
692 : cpu = "goldmont";
693 0 : else if (has_feature (FEATURE_MOVBE))
694 : /* Assume Silvermont. */
695 : cpu = "silvermont";
696 : else
697 : /* Assume Nehalem. */
698 0 : cpu = "nehalem";
699 : }
700 0 : else if (has_feature (FEATURE_SSSE3))
701 : {
702 0 : if (has_feature (FEATURE_MOVBE))
703 : /* Assume Bonnell. */
704 : cpu = "bonnell";
705 : else
706 : /* Assume Core 2. */
707 0 : cpu = "core2";
708 : }
709 0 : else if (has_feature (FEATURE_LM))
710 : /* Perhaps some emulator? Assume x86-64, otherwise gcc
711 : -march=native would be unusable for 64-bit compilations,
712 : as all the CPUs below are 32-bit only. */
713 : cpu = "x86-64";
714 0 : else if (has_feature (FEATURE_SSE3))
715 : {
716 0 : if (vendor == VENDOR_CENTAUR)
717 : /* C7 / Eden "Esther" */
718 : cpu = "c7";
719 : else
720 : /* It is Core Duo. */
721 0 : cpu = "pentium-m";
722 : }
723 0 : else if (has_feature (FEATURE_SSE2))
724 : /* It is Pentium M. */
725 : cpu = "pentium-m";
726 0 : else if (has_feature (FEATURE_SSE))
727 : {
728 0 : if (vendor == VENDOR_CENTAUR)
729 : {
730 0 : if (model >= 9)
731 : /* Eden "Nehemiah" */
732 : cpu = "nehemiah";
733 : else
734 0 : cpu = "c3-2";
735 : }
736 : else
737 : /* It is Pentium III. */
738 : cpu = "pentium3";
739 : }
740 0 : else if (has_feature (FEATURE_MMX))
741 : /* It is Pentium II. */
742 : cpu = "pentium2";
743 : else
744 : /* Default to Pentium Pro. */
745 0 : cpu = "pentiumpro";
746 : }
747 : else
748 : /* For -mtune, we default to -mtune=generic. */
749 : cpu = "generic";
750 : }
751 : break;
752 0 : case PROCESSOR_PENTIUM4:
753 0 : if (has_feature (FEATURE_SSE3))
754 : {
755 0 : if (has_feature (FEATURE_LM))
756 : cpu = "nocona";
757 : else
758 1348 : cpu = "prescott";
759 : }
760 : else
761 : cpu = "pentium4";
762 : break;
763 : case PROCESSOR_GEODE:
764 : cpu = "geode";
765 : break;
766 0 : case PROCESSOR_K6:
767 0 : if (arch && has_feature (FEATURE_3DNOW))
768 : cpu = "k6-3";
769 : else
770 : cpu = "k6";
771 : break;
772 0 : case PROCESSOR_ATHLON:
773 0 : if (arch && has_feature (FEATURE_SSE))
774 : cpu = "athlon-4";
775 : else
776 : cpu = "athlon";
777 : break;
778 0 : case PROCESSOR_K8:
779 0 : if (arch)
780 : {
781 0 : if (vendor == VENDOR_CENTAUR)
782 : {
783 0 : if (has_feature (FEATURE_SSE4_1))
784 : /* Nano 3000 | Nano dual / quad core | Eden X4 */
785 : cpu = "nano-3000";
786 0 : else if (has_feature (FEATURE_SSSE3))
787 : /* Nano 1000 | Nano 2000 */
788 : cpu = "nano";
789 0 : else if (has_feature (FEATURE_SSE3))
790 : /* Eden X2 */
791 : cpu = "eden-x2";
792 : else
793 : /* Default to k8 */
794 0 : cpu = "k8";
795 : }
796 0 : else if (has_feature (FEATURE_SSE3))
797 : cpu = "k8-sse3";
798 : else
799 0 : cpu = "k8";
800 : }
801 : else
802 : /* For -mtune, we default to -mtune=k8 */
803 : cpu = "k8";
804 : break;
805 : case PROCESSOR_AMDFAM10:
806 : cpu = "amdfam10";
807 : break;
808 : case PROCESSOR_BDVER1:
809 : cpu = "bdver1";
810 : break;
811 : case PROCESSOR_BDVER2:
812 : cpu = "bdver2";
813 : break;
814 : case PROCESSOR_BDVER3:
815 : cpu = "bdver3";
816 : break;
817 : case PROCESSOR_BDVER4:
818 : cpu = "bdver4";
819 : break;
820 : case PROCESSOR_ZNVER1:
821 : cpu = "znver1";
822 : break;
823 : case PROCESSOR_ZNVER2:
824 : cpu = "znver2";
825 : break;
826 : case PROCESSOR_ZNVER3:
827 : cpu = "znver3";
828 : break;
829 : case PROCESSOR_ZNVER4:
830 : cpu = "znver4";
831 : break;
832 : case PROCESSOR_ZNVER5:
833 : cpu = "znver5";
834 : break;
835 : case PROCESSOR_ZNVER6:
836 : cpu = "znver6";
837 : break;
838 : case PROCESSOR_BTVER1:
839 : cpu = "btver1";
840 : break;
841 : case PROCESSOR_BTVER2:
842 : cpu = "btver2";
843 : break;
844 : case PROCESSOR_LUJIAZUI:
845 : cpu = "lujiazui";
846 : break;
847 : case PROCESSOR_YONGFENG:
848 : cpu = "yongfeng";
849 : break;
850 : case PROCESSOR_SHIJIDADAO:
851 : cpu = "shijidadao";
852 : break;
853 :
854 0 : default:
855 : /* Use something reasonable. */
856 0 : if (arch)
857 : {
858 0 : if (has_feature (FEATURE_SSSE3))
859 : cpu = "core2";
860 0 : else if (has_feature (FEATURE_SSE3))
861 : {
862 0 : if (has_feature (FEATURE_LM))
863 : cpu = "nocona";
864 : else
865 1348 : cpu = "prescott";
866 : }
867 0 : else if (has_feature (FEATURE_LM))
868 : /* Perhaps some emulator? Assume x86-64, otherwise gcc
869 : -march=native would be unusable for 64-bit compilations,
870 : as all the CPUs below are 32-bit only. */
871 : cpu = "x86-64";
872 0 : else if (has_feature (FEATURE_SSE2))
873 : cpu = "pentium4";
874 0 : else if (has_feature (FEATURE_CMOV))
875 : cpu = "pentiumpro";
876 0 : else if (has_feature (FEATURE_MMX))
877 : cpu = "pentium-mmx";
878 0 : else if (has_feature (FEATURE_CMPXCHG8B))
879 0 : cpu = "pentium";
880 : }
881 : else
882 : cpu = "generic";
883 : }
884 :
885 1348 : if (arch)
886 : {
887 : unsigned int i;
888 : const char *const neg_option = " -mno-";
889 156429 : for (i = 0; i < ARRAY_SIZE (isa_names_table); i++)
890 155092 : if (isa_names_table[i].option)
891 : {
892 140385 : if (has_feature (isa_names_table[i].feature))
893 : {
894 52143 : if (codegen_x86_64
895 0 : || (isa_names_table[i].feature != FEATURE_UINTR
896 0 : && isa_names_table[i].feature != FEATURE_APX_F))
897 52143 : options = concat (options, " ",
898 : isa_names_table[i].option, NULL);
899 : }
900 : else
901 88242 : options = concat (options, neg_option,
902 : isa_names_table[i].option + 2, NULL);
903 : }
904 : }
905 :
906 11 : done:
907 1348 : return concat (cache, "-m", argv[0], "=", cpu, options, NULL);
908 : }
909 : #else
910 :
911 : /* If we are compiling with GCC where %EBX register is fixed, then the
912 : driver will just ignore -march and -mtune "native" target and will leave
913 : to the newly built compiler to generate code for its default target. */
914 :
915 : const char *host_detect_local_cpu (int, const char **)
916 : {
917 : return NULL;
918 : }
919 : #endif /* __GNUC__ */
|