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