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