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