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_HYGON)
505 : {
506 0 : processor = PROCESSOR_GENERIC;
507 0 : if (model == 4)
508 : processor = PROCESSOR_C86_4G_M4;
509 0 : else if (model == 6)
510 : processor = PROCESSOR_C86_4G_M6;
511 0 : else if (model >= 7)
512 : processor = PROCESSOR_C86_4G_M7;
513 : }
514 0 : else if (vendor == VENDOR_CENTAUR)
515 : {
516 0 : processor = PROCESSOR_GENERIC;
517 :
518 0 : switch (family)
519 : {
520 : default:
521 : /* We have no idea. */
522 : break;
523 :
524 0 : case 5:
525 0 : if (has_feature (FEATURE_3DNOW)
526 0 : || has_feature (FEATURE_MMX))
527 : processor = PROCESSOR_I486;
528 : break;
529 :
530 0 : case 6:
531 0 : if (has_feature (FEATURE_LM))
532 : processor = PROCESSOR_K8;
533 0 : else if (model >= 9)
534 : processor = PROCESSOR_PENTIUMPRO;
535 0 : else if (model >= 6)
536 : processor = PROCESSOR_I486;
537 : }
538 : }
539 0 : else if (vendor == VENDOR_ZHAOXIN)
540 : {
541 0 : processor = PROCESSOR_GENERIC;
542 :
543 0 : switch (family)
544 : {
545 0 : case 7:
546 0 : if (model >= 0x6b)
547 : processor = PROCESSOR_SHIJIDADAO;
548 0 : else if (model == 0x5b)
549 : processor = PROCESSOR_YONGFENG;
550 0 : else if (model == 0x3b)
551 : processor = PROCESSOR_LUJIAZUI;
552 : break;
553 : default:
554 : break;
555 : }
556 : }
557 : else
558 : {
559 0 : switch (family)
560 : {
561 : case 4:
562 : processor = PROCESSOR_I486;
563 : break;
564 : case 5:
565 : processor = PROCESSOR_PENTIUM;
566 : break;
567 : case 6:
568 : case 18:
569 : case 19:
570 : processor = PROCESSOR_PENTIUMPRO;
571 : break;
572 0 : case 15:
573 0 : processor = PROCESSOR_PENTIUM4;
574 0 : break;
575 : default:
576 : /* We have no idea. */
577 : processor = PROCESSOR_GENERIC;
578 : }
579 : }
580 :
581 0 : switch (processor)
582 : {
583 : case PROCESSOR_I386:
584 : /* Default. */
585 : break;
586 0 : case PROCESSOR_I486:
587 0 : if (arch && vendor == VENDOR_CENTAUR)
588 : {
589 0 : if (model >= 6)
590 : cpu = "c3";
591 0 : else if (has_feature (FEATURE_3DNOW))
592 : cpu = "winchip2";
593 : else
594 : /* Assume WinChip C6. */
595 0 : cpu = "winchip-c6";
596 : }
597 : else
598 : cpu = "i486";
599 : break;
600 0 : case PROCESSOR_PENTIUM:
601 0 : if (arch && has_feature (FEATURE_MMX))
602 : cpu = "pentium-mmx";
603 : else
604 : cpu = "pentium";
605 : break;
606 0 : case PROCESSOR_PENTIUMPRO:
607 0 : cpu = get_intel_cpu (&cpu_model, &cpu_model2, cpu_features2);
608 0 : if (cpu == NULL)
609 : {
610 0 : if (arch)
611 : {
612 : /* This is unknown CPU. */
613 0 : if (has_feature (FEATURE_AVX512F))
614 : {
615 : /* Assume Diamond Rapids. */
616 0 : if (has_feature (FEATURE_AMX_FP8))
617 : cpu = "diamondrapids";
618 : /* Assume Nova Lake. */
619 0 : else if (has_feature (FEATURE_AVX10_2))
620 : cpu = "novalake";
621 : /* Assume Granite Rapids D. */
622 0 : else if (has_feature (FEATURE_AMX_COMPLEX))
623 : cpu = "graniterapids-d";
624 : /* Assume Granite Rapids. */
625 0 : else if (has_feature (FEATURE_AMX_FP16))
626 : cpu = "graniterapids";
627 : /* Assume Tiger Lake */
628 0 : else if (has_feature (FEATURE_AVX512VP2INTERSECT))
629 : cpu = "tigerlake";
630 : /* Assume Sapphire Rapids. */
631 0 : else if (has_feature (FEATURE_TSXLDTRK))
632 : cpu = "sapphirerapids";
633 : /* Assume Cooper Lake */
634 0 : else if (has_feature (FEATURE_AVX512BF16))
635 : cpu = "cooperlake";
636 : /* Assume Ice Lake Server. */
637 0 : else if (has_feature (FEATURE_WBNOINVD))
638 : cpu = "icelake-server";
639 : /* Assume Ice Lake. */
640 0 : else if (has_feature (FEATURE_AVX512BITALG))
641 : cpu = "icelake-client";
642 : /* Assume Cannon Lake. */
643 0 : else if (has_feature (FEATURE_AVX512VBMI))
644 : cpu = "cannonlake";
645 : /* Assume Xeon Phi Processors. Support has been removed
646 : since GCC 15. */
647 0 : else if (!has_feature (FEATURE_AVX512VL))
648 0 : error ("Xeon Phi ISA support has been removed since "
649 : "GCC 15, use GCC 14 for the Xeon Phi ISAs or "
650 : "%<-march=broadwell%> for all the other ISAs "
651 : "supported on this machine.");
652 : /* Assume Skylake with AVX-512. */
653 : else
654 : cpu = "skylake-avx512";
655 : }
656 0 : else if (has_feature (FEATURE_AVX))
657 : {
658 : /* Assume Clearwater Forest. */
659 0 : if (has_feature (FEATURE_USER_MSR))
660 : cpu = "clearwaterforest";
661 0 : else if (has_feature (FEATURE_SM3))
662 : {
663 0 : if (has_feature (FEATURE_KL))
664 : /* Assume Arrow Lake S. */
665 : cpu = "arrowlake-s";
666 : else
667 : /* Assume Panther Lake. */
668 0 : cpu = "pantherlake";
669 : }
670 : /* Assume Sierra Forest. */
671 0 : else if (has_feature (FEATURE_CLDEMOTE))
672 : cpu = "sierraforest";
673 : /* Assume Arrow Lake. */
674 0 : else if (has_feature (FEATURE_AVXVNNIINT8))
675 : cpu = "arrowlake";
676 : /* Assume Alder Lake. */
677 0 : else if (has_feature (FEATURE_SERIALIZE))
678 : cpu = "alderlake";
679 : /* Assume Skylake. */
680 0 : else if (has_feature (FEATURE_CLFLUSHOPT))
681 : cpu = "skylake";
682 : /* Assume Broadwell. */
683 0 : else if (has_feature (FEATURE_ADX))
684 : cpu = "broadwell";
685 : /* Assume Haswell. */
686 0 : else if (has_feature (FEATURE_AVX2))
687 : cpu = "haswell";
688 : /* Assume Sandy Bridge. */
689 : else
690 0 : cpu = "sandybridge";
691 : }
692 0 : else if (has_feature (FEATURE_SSE4_2))
693 : {
694 0 : if (has_feature (FEATURE_GFNI))
695 : /* Assume Tremont. */
696 : cpu = "tremont";
697 0 : else if (has_feature (FEATURE_SGX))
698 : /* Assume Goldmont Plus. */
699 : cpu = "goldmont-plus";
700 0 : else if (has_feature (FEATURE_XSAVE))
701 : /* Assume Goldmont. */
702 : cpu = "goldmont";
703 0 : else if (has_feature (FEATURE_MOVBE))
704 : /* Assume Silvermont. */
705 : cpu = "silvermont";
706 : else
707 : /* Assume Nehalem. */
708 0 : cpu = "nehalem";
709 : }
710 0 : else if (has_feature (FEATURE_SSSE3))
711 : {
712 0 : if (has_feature (FEATURE_MOVBE))
713 : /* Assume Bonnell. */
714 : cpu = "bonnell";
715 : else
716 : /* Assume Core 2. */
717 0 : cpu = "core2";
718 : }
719 0 : else if (has_feature (FEATURE_LM))
720 : /* Perhaps some emulator? Assume x86-64, otherwise gcc
721 : -march=native would be unusable for 64-bit compilations,
722 : as all the CPUs below are 32-bit only. */
723 : cpu = "x86-64";
724 0 : else if (has_feature (FEATURE_SSE3))
725 : {
726 0 : if (vendor == VENDOR_CENTAUR)
727 : /* C7 / Eden "Esther" */
728 : cpu = "c7";
729 : else
730 : /* It is Core Duo. */
731 0 : cpu = "pentium-m";
732 : }
733 0 : else if (has_feature (FEATURE_SSE2))
734 : /* It is Pentium M. */
735 : cpu = "pentium-m";
736 0 : else if (has_feature (FEATURE_SSE))
737 : {
738 0 : if (vendor == VENDOR_CENTAUR)
739 : {
740 0 : if (model >= 9)
741 : /* Eden "Nehemiah" */
742 : cpu = "nehemiah";
743 : else
744 0 : cpu = "c3-2";
745 : }
746 : else
747 : /* It is Pentium III. */
748 : cpu = "pentium3";
749 : }
750 0 : else if (has_feature (FEATURE_MMX))
751 : /* It is Pentium II. */
752 : cpu = "pentium2";
753 : else
754 : /* Default to Pentium Pro. */
755 0 : cpu = "pentiumpro";
756 : }
757 : else
758 : /* For -mtune, we default to -mtune=generic. */
759 : cpu = "generic";
760 : }
761 : break;
762 0 : case PROCESSOR_PENTIUM4:
763 0 : if (has_feature (FEATURE_SSE3))
764 : {
765 0 : if (has_feature (FEATURE_LM))
766 : cpu = "nocona";
767 : else
768 1348 : cpu = "prescott";
769 : }
770 : else
771 : cpu = "pentium4";
772 : break;
773 : case PROCESSOR_GEODE:
774 : cpu = "geode";
775 : break;
776 0 : case PROCESSOR_K6:
777 0 : if (arch && has_feature (FEATURE_3DNOW))
778 : cpu = "k6-3";
779 : else
780 : cpu = "k6";
781 : break;
782 0 : case PROCESSOR_ATHLON:
783 0 : if (arch && has_feature (FEATURE_SSE))
784 : cpu = "athlon-4";
785 : else
786 : cpu = "athlon";
787 : break;
788 0 : case PROCESSOR_K8:
789 0 : if (arch)
790 : {
791 0 : if (vendor == VENDOR_CENTAUR)
792 : {
793 0 : if (has_feature (FEATURE_SSE4_1))
794 : /* Nano 3000 | Nano dual / quad core | Eden X4 */
795 : cpu = "nano-3000";
796 0 : else if (has_feature (FEATURE_SSSE3))
797 : /* Nano 1000 | Nano 2000 */
798 : cpu = "nano";
799 0 : else if (has_feature (FEATURE_SSE3))
800 : /* Eden X2 */
801 : cpu = "eden-x2";
802 : else
803 : /* Default to k8 */
804 0 : cpu = "k8";
805 : }
806 0 : else if (has_feature (FEATURE_SSE3))
807 : cpu = "k8-sse3";
808 : else
809 0 : cpu = "k8";
810 : }
811 : else
812 : /* For -mtune, we default to -mtune=k8 */
813 : cpu = "k8";
814 : break;
815 : case PROCESSOR_AMDFAM10:
816 : cpu = "amdfam10";
817 : break;
818 : case PROCESSOR_BDVER1:
819 : cpu = "bdver1";
820 : break;
821 : case PROCESSOR_BDVER2:
822 : cpu = "bdver2";
823 : break;
824 : case PROCESSOR_BDVER3:
825 : cpu = "bdver3";
826 : break;
827 : case PROCESSOR_BDVER4:
828 : cpu = "bdver4";
829 : break;
830 : case PROCESSOR_ZNVER1:
831 : cpu = "znver1";
832 : break;
833 : case PROCESSOR_ZNVER2:
834 : cpu = "znver2";
835 : break;
836 : case PROCESSOR_ZNVER3:
837 : cpu = "znver3";
838 : break;
839 : case PROCESSOR_ZNVER4:
840 : cpu = "znver4";
841 : break;
842 : case PROCESSOR_ZNVER5:
843 : cpu = "znver5";
844 : break;
845 : case PROCESSOR_ZNVER6:
846 : cpu = "znver6";
847 : break;
848 : case PROCESSOR_BTVER1:
849 : cpu = "btver1";
850 : break;
851 : case PROCESSOR_BTVER2:
852 : cpu = "btver2";
853 : break;
854 : case PROCESSOR_LUJIAZUI:
855 : cpu = "lujiazui";
856 : break;
857 : case PROCESSOR_YONGFENG:
858 : cpu = "yongfeng";
859 : break;
860 : case PROCESSOR_SHIJIDADAO:
861 : cpu = "shijidadao";
862 : break;
863 : case PROCESSOR_C86_4G_M4:
864 : cpu = "c86-4g-m4";
865 : break;
866 : case PROCESSOR_C86_4G_M6:
867 : cpu = "c86-4g-m6";
868 : break;
869 : case PROCESSOR_C86_4G_M7:
870 : cpu = "c86-4g-m7";
871 : break;
872 :
873 0 : default:
874 : /* Use something reasonable. */
875 0 : if (arch)
876 : {
877 0 : if (has_feature (FEATURE_SSSE3))
878 : cpu = "core2";
879 0 : else if (has_feature (FEATURE_SSE3))
880 : {
881 0 : if (has_feature (FEATURE_LM))
882 : cpu = "nocona";
883 : else
884 1348 : cpu = "prescott";
885 : }
886 0 : else if (has_feature (FEATURE_LM))
887 : /* Perhaps some emulator? Assume x86-64, otherwise gcc
888 : -march=native would be unusable for 64-bit compilations,
889 : as all the CPUs below are 32-bit only. */
890 : cpu = "x86-64";
891 0 : else if (has_feature (FEATURE_SSE2))
892 : cpu = "pentium4";
893 0 : else if (has_feature (FEATURE_CMOV))
894 : cpu = "pentiumpro";
895 0 : else if (has_feature (FEATURE_MMX))
896 : cpu = "pentium-mmx";
897 0 : else if (has_feature (FEATURE_CMPXCHG8B))
898 0 : cpu = "pentium";
899 : }
900 : else
901 : cpu = "generic";
902 : }
903 :
904 1348 : if (arch)
905 : {
906 : unsigned int i;
907 : const char *const neg_option = " -mno-";
908 156429 : for (i = 0; i < ARRAY_SIZE (isa_names_table); i++)
909 155092 : if (isa_names_table[i].option)
910 : {
911 140385 : if (has_feature (isa_names_table[i].feature))
912 : {
913 52143 : if (codegen_x86_64
914 0 : || (isa_names_table[i].feature != FEATURE_UINTR
915 0 : && isa_names_table[i].feature != FEATURE_APX_F))
916 52143 : options = concat (options, " ",
917 : isa_names_table[i].option, NULL);
918 : }
919 : else
920 88242 : options = concat (options, neg_option,
921 : isa_names_table[i].option + 2, NULL);
922 : }
923 : }
924 :
925 11 : done:
926 1348 : return concat (cache, "-m", argv[0], "=", cpu, options, NULL);
927 : }
928 : #else
929 :
930 : /* If we are compiling with GCC where %EBX register is fixed, then the
931 : driver will just ignore -march and -mtune "native" target and will leave
932 : to the newly built compiler to generate code for its default target. */
933 :
934 : const char *host_detect_local_cpu (int, const char **)
935 : {
936 : return NULL;
937 : }
938 : #endif /* __GNUC__ */
|