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