Branch data Line data Source code
1 : : /* Subroutines for the gcc driver.
2 : : Copyright (C) 2006-2024 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 : :
27 : : const char *host_detect_local_cpu (int argc, const char **argv);
28 : :
29 : : #if defined(__GNUC__) && (__GNUC__ >= 5 || !defined(__PIC__))
30 : : #include "cpuid.h"
31 : : #include "common/config/i386/cpuinfo.h"
32 : : #include "common/config/i386/i386-isas.h"
33 : :
34 : : struct cache_desc
35 : : {
36 : : unsigned sizekb;
37 : : unsigned assoc;
38 : : unsigned line;
39 : : };
40 : :
41 : : /* Returns command line parameters that describe size and
42 : : cache line size of the processor caches. */
43 : :
44 : : static char *
45 : 11 : describe_cache (struct cache_desc level1, struct cache_desc level2)
46 : : {
47 : 11 : char size[100], line[100], size2[100];
48 : :
49 : : /* At the moment, gcc does not use the information
50 : : about the associativity of the cache. */
51 : :
52 : 11 : snprintf (size, sizeof (size),
53 : : "--param l1-cache-size=%u ", level1.sizekb);
54 : 11 : snprintf (line, sizeof (line),
55 : : "--param l1-cache-line-size=%u ", level1.line);
56 : :
57 : 11 : snprintf (size2, sizeof (size2),
58 : : "--param l2-cache-size=%u ", level2.sizekb);
59 : :
60 : 11 : return concat (size, line, size2, NULL);
61 : : }
62 : :
63 : : /* Detect L2 cache parameters using CPUID extended function 0x80000006. */
64 : :
65 : : static void
66 : 11 : detect_l2_cache (struct cache_desc *level2)
67 : : {
68 : 11 : unsigned eax, ebx, ecx, edx;
69 : 11 : unsigned assoc;
70 : :
71 : 11 : __cpuid (0x80000006, eax, ebx, ecx, edx);
72 : :
73 : 11 : level2->sizekb = (ecx >> 16) & 0xffff;
74 : 11 : level2->line = ecx & 0xff;
75 : :
76 : 11 : assoc = (ecx >> 12) & 0xf;
77 : 11 : if (assoc == 6)
78 : : assoc = 8;
79 : 0 : else if (assoc == 8)
80 : : assoc = 16;
81 : 0 : else if (assoc >= 0xa && assoc <= 0xc)
82 : 0 : assoc = 32 + (assoc - 0xa) * 16;
83 : 0 : else if (assoc >= 0xd && assoc <= 0xe)
84 : 0 : assoc = 96 + (assoc - 0xd) * 32;
85 : :
86 : 11 : level2->assoc = assoc;
87 : 11 : }
88 : :
89 : : /* Returns the description of caches for an AMD processor. */
90 : :
91 : : static const char *
92 : 11 : detect_caches_amd (unsigned max_ext_level)
93 : : {
94 : 11 : unsigned eax, ebx, ecx, edx;
95 : :
96 : 11 : struct cache_desc level1, level2 = {0, 0, 0};
97 : :
98 : 11 : if (max_ext_level < 0x80000005)
99 : : return "";
100 : :
101 : 11 : __cpuid (0x80000005, eax, ebx, ecx, edx);
102 : :
103 : 11 : level1.sizekb = (ecx >> 24) & 0xff;
104 : 11 : level1.assoc = (ecx >> 16) & 0xff;
105 : 11 : level1.line = ecx & 0xff;
106 : :
107 : 11 : if (max_ext_level >= 0x80000006)
108 : 11 : detect_l2_cache (&level2);
109 : :
110 : 11 : return describe_cache (level1, level2);
111 : : }
112 : :
113 : : /* Decodes the size, the associativity and the cache line size of
114 : : L1/L2 caches of an Intel processor. Values are based on
115 : : "Intel Processor Identification and the CPUID Instruction"
116 : : [Application Note 485], revision -032, December 2007. */
117 : :
118 : : static void
119 : 0 : decode_caches_intel (unsigned reg, bool xeon_mp,
120 : : struct cache_desc *level1, struct cache_desc *level2)
121 : : {
122 : 0 : int i;
123 : :
124 : 0 : for (i = 24; i >= 0; i -= 8)
125 : 0 : switch ((reg >> i) & 0xff)
126 : : {
127 : 0 : case 0x0a:
128 : 0 : level1->sizekb = 8; level1->assoc = 2; level1->line = 32;
129 : 0 : break;
130 : 0 : case 0x0c:
131 : 0 : level1->sizekb = 16; level1->assoc = 4; level1->line = 32;
132 : 0 : break;
133 : 0 : case 0x0d:
134 : 0 : level1->sizekb = 16; level1->assoc = 4; level1->line = 64;
135 : 0 : break;
136 : 0 : case 0x0e:
137 : 0 : level1->sizekb = 24; level1->assoc = 6; level1->line = 64;
138 : 0 : break;
139 : 0 : case 0x21:
140 : 0 : level2->sizekb = 256; level2->assoc = 8; level2->line = 64;
141 : 0 : break;
142 : 0 : case 0x24:
143 : 0 : level2->sizekb = 1024; level2->assoc = 16; level2->line = 64;
144 : 0 : break;
145 : 0 : case 0x2c:
146 : 0 : level1->sizekb = 32; level1->assoc = 8; level1->line = 64;
147 : 0 : break;
148 : 0 : case 0x39:
149 : 0 : level2->sizekb = 128; level2->assoc = 4; level2->line = 64;
150 : 0 : break;
151 : 0 : case 0x3a:
152 : 0 : level2->sizekb = 192; level2->assoc = 6; level2->line = 64;
153 : 0 : break;
154 : 0 : case 0x3b:
155 : 0 : level2->sizekb = 128; level2->assoc = 2; level2->line = 64;
156 : 0 : break;
157 : 0 : case 0x3c:
158 : 0 : level2->sizekb = 256; level2->assoc = 4; level2->line = 64;
159 : 0 : break;
160 : 0 : case 0x3d:
161 : 0 : level2->sizekb = 384; level2->assoc = 6; level2->line = 64;
162 : 0 : break;
163 : 0 : case 0x3e:
164 : 0 : level2->sizekb = 512; level2->assoc = 4; level2->line = 64;
165 : 0 : break;
166 : 0 : case 0x41:
167 : 0 : level2->sizekb = 128; level2->assoc = 4; level2->line = 32;
168 : 0 : break;
169 : 0 : case 0x42:
170 : 0 : level2->sizekb = 256; level2->assoc = 4; level2->line = 32;
171 : 0 : break;
172 : 0 : case 0x43:
173 : 0 : level2->sizekb = 512; level2->assoc = 4; level2->line = 32;
174 : 0 : break;
175 : 0 : case 0x44:
176 : 0 : level2->sizekb = 1024; level2->assoc = 4; level2->line = 32;
177 : 0 : break;
178 : 0 : case 0x45:
179 : 0 : level2->sizekb = 2048; level2->assoc = 4; level2->line = 32;
180 : 0 : break;
181 : 0 : case 0x48:
182 : 0 : level2->sizekb = 3072; level2->assoc = 12; level2->line = 64;
183 : 0 : break;
184 : 0 : case 0x49:
185 : 0 : if (xeon_mp)
186 : : break;
187 : 0 : level2->sizekb = 4096; level2->assoc = 16; level2->line = 64;
188 : 0 : break;
189 : 0 : case 0x4e:
190 : 0 : level2->sizekb = 6144; level2->assoc = 24; level2->line = 64;
191 : 0 : break;
192 : 0 : case 0x60:
193 : 0 : level1->sizekb = 16; level1->assoc = 8; level1->line = 64;
194 : 0 : break;
195 : 0 : case 0x66:
196 : 0 : level1->sizekb = 8; level1->assoc = 4; level1->line = 64;
197 : 0 : break;
198 : 0 : case 0x67:
199 : 0 : level1->sizekb = 16; level1->assoc = 4; level1->line = 64;
200 : 0 : break;
201 : 0 : case 0x68:
202 : 0 : level1->sizekb = 32; level1->assoc = 4; level1->line = 64;
203 : 0 : break;
204 : 0 : case 0x78:
205 : 0 : level2->sizekb = 1024; level2->assoc = 4; level2->line = 64;
206 : 0 : break;
207 : 0 : case 0x79:
208 : 0 : level2->sizekb = 128; level2->assoc = 8; level2->line = 64;
209 : 0 : break;
210 : 0 : case 0x7a:
211 : 0 : level2->sizekb = 256; level2->assoc = 8; level2->line = 64;
212 : 0 : break;
213 : 0 : case 0x7b:
214 : 0 : level2->sizekb = 512; level2->assoc = 8; level2->line = 64;
215 : 0 : break;
216 : 0 : case 0x7c:
217 : 0 : level2->sizekb = 1024; level2->assoc = 8; level2->line = 64;
218 : 0 : break;
219 : 0 : case 0x7d:
220 : 0 : level2->sizekb = 2048; level2->assoc = 8; level2->line = 64;
221 : 0 : break;
222 : 0 : case 0x7f:
223 : 0 : level2->sizekb = 512; level2->assoc = 2; level2->line = 64;
224 : 0 : break;
225 : 0 : case 0x80:
226 : 0 : level2->sizekb = 512; level2->assoc = 8; level2->line = 64;
227 : 0 : break;
228 : 0 : case 0x82:
229 : 0 : level2->sizekb = 256; level2->assoc = 8; level2->line = 32;
230 : 0 : break;
231 : 0 : case 0x83:
232 : 0 : level2->sizekb = 512; level2->assoc = 8; level2->line = 32;
233 : 0 : break;
234 : 0 : case 0x84:
235 : 0 : level2->sizekb = 1024; level2->assoc = 8; level2->line = 32;
236 : 0 : break;
237 : 0 : case 0x85:
238 : 0 : level2->sizekb = 2048; level2->assoc = 8; level2->line = 32;
239 : 0 : break;
240 : 0 : case 0x86:
241 : 0 : level2->sizekb = 512; level2->assoc = 4; level2->line = 64;
242 : 0 : break;
243 : 0 : case 0x87:
244 : 0 : level2->sizekb = 1024; level2->assoc = 8; level2->line = 64;
245 : :
246 : : default:
247 : : break;
248 : : }
249 : 0 : }
250 : :
251 : : /* Detect cache parameters using CPUID function 2. */
252 : :
253 : : static void
254 : 0 : detect_caches_cpuid2 (bool xeon_mp,
255 : : struct cache_desc *level1, struct cache_desc *level2)
256 : : {
257 : 0 : unsigned regs[4];
258 : 0 : int nreps, i;
259 : :
260 : 0 : __cpuid (2, regs[0], regs[1], regs[2], regs[3]);
261 : :
262 : 0 : nreps = regs[0] & 0x0f;
263 : 0 : regs[0] &= ~0x0f;
264 : :
265 : 0 : while (--nreps >= 0)
266 : : {
267 : 0 : for (i = 0; i < 4; i++)
268 : 0 : if (regs[i] && !((regs[i] >> 31) & 1))
269 : 0 : decode_caches_intel (regs[i], xeon_mp, level1, level2);
270 : :
271 : 0 : if (nreps)
272 : 0 : __cpuid (2, regs[0], regs[1], regs[2], regs[3]);
273 : : }
274 : 0 : }
275 : :
276 : : /* Detect cache parameters using CPUID function 4. This
277 : : method doesn't require hardcoded tables. */
278 : :
279 : : enum cache_type
280 : : {
281 : : CACHE_END = 0,
282 : : CACHE_DATA = 1,
283 : : CACHE_INST = 2,
284 : : CACHE_UNIFIED = 3
285 : : };
286 : :
287 : : static void
288 : 0 : detect_caches_cpuid4 (struct cache_desc *level1, struct cache_desc *level2,
289 : : struct cache_desc *level3)
290 : : {
291 : 0 : struct cache_desc *cache;
292 : :
293 : 0 : unsigned eax, ebx, ecx, edx;
294 : 0 : int count;
295 : :
296 : 0 : for (count = 0;; count++)
297 : : {
298 : 0 : __cpuid_count(4, count, eax, ebx, ecx, edx);
299 : 0 : switch (eax & 0x1f)
300 : : {
301 : 0 : case CACHE_END:
302 : 0 : return;
303 : 0 : case CACHE_DATA:
304 : 0 : case CACHE_UNIFIED:
305 : 0 : {
306 : 0 : switch ((eax >> 5) & 0x07)
307 : : {
308 : : case 1:
309 : : cache = level1;
310 : : break;
311 : 0 : case 2:
312 : 0 : cache = level2;
313 : 0 : break;
314 : 0 : case 3:
315 : 0 : cache = level3;
316 : 0 : break;
317 : : default:
318 : : cache = NULL;
319 : : }
320 : :
321 : 0 : if (cache)
322 : : {
323 : 0 : unsigned sets = ecx + 1;
324 : 0 : unsigned part = ((ebx >> 12) & 0x03ff) + 1;
325 : :
326 : 0 : cache->assoc = ((ebx >> 22) & 0x03ff) + 1;
327 : 0 : cache->line = (ebx & 0x0fff) + 1;
328 : :
329 : 0 : cache->sizekb = (cache->assoc * part
330 : 0 : * cache->line * sets) / 1024;
331 : : }
332 : : }
333 : 0 : default:
334 : 0 : break;
335 : : }
336 : 0 : }
337 : : }
338 : :
339 : : /* Returns the description of caches for an Intel processor. */
340 : :
341 : : static const char *
342 : 0 : detect_caches_intel (bool xeon_mp, unsigned max_level,
343 : : unsigned max_ext_level, unsigned *l2sizekb)
344 : : {
345 : 0 : struct cache_desc level1 = {0, 0, 0}, level2 = {0, 0, 0}, level3 = {0, 0, 0};
346 : :
347 : 0 : if (max_level >= 4)
348 : 0 : detect_caches_cpuid4 (&level1, &level2, &level3);
349 : 0 : else if (max_level >= 2)
350 : 0 : detect_caches_cpuid2 (xeon_mp, &level1, &level2);
351 : : else
352 : : return "";
353 : :
354 : 0 : if (level1.sizekb == 0)
355 : : return "";
356 : :
357 : : /* Let the L3 replace the L2. This assumes inclusive caches
358 : : and single threaded program for now. */
359 : 0 : if (level3.sizekb)
360 : 0 : level2 = level3;
361 : :
362 : : /* Intel CPUs are equipped with AMD style L2 cache info. Try this
363 : : method if other methods fail to provide L2 cache parameters. */
364 : 0 : if (level2.sizekb == 0 && max_ext_level >= 0x80000006)
365 : 0 : detect_l2_cache (&level2);
366 : :
367 : 0 : *l2sizekb = level2.sizekb;
368 : :
369 : 0 : return describe_cache (level1, level2);
370 : : }
371 : :
372 : : /* Extended features */
373 : : #define has_feature(f) \
374 : : has_cpu_feature (&cpu_model, cpu_features2, f)
375 : :
376 : : /* We will emit a warning when using AVX10.1 and AVX512 options with one
377 : : enabled and the other disabled. Add this function to avoid push "-mno-"
378 : : options under this scenario for -march=native. */
379 : :
380 : 638 : bool check_avx512_features (__processor_model &cpu_model,
381 : : unsigned int (&cpu_features2)[SIZE_OF_CPU_FEATURES],
382 : : const enum processor_features feature)
383 : : {
384 : 638 : if (has_feature (FEATURE_AVX10_1_256)
385 : 638 : && ((feature == FEATURE_AVX512F)
386 : 0 : || (feature == FEATURE_AVX512CD)
387 : : || (feature == FEATURE_AVX512DQ)
388 : : || (feature == FEATURE_AVX512BW)
389 : : || (feature == FEATURE_AVX512VL)
390 : : || (feature == FEATURE_AVX512IFMA)
391 : : || (feature == FEATURE_AVX512VBMI)
392 : : || (feature == FEATURE_AVX512VBMI2)
393 : : || (feature == FEATURE_AVX512VNNI)
394 : : || (feature == FEATURE_AVX512VPOPCNTDQ)
395 : : || (feature == FEATURE_AVX512BITALG)
396 : : || (feature == FEATURE_AVX512FP16)
397 : : || (feature == FEATURE_AVX512BF16)))
398 : 0 : return false;
399 : :
400 : : return true;
401 : : }
402 : :
403 : : /* This will be called by the spec parser in gcc.cc when it sees
404 : : a %:local_cpu_detect(args) construct. Currently it will be
405 : : called with either "arch [32|64]" or "tune [32|64]" as argument
406 : : depending on if -march=native or -mtune=native is to be substituted.
407 : :
408 : : It returns a string containing new command line parameters to be
409 : : put at the place of the above two options, depending on what CPU
410 : : this is executed. E.g. "-march=k8" on an AMD64 machine
411 : : for -march=native.
412 : :
413 : : ARGC and ARGV are set depending on the actual arguments given
414 : : in the spec. */
415 : :
416 : 22 : const char *host_detect_local_cpu (int argc, const char **argv)
417 : : {
418 : 22 : enum processor_type processor = PROCESSOR_I386;
419 : 22 : const char *cpu = "i386";
420 : :
421 : 22 : const char *cache = "";
422 : 22 : const char *options = "";
423 : :
424 : 22 : unsigned int ebx, ecx, edx;
425 : :
426 : 22 : unsigned int max_level, ext_level;
427 : :
428 : 22 : unsigned int vendor;
429 : 22 : unsigned int model, family;
430 : :
431 : 22 : bool arch;
432 : :
433 : 22 : unsigned int l2sizekb = 0;
434 : :
435 : 22 : if (argc < 2)
436 : : return NULL;
437 : :
438 : 22 : arch = !strcmp (argv[0], "arch");
439 : :
440 : 22 : if (!arch && strcmp (argv[0], "tune"))
441 : : return NULL;
442 : :
443 : 22 : bool codegen_x86_64;
444 : :
445 : 22 : if (!strcmp (argv[1], "32"))
446 : : codegen_x86_64 = false;
447 : 22 : else if (!strcmp (argv[1], "64"))
448 : : codegen_x86_64 = true;
449 : : else
450 : : return NULL;
451 : :
452 : 22 : struct __processor_model cpu_model = { };
453 : 22 : struct __processor_model2 cpu_model2 = { };
454 : 22 : unsigned int cpu_features2[SIZE_OF_CPU_FEATURES] = { };
455 : :
456 : 22 : if (cpu_indicator_init (&cpu_model, &cpu_model2, cpu_features2) != 0)
457 : 0 : goto done;
458 : :
459 : 22 : vendor = cpu_model.__cpu_vendor;
460 : 22 : family = cpu_model2.__cpu_family;
461 : 22 : model = cpu_model2.__cpu_model;
462 : 22 : max_level = cpu_model2.__cpu_max_level;
463 : 22 : ext_level = cpu_model2.__cpu_ext_level;
464 : :
465 : 22 : if (!arch)
466 : : {
467 : 11 : if (vendor == VENDOR_AMD
468 : 11 : || vendor == VENDOR_CENTAUR
469 : : || vendor == VENDOR_CYRIX
470 : 0 : || vendor == VENDOR_NSC)
471 : 11 : cache = detect_caches_amd (ext_level);
472 : 0 : else if (vendor == VENDOR_INTEL
473 : 0 : || vendor == VENDOR_ZHAOXIN)
474 : : {
475 : 0 : bool xeon_mp = (family == 15 && model == 6);
476 : 0 : cache = detect_caches_intel (xeon_mp, max_level,
477 : : ext_level, &l2sizekb);
478 : : }
479 : : }
480 : :
481 : 22 : if (vendor == VENDOR_AMD)
482 : : {
483 : 22 : unsigned int name;
484 : :
485 : : /* Detect geode processor by its processor signature. */
486 : 22 : if (ext_level >= 0x80000002)
487 : 22 : __cpuid (0x80000002, name, ebx, ecx, edx);
488 : : else
489 : : name = 0;
490 : :
491 : 22 : if (name == signature_NSC_ebx)
492 : : processor = PROCESSOR_GEODE;
493 : 22 : else if (has_feature (FEATURE_MOVBE) && family == 22)
494 : : processor = PROCESSOR_BTVER2;
495 : 22 : else if (has_feature (FEATURE_AVX512VP2INTERSECT))
496 : : processor = PROCESSOR_ZNVER5;
497 : 22 : else if (has_feature (FEATURE_AVX512F))
498 : : processor = PROCESSOR_ZNVER4;
499 : 22 : else if (has_feature (FEATURE_VAES))
500 : : processor = PROCESSOR_ZNVER3;
501 : 22 : else if (has_feature (FEATURE_CLWB))
502 : : processor = PROCESSOR_ZNVER2;
503 : 0 : else if (has_feature (FEATURE_CLZERO))
504 : : processor = PROCESSOR_ZNVER1;
505 : 0 : else if (has_feature (FEATURE_AVX2))
506 : : processor = PROCESSOR_BDVER4;
507 : 0 : else if (has_feature (FEATURE_XSAVEOPT))
508 : : processor = PROCESSOR_BDVER3;
509 : 0 : else if (has_feature (FEATURE_BMI))
510 : : processor = PROCESSOR_BDVER2;
511 : 0 : else if (has_feature (FEATURE_XOP))
512 : : processor = PROCESSOR_BDVER1;
513 : 0 : else if (has_feature (FEATURE_SSE4_A)
514 : 0 : && has_feature (FEATURE_SSSE3))
515 : : processor = PROCESSOR_BTVER1;
516 : 0 : else if (has_feature (FEATURE_SSE4_A))
517 : : processor = PROCESSOR_AMDFAM10;
518 : 0 : else if (has_feature (FEATURE_SSE2)
519 : 0 : || has_feature (FEATURE_LM))
520 : : processor = PROCESSOR_K8;
521 : 0 : else if (has_feature (FEATURE_3DNOWP) && family == 6)
522 : : processor = PROCESSOR_ATHLON;
523 : 0 : else if (has_feature (FEATURE_MMX))
524 : : processor = PROCESSOR_K6;
525 : : else
526 : : processor = PROCESSOR_PENTIUM;
527 : : }
528 : 0 : else if (vendor == VENDOR_CENTAUR)
529 : : {
530 : 0 : processor = PROCESSOR_GENERIC;
531 : :
532 : 0 : switch (family)
533 : : {
534 : : default:
535 : : /* We have no idea. */
536 : : break;
537 : :
538 : 0 : case 5:
539 : 0 : if (has_feature (FEATURE_3DNOW)
540 : 0 : || has_feature (FEATURE_MMX))
541 : : processor = PROCESSOR_I486;
542 : : break;
543 : :
544 : 0 : case 6:
545 : 0 : if (has_feature (FEATURE_LM))
546 : : processor = PROCESSOR_K8;
547 : 0 : else if (model >= 9)
548 : : processor = PROCESSOR_PENTIUMPRO;
549 : 0 : else if (model >= 6)
550 : : processor = PROCESSOR_I486;
551 : : }
552 : : }
553 : 0 : else if (vendor == VENDOR_ZHAOXIN)
554 : : {
555 : 0 : processor = PROCESSOR_GENERIC;
556 : :
557 : 0 : switch (family)
558 : : {
559 : 0 : case 7:
560 : 0 : if (model == 0x3b)
561 : : processor = PROCESSOR_LUJIAZUI;
562 : 0 : else if (model >= 0x5b)
563 : : processor = PROCESSOR_YONGFENG;
564 : : break;
565 : : default:
566 : : break;
567 : : }
568 : : }
569 : : else
570 : : {
571 : 0 : switch (family)
572 : : {
573 : : case 4:
574 : : processor = PROCESSOR_I486;
575 : : break;
576 : : case 5:
577 : : processor = PROCESSOR_PENTIUM;
578 : : break;
579 : : case 6:
580 : : processor = PROCESSOR_PENTIUMPRO;
581 : : break;
582 : 0 : case 15:
583 : 0 : processor = PROCESSOR_PENTIUM4;
584 : 0 : break;
585 : : default:
586 : : /* We have no idea. */
587 : : processor = PROCESSOR_GENERIC;
588 : : }
589 : : }
590 : :
591 : 0 : switch (processor)
592 : : {
593 : : case PROCESSOR_I386:
594 : : /* Default. */
595 : : break;
596 : 0 : case PROCESSOR_I486:
597 : 0 : if (arch && vendor == VENDOR_CENTAUR)
598 : : {
599 : 0 : if (model >= 6)
600 : : cpu = "c3";
601 : 0 : else if (has_feature (FEATURE_3DNOW))
602 : : cpu = "winchip2";
603 : : else
604 : : /* Assume WinChip C6. */
605 : 0 : cpu = "winchip-c6";
606 : : }
607 : : else
608 : : cpu = "i486";
609 : : break;
610 : 0 : case PROCESSOR_PENTIUM:
611 : 0 : if (arch && has_feature (FEATURE_MMX))
612 : : cpu = "pentium-mmx";
613 : : else
614 : : cpu = "pentium";
615 : : break;
616 : 0 : case PROCESSOR_PENTIUMPRO:
617 : 0 : cpu = get_intel_cpu (&cpu_model, &cpu_model2, cpu_features2);
618 : 0 : if (cpu == NULL)
619 : : {
620 : 0 : if (arch)
621 : : {
622 : : /* This is unknown family 0x6 CPU. */
623 : 0 : if (has_feature (FEATURE_AVX512F))
624 : : {
625 : : /* Assume Granite Rapids D. */
626 : 0 : if (has_feature (FEATURE_AMX_COMPLEX))
627 : : cpu = "graniterapids-d";
628 : : /* Assume Granite Rapids. */
629 : 0 : else if (has_feature (FEATURE_AMX_FP16))
630 : : cpu = "graniterapids";
631 : : /* Assume Tiger Lake */
632 : 0 : else if (has_feature (FEATURE_AVX512VP2INTERSECT))
633 : : cpu = "tigerlake";
634 : : /* Assume Sapphire Rapids. */
635 : 0 : else if (has_feature (FEATURE_TSXLDTRK))
636 : : cpu = "sapphirerapids";
637 : : /* Assume Cooper Lake */
638 : 0 : else if (has_feature (FEATURE_AVX512BF16))
639 : : cpu = "cooperlake";
640 : : /* Assume Ice Lake Server. */
641 : 0 : else if (has_feature (FEATURE_WBNOINVD))
642 : : cpu = "icelake-server";
643 : : /* Assume Ice Lake. */
644 : 0 : else if (has_feature (FEATURE_AVX512BITALG))
645 : : cpu = "icelake-client";
646 : : /* Assume Cannon Lake. */
647 : 0 : else if (has_feature (FEATURE_AVX512VBMI))
648 : : cpu = "cannonlake";
649 : : /* Assume Knights Mill. */
650 : 0 : else if (has_feature (FEATURE_AVX5124VNNIW))
651 : : cpu = "knm";
652 : : /* Assume Knights Landing. */
653 : 0 : else if (has_feature (FEATURE_AVX512ER))
654 : : cpu = "knl";
655 : : /* Assume Skylake with AVX-512. */
656 : : else
657 : 0 : cpu = "skylake-avx512";
658 : : }
659 : 0 : else if (has_feature (FEATURE_AVX))
660 : : {
661 : : /* Assume Panther Lake. */
662 : 0 : if (has_feature (FEATURE_PREFETCHI))
663 : : cpu = "pantherlake";
664 : : /* Assume Clearwater Forest. */
665 : 0 : else if (has_feature (FEATURE_USER_MSR))
666 : : cpu = "clearwaterforest";
667 : : /* Assume Arrow Lake S. */
668 : 0 : else if (has_feature (FEATURE_SM3))
669 : : cpu = "arrowlake-s";
670 : : /* Assume Sierra Forest. */
671 : 0 : else if (has_feature (FEATURE_AVXVNNIINT8))
672 : : cpu = "sierraforest";
673 : : /* Assume Alder Lake. */
674 : 0 : else if (has_feature (FEATURE_SERIALIZE))
675 : : cpu = "alderlake";
676 : : /* Assume Skylake. */
677 : 0 : else if (has_feature (FEATURE_CLFLUSHOPT))
678 : : cpu = "skylake";
679 : : /* Assume Broadwell. */
680 : 0 : else if (has_feature (FEATURE_ADX))
681 : : cpu = "broadwell";
682 : : /* Assume Haswell. */
683 : 0 : else if (has_feature (FEATURE_AVX2))
684 : : cpu = "haswell";
685 : : /* Assume Sandy Bridge. */
686 : : else
687 : 0 : cpu = "sandybridge";
688 : : }
689 : 0 : else if (has_feature (FEATURE_SSE4_2))
690 : : {
691 : 0 : if (has_feature (FEATURE_GFNI))
692 : : /* Assume Tremont. */
693 : : cpu = "tremont";
694 : 0 : else if (has_feature (FEATURE_SGX))
695 : : /* Assume Goldmont Plus. */
696 : : cpu = "goldmont-plus";
697 : 0 : else if (has_feature (FEATURE_XSAVE))
698 : : /* Assume Goldmont. */
699 : : cpu = "goldmont";
700 : 0 : else if (has_feature (FEATURE_MOVBE))
701 : : /* Assume Silvermont. */
702 : : cpu = "silvermont";
703 : : else
704 : : /* Assume Nehalem. */
705 : 0 : cpu = "nehalem";
706 : : }
707 : 0 : else if (has_feature (FEATURE_SSSE3))
708 : : {
709 : 0 : if (has_feature (FEATURE_MOVBE))
710 : : /* Assume Bonnell. */
711 : : cpu = "bonnell";
712 : : else
713 : : /* Assume Core 2. */
714 : 0 : cpu = "core2";
715 : : }
716 : 0 : else if (has_feature (FEATURE_LM))
717 : : /* Perhaps some emulator? Assume x86-64, otherwise gcc
718 : : -march=native would be unusable for 64-bit compilations,
719 : : as all the CPUs below are 32-bit only. */
720 : : cpu = "x86-64";
721 : 0 : else if (has_feature (FEATURE_SSE3))
722 : : {
723 : 0 : if (vendor == VENDOR_CENTAUR)
724 : : /* C7 / Eden "Esther" */
725 : : cpu = "c7";
726 : : else
727 : : /* It is Core Duo. */
728 : 0 : cpu = "pentium-m";
729 : : }
730 : 0 : else if (has_feature (FEATURE_SSE2))
731 : : /* It is Pentium M. */
732 : : cpu = "pentium-m";
733 : 0 : else if (has_feature (FEATURE_SSE))
734 : : {
735 : 0 : if (vendor == VENDOR_CENTAUR)
736 : : {
737 : 0 : if (model >= 9)
738 : : /* Eden "Nehemiah" */
739 : : cpu = "nehemiah";
740 : : else
741 : 0 : cpu = "c3-2";
742 : : }
743 : : else
744 : : /* It is Pentium III. */
745 : : cpu = "pentium3";
746 : : }
747 : 0 : else if (has_feature (FEATURE_MMX))
748 : : /* It is Pentium II. */
749 : : cpu = "pentium2";
750 : : else
751 : : /* Default to Pentium Pro. */
752 : 0 : cpu = "pentiumpro";
753 : : }
754 : : else
755 : : /* For -mtune, we default to -mtune=generic. */
756 : : cpu = "generic";
757 : : }
758 : : break;
759 : 0 : case PROCESSOR_PENTIUM4:
760 : 0 : if (has_feature (FEATURE_SSE3))
761 : : {
762 : 0 : if (has_feature (FEATURE_LM))
763 : : cpu = "nocona";
764 : : else
765 : 22 : cpu = "prescott";
766 : : }
767 : : else
768 : : cpu = "pentium4";
769 : : break;
770 : : case PROCESSOR_GEODE:
771 : : cpu = "geode";
772 : : break;
773 : 0 : case PROCESSOR_K6:
774 : 0 : if (arch && has_feature (FEATURE_3DNOW))
775 : : cpu = "k6-3";
776 : : else
777 : : cpu = "k6";
778 : : break;
779 : 0 : case PROCESSOR_ATHLON:
780 : 0 : if (arch && has_feature (FEATURE_SSE))
781 : : cpu = "athlon-4";
782 : : else
783 : : cpu = "athlon";
784 : : break;
785 : 0 : case PROCESSOR_K8:
786 : 0 : if (arch)
787 : : {
788 : 0 : if (vendor == VENDOR_CENTAUR)
789 : : {
790 : 0 : if (has_feature (FEATURE_SSE4_1))
791 : : /* Nano 3000 | Nano dual / quad core | Eden X4 */
792 : : cpu = "nano-3000";
793 : 0 : else if (has_feature (FEATURE_SSSE3))
794 : : /* Nano 1000 | Nano 2000 */
795 : : cpu = "nano";
796 : 0 : else if (has_feature (FEATURE_SSE3))
797 : : /* Eden X2 */
798 : : cpu = "eden-x2";
799 : : else
800 : : /* Default to k8 */
801 : 0 : cpu = "k8";
802 : : }
803 : 0 : else if (has_feature (FEATURE_SSE3))
804 : : cpu = "k8-sse3";
805 : : else
806 : 0 : cpu = "k8";
807 : : }
808 : : else
809 : : /* For -mtune, we default to -mtune=k8 */
810 : : cpu = "k8";
811 : : break;
812 : : case PROCESSOR_AMDFAM10:
813 : : cpu = "amdfam10";
814 : : break;
815 : : case PROCESSOR_BDVER1:
816 : : cpu = "bdver1";
817 : : break;
818 : : case PROCESSOR_BDVER2:
819 : : cpu = "bdver2";
820 : : break;
821 : : case PROCESSOR_BDVER3:
822 : : cpu = "bdver3";
823 : : break;
824 : : case PROCESSOR_BDVER4:
825 : : cpu = "bdver4";
826 : : break;
827 : : case PROCESSOR_ZNVER1:
828 : : cpu = "znver1";
829 : : break;
830 : : case PROCESSOR_ZNVER2:
831 : : cpu = "znver2";
832 : : break;
833 : : case PROCESSOR_ZNVER3:
834 : : cpu = "znver3";
835 : : break;
836 : : case PROCESSOR_ZNVER4:
837 : : cpu = "znver4";
838 : : break;
839 : : case PROCESSOR_ZNVER5:
840 : : cpu = "znver5";
841 : : break;
842 : : case PROCESSOR_BTVER1:
843 : : cpu = "btver1";
844 : : break;
845 : : case PROCESSOR_BTVER2:
846 : : cpu = "btver2";
847 : : break;
848 : : case PROCESSOR_LUJIAZUI:
849 : : cpu = "lujiazui";
850 : : break;
851 : : case PROCESSOR_YONGFENG:
852 : : cpu = "yongfeng";
853 : : break;
854 : :
855 : 0 : default:
856 : : /* Use something reasonable. */
857 : 0 : if (arch)
858 : : {
859 : 0 : if (has_feature (FEATURE_SSSE3))
860 : : cpu = "core2";
861 : 0 : else if (has_feature (FEATURE_SSE3))
862 : : {
863 : 0 : if (has_feature (FEATURE_LM))
864 : : cpu = "nocona";
865 : : else
866 : 22 : cpu = "prescott";
867 : : }
868 : 0 : else if (has_feature (FEATURE_LM))
869 : : /* Perhaps some emulator? Assume x86-64, otherwise gcc
870 : : -march=native would be unusable for 64-bit compilations,
871 : : as all the CPUs below are 32-bit only. */
872 : : cpu = "x86-64";
873 : 0 : else if (has_feature (FEATURE_SSE2))
874 : : cpu = "pentium4";
875 : 0 : else if (has_feature (FEATURE_CMOV))
876 : : cpu = "pentiumpro";
877 : 0 : else if (has_feature (FEATURE_MMX))
878 : : cpu = "pentium-mmx";
879 : 0 : else if (has_feature (FEATURE_CMPXCHG8B))
880 : 0 : cpu = "pentium";
881 : : }
882 : : else
883 : : cpu = "generic";
884 : : }
885 : :
886 : 22 : if (arch)
887 : : {
888 : : unsigned int i;
889 : : const char *const neg_option = " -mno-";
890 : 1287 : for (i = 0; i < ARRAY_SIZE (isa_names_table); i++)
891 : 1276 : if (isa_names_table[i].option)
892 : : {
893 : 1155 : if (has_feature (isa_names_table[i].feature))
894 : : {
895 : 429 : if (codegen_x86_64
896 : 0 : || isa_names_table[i].feature != FEATURE_UINTR)
897 : 429 : options = concat (options, " ",
898 : : isa_names_table[i].option, NULL);
899 : : }
900 : : /* Never push -mno-avx10.1-{256,512} under -march=native to
901 : : avoid unnecessary warnings when building librarys. */
902 : 726 : else if (isa_names_table[i].feature != FEATURE_AVX10_1_256
903 : 726 : && isa_names_table[i].feature != FEATURE_AVX10_1_512
904 : : && isa_names_table[i].feature != FEATURE_AVX512PF
905 : : && isa_names_table[i].feature != FEATURE_AVX512ER
906 : : && isa_names_table[i].feature != FEATURE_AVX5124FMAPS
907 : : && isa_names_table[i].feature != FEATURE_AVX5124VNNIW
908 : : && isa_names_table[i].feature != FEATURE_PREFETCHWT1
909 : 638 : && check_avx512_features (cpu_model, cpu_features2,
910 : : isa_names_table[i].feature))
911 : 638 : options = concat (options, neg_option,
912 : : isa_names_table[i].option + 2, NULL);
913 : : }
914 : : }
915 : :
916 : 11 : done:
917 : 22 : return concat (cache, "-m", argv[0], "=", cpu, options, NULL);
918 : : }
919 : : #else
920 : :
921 : : /* If we are compiling with GCC where %EBX register is fixed, then the
922 : : driver will just ignore -march and -mtune "native" target and will leave
923 : : to the newly built compiler to generate code for its default target. */
924 : :
925 : : const char *host_detect_local_cpu (int, const char **)
926 : : {
927 : : return NULL;
928 : : }
929 : : #endif /* __GNUC__ */
|