]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/i386/driver-i386.c
gcc/
[thirdparty/gcc.git] / gcc / config / i386 / driver-i386.c
CommitLineData
4009b53f 1/* Subroutines for the gcc driver.
d353bf18 2 Copyright (C) 2006-2015 Free Software Foundation, Inc.
4009b53f 3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
038d1e19 8the Free Software Foundation; either version 3, or (at your option)
4009b53f 9any later version.
10
11GCC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
038d1e19 17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
4009b53f 19
20#include "config.h"
21#include "system.h"
10e818c2 22#include "coretypes.h"
23#include "tm.h"
4009b53f 24
eada9ddd 25const char *host_detect_local_cpu (int argc, const char **argv);
26
b587c125 27#if defined(__GNUC__) && (__GNUC__ >= 5 || !defined(__PIC__))
daf03e2f 28#include "cpuid.h"
4009b53f 29
25010f2a 30struct cache_desc
31{
32 unsigned sizekb;
33 unsigned assoc;
34 unsigned line;
35};
36
37/* Returns command line parameters that describe size and
38 cache line size of the processor caches. */
78f46d45 39
40static char *
25010f2a 41describe_cache (struct cache_desc level1, struct cache_desc level2)
78f46d45 42{
4c8b808d 43 char size[100], line[100], size2[100];
78f46d45 44
25010f2a 45 /* At the moment, gcc does not use the information
46 about the associativity of the cache. */
47
faa14cce 48 snprintf (size, sizeof (size),
49 "--param l1-cache-size=%u ", level1.sizekb);
50 snprintf (line, sizeof (line),
51 "--param l1-cache-line-size=%u ", level1.line);
78f46d45 52
faa14cce 53 snprintf (size2, sizeof (size2),
54 "--param l2-cache-size=%u ", level2.sizekb);
78f46d45 55
faa14cce 56 return concat (size, line, size2, NULL);
4c8b808d 57}
58
25010f2a 59/* Detect L2 cache parameters using CPUID extended function 0x80000006. */
60
4c8b808d 61static void
25010f2a 62detect_l2_cache (struct cache_desc *level2)
4c8b808d 63{
25010f2a 64 unsigned eax, ebx, ecx, edx;
65 unsigned assoc;
4c8b808d 66
67 __cpuid (0x80000006, eax, ebx, ecx, edx);
68
25010f2a 69 level2->sizekb = (ecx >> 16) & 0xffff;
70 level2->line = ecx & 0xff;
71
4c8b808d 72 assoc = (ecx >> 12) & 0xf;
73 if (assoc == 6)
74 assoc = 8;
75 else if (assoc == 8)
76 assoc = 16;
77 else if (assoc >= 0xa && assoc <= 0xc)
78 assoc = 32 + (assoc - 0xa) * 16;
79 else if (assoc >= 0xd && assoc <= 0xe)
80 assoc = 96 + (assoc - 0xd) * 32;
25010f2a 81
82 level2->assoc = assoc;
78f46d45 83}
84
85/* Returns the description of caches for an AMD processor. */
86
4077bf7a 87static const char *
78f46d45 88detect_caches_amd (unsigned max_ext_level)
89{
90 unsigned eax, ebx, ecx, edx;
25010f2a 91
92 struct cache_desc level1, level2 = {0, 0, 0};
78f46d45 93
94 if (max_ext_level < 0x80000005)
4077bf7a 95 return "";
78f46d45 96
daf03e2f 97 __cpuid (0x80000005, eax, ebx, ecx, edx);
78f46d45 98
25010f2a 99 level1.sizekb = (ecx >> 24) & 0xff;
100 level1.assoc = (ecx >> 16) & 0xff;
101 level1.line = ecx & 0xff;
78f46d45 102
4c8b808d 103 if (max_ext_level >= 0x80000006)
25010f2a 104 detect_l2_cache (&level2);
4c8b808d 105
25010f2a 106 return describe_cache (level1, level2);
78f46d45 107}
108
25010f2a 109/* Decodes the size, the associativity and the cache line size of
110 L1/L2 caches of an Intel processor. Values are based on
111 "Intel Processor Identification and the CPUID Instruction"
112 [Application Note 485], revision -032, December 2007. */
78f46d45 113
114static void
25010f2a 115decode_caches_intel (unsigned reg, bool xeon_mp,
116 struct cache_desc *level1, struct cache_desc *level2)
78f46d45 117{
25010f2a 118 int i;
119
120 for (i = 24; i >= 0; i -= 8)
121 switch ((reg >> i) & 0xff)
122 {
123 case 0x0a:
124 level1->sizekb = 8; level1->assoc = 2; level1->line = 32;
125 break;
126 case 0x0c:
127 level1->sizekb = 16; level1->assoc = 4; level1->line = 32;
128 break;
a35af8e8 129 case 0x0d:
130 level1->sizekb = 16; level1->assoc = 4; level1->line = 64;
131 break;
132 case 0x0e:
133 level1->sizekb = 24; level1->assoc = 6; level1->line = 64;
134 break;
135 case 0x21:
136 level2->sizekb = 256; level2->assoc = 8; level2->line = 64;
137 break;
138 case 0x24:
139 level2->sizekb = 1024; level2->assoc = 16; level2->line = 64;
140 break;
25010f2a 141 case 0x2c:
142 level1->sizekb = 32; level1->assoc = 8; level1->line = 64;
143 break;
144 case 0x39:
145 level2->sizekb = 128; level2->assoc = 4; level2->line = 64;
146 break;
147 case 0x3a:
148 level2->sizekb = 192; level2->assoc = 6; level2->line = 64;
149 break;
150 case 0x3b:
151 level2->sizekb = 128; level2->assoc = 2; level2->line = 64;
152 break;
153 case 0x3c:
154 level2->sizekb = 256; level2->assoc = 4; level2->line = 64;
155 break;
156 case 0x3d:
157 level2->sizekb = 384; level2->assoc = 6; level2->line = 64;
158 break;
159 case 0x3e:
160 level2->sizekb = 512; level2->assoc = 4; level2->line = 64;
161 break;
162 case 0x41:
163 level2->sizekb = 128; level2->assoc = 4; level2->line = 32;
164 break;
165 case 0x42:
166 level2->sizekb = 256; level2->assoc = 4; level2->line = 32;
167 break;
168 case 0x43:
169 level2->sizekb = 512; level2->assoc = 4; level2->line = 32;
170 break;
171 case 0x44:
172 level2->sizekb = 1024; level2->assoc = 4; level2->line = 32;
173 break;
174 case 0x45:
175 level2->sizekb = 2048; level2->assoc = 4; level2->line = 32;
176 break;
a35af8e8 177 case 0x48:
178 level2->sizekb = 3072; level2->assoc = 12; level2->line = 64;
179 break;
25010f2a 180 case 0x49:
181 if (xeon_mp)
182 break;
183 level2->sizekb = 4096; level2->assoc = 16; level2->line = 64;
184 break;
185 case 0x4e:
186 level2->sizekb = 6144; level2->assoc = 24; level2->line = 64;
187 break;
188 case 0x60:
189 level1->sizekb = 16; level1->assoc = 8; level1->line = 64;
190 break;
191 case 0x66:
192 level1->sizekb = 8; level1->assoc = 4; level1->line = 64;
193 break;
194 case 0x67:
195 level1->sizekb = 16; level1->assoc = 4; level1->line = 64;
196 break;
197 case 0x68:
198 level1->sizekb = 32; level1->assoc = 4; level1->line = 64;
199 break;
200 case 0x78:
201 level2->sizekb = 1024; level2->assoc = 4; level2->line = 64;
202 break;
203 case 0x79:
204 level2->sizekb = 128; level2->assoc = 8; level2->line = 64;
205 break;
206 case 0x7a:
207 level2->sizekb = 256; level2->assoc = 8; level2->line = 64;
208 break;
209 case 0x7b:
210 level2->sizekb = 512; level2->assoc = 8; level2->line = 64;
211 break;
212 case 0x7c:
213 level2->sizekb = 1024; level2->assoc = 8; level2->line = 64;
214 break;
215 case 0x7d:
216 level2->sizekb = 2048; level2->assoc = 8; level2->line = 64;
217 break;
218 case 0x7f:
219 level2->sizekb = 512; level2->assoc = 2; level2->line = 64;
220 break;
a35af8e8 221 case 0x80:
222 level2->sizekb = 512; level2->assoc = 8; level2->line = 64;
223 break;
25010f2a 224 case 0x82:
225 level2->sizekb = 256; level2->assoc = 8; level2->line = 32;
226 break;
227 case 0x83:
228 level2->sizekb = 512; level2->assoc = 8; level2->line = 32;
229 break;
230 case 0x84:
231 level2->sizekb = 1024; level2->assoc = 8; level2->line = 32;
232 break;
233 case 0x85:
234 level2->sizekb = 2048; level2->assoc = 8; level2->line = 32;
235 break;
236 case 0x86:
237 level2->sizekb = 512; level2->assoc = 4; level2->line = 64;
238 break;
239 case 0x87:
240 level2->sizekb = 1024; level2->assoc = 8; level2->line = 64;
241
242 default:
243 break;
244 }
245}
78f46d45 246
25010f2a 247/* Detect cache parameters using CPUID function 2. */
78f46d45 248
25010f2a 249static void
250detect_caches_cpuid2 (bool xeon_mp,
251 struct cache_desc *level1, struct cache_desc *level2)
252{
85a2543a 253 unsigned regs[4];
254 int nreps, i;
25010f2a 255
85a2543a 256 __cpuid (2, regs[0], regs[1], regs[2], regs[3]);
25010f2a 257
85a2543a 258 nreps = regs[0] & 0x0f;
259 regs[0] &= ~0x0f;
25010f2a 260
261 while (--nreps >= 0)
78f46d45 262 {
85a2543a 263 for (i = 0; i < 4; i++)
264 if (regs[i] && !((regs[i] >> 31) & 1))
265 decode_caches_intel (regs[i], xeon_mp, level1, level2);
25010f2a 266
267 if (nreps)
85a2543a 268 __cpuid (2, regs[0], regs[1], regs[2], regs[3]);
25010f2a 269 }
270}
78f46d45 271
25010f2a 272/* Detect cache parameters using CPUID function 4. This
273 method doesn't require hardcoded tables. */
78f46d45 274
25010f2a 275enum cache_type
276{
277 CACHE_END = 0,
278 CACHE_DATA = 1,
279 CACHE_INST = 2,
280 CACHE_UNIFIED = 3
281};
282
283static void
3ba7ca5c 284detect_caches_cpuid4 (struct cache_desc *level1, struct cache_desc *level2,
285 struct cache_desc *level3)
25010f2a 286{
287 struct cache_desc *cache;
288
289 unsigned eax, ebx, ecx, edx;
290 int count;
291
292 for (count = 0;; count++)
293 {
294 __cpuid_count(4, count, eax, ebx, ecx, edx);
295 switch (eax & 0x1f)
296 {
297 case CACHE_END:
298 return;
299 case CACHE_DATA:
300 case CACHE_UNIFIED:
301 {
302 switch ((eax >> 5) & 0x07)
303 {
304 case 1:
305 cache = level1;
306 break;
307 case 2:
308 cache = level2;
309 break;
3ba7ca5c 310 case 3:
311 cache = level3;
312 break;
25010f2a 313 default:
314 cache = NULL;
315 }
316
317 if (cache)
318 {
319 unsigned sets = ecx + 1;
85a2543a 320 unsigned part = ((ebx >> 12) & 0x03ff) + 1;
25010f2a 321
85a2543a 322 cache->assoc = ((ebx >> 22) & 0x03ff) + 1;
25010f2a 323 cache->line = (ebx & 0x0fff) + 1;
25010f2a 324
325 cache->sizekb = (cache->assoc * part
326 * cache->line * sets) / 1024;
3ba7ca5c 327 }
25010f2a 328 }
78f46d45 329 default:
330 break;
331 }
332 }
333}
334
25010f2a 335/* Returns the description of caches for an Intel processor. */
78f46d45 336
4077bf7a 337static const char *
3ba7ca5c 338detect_caches_intel (bool xeon_mp, unsigned max_level,
339 unsigned max_ext_level, unsigned *l2sizekb)
78f46d45 340{
3ba7ca5c 341 struct cache_desc level1 = {0, 0, 0}, level2 = {0, 0, 0}, level3 = {0, 0, 0};
78f46d45 342
25010f2a 343 if (max_level >= 4)
3ba7ca5c 344 detect_caches_cpuid4 (&level1, &level2, &level3);
25010f2a 345 else if (max_level >= 2)
346 detect_caches_cpuid2 (xeon_mp, &level1, &level2);
347 else
4077bf7a 348 return "";
78f46d45 349
25010f2a 350 if (level1.sizekb == 0)
4077bf7a 351 return "";
78f46d45 352
3ba7ca5c 353 /* Let the L3 replace the L2. This assumes inclusive caches
354 and single threaded program for now. */
355 if (level3.sizekb)
356 level2 = level3;
357
25010f2a 358 /* Intel CPUs are equipped with AMD style L2 cache info. Try this
359 method if other methods fail to provide L2 cache parameters. */
360 if (level2.sizekb == 0 && max_ext_level >= 0x80000006)
361 detect_l2_cache (&level2);
4c8b808d 362
3ba7ca5c 363 *l2sizekb = level2.sizekb;
364
25010f2a 365 return describe_cache (level1, level2);
78f46d45 366}
367
4009b53f 368/* This will be called by the spec parser in gcc.c when it sees
369 a %:local_cpu_detect(args) construct. Currently it will be called
370 with either "arch" or "tune" as argument depending on if -march=native
371 or -mtune=native is to be substituted.
372
373 It returns a string containing new command line parameters to be
374 put at the place of the above two options, depending on what CPU
375 this is executed. E.g. "-march=k8" on an AMD64 machine
376 for -march=native.
377
378 ARGC and ARGV are set depending on the actual arguments given
379 in the spec. */
daf03e2f 380
4009b53f 381const char *host_detect_local_cpu (int argc, const char **argv)
382{
daf03e2f 383 enum processor_type processor = PROCESSOR_I386;
384 const char *cpu = "i386";
385
78f46d45 386 const char *cache = "";
92a5086b 387 const char *options = "";
daf03e2f 388
25010f2a 389 unsigned int eax, ebx, ecx, edx;
daf03e2f 390
391 unsigned int max_level, ext_level;
25010f2a 392
4009b53f 393 unsigned int vendor;
25010f2a 394 unsigned int model, family;
daf03e2f 395
396 unsigned int has_sse3, has_ssse3, has_cmpxchg16b;
397 unsigned int has_cmpxchg8b, has_cmov, has_mmx, has_sse, has_sse2;
398
399 /* Extended features */
400 unsigned int has_lahf_lm = 0, has_sse4a = 0;
401 unsigned int has_longmode = 0, has_3dnowp = 0, has_3dnow = 0;
c2d2fbe7 402 unsigned int has_movbe = 0, has_sse4_1 = 0, has_sse4_2 = 0;
d2a15bb8 403 unsigned int has_popcnt = 0, has_aes = 0, has_avx = 0, has_avx2 = 0;
fd3ed659 404 unsigned int has_pclmul = 0, has_abm = 0, has_lwp = 0;
93294988 405 unsigned int has_fma = 0, has_fma4 = 0, has_xop = 0;
2339767f 406 unsigned int has_bmi = 0, has_bmi2 = 0, has_tbm = 0, has_lzcnt = 0;
91af12fe 407 unsigned int has_hle = 0, has_rtm = 0;
db3de906 408 unsigned int has_rdrnd = 0, has_f16c = 0, has_fsgsbase = 0;
41bc5727 409 unsigned int has_rdseed = 0, has_prfchw = 0, has_adx = 0;
32eca732 410 unsigned int has_osxsave = 0, has_fxsr = 0, has_xsave = 0, has_xsaveopt = 0;
e13e1b39 411 unsigned int has_avx512er = 0, has_avx512pf = 0, has_avx512cd = 0;
e3659231 412 unsigned int has_avx512f = 0, has_sha = 0, has_prefetchwt1 = 0;
2ed44428 413 unsigned int has_clflushopt = 0, has_xsavec = 0, has_xsaves = 0;
5bb7556d 414 unsigned int has_avx512dq = 0, has_avx512bw = 0, has_avx512vl = 0;
741c191b 415 unsigned int has_avx512vbmi = 0, has_avx512ifma = 0, has_clwb = 0;
f17272b7 416 unsigned int has_pcommit = 0, has_mwaitx = 0;
daf03e2f 417
10e818c2 418 bool arch;
419
3ba7ca5c 420 unsigned int l2sizekb = 0;
421
10e818c2 422 if (argc < 1)
423 return NULL;
424
daf03e2f 425 arch = !strcmp (argv[0], "arch");
426
10e818c2 427 if (!arch && strcmp (argv[0], "tune"))
4009b53f 428 return NULL;
429
daf03e2f 430 max_level = __get_cpuid_max (0, &vendor);
431 if (max_level < 1)
4009b53f 432 goto done;
4009b53f 433
daf03e2f 434 __cpuid (1, eax, ebx, ecx, edx);
4009b53f 435
25010f2a 436 model = (eax >> 4) & 0x0f;
daf03e2f 437 family = (eax >> 8) & 0x0f;
e61df51b 438 if (vendor == signature_INTEL_ebx
439 || vendor == signature_AMD_ebx)
4ec32090 440 {
441 unsigned int extended_model, extended_family;
442
443 extended_model = (eax >> 12) & 0xf0;
444 extended_family = (eax >> 20) & 0xff;
445 if (family == 0x0f)
446 {
447 family += extended_family;
448 model += extended_model;
449 }
450 else if (family == 0x06)
451 model += extended_model;
452 }
daf03e2f 453
454 has_sse3 = ecx & bit_SSE3;
455 has_ssse3 = ecx & bit_SSSE3;
c2d2fbe7 456 has_sse4_1 = ecx & bit_SSE4_1;
457 has_sse4_2 = ecx & bit_SSE4_2;
458 has_avx = ecx & bit_AVX;
0c1a9b32 459 has_osxsave = ecx & bit_OSXSAVE;
daf03e2f 460 has_cmpxchg16b = ecx & bit_CMPXCHG16B;
525b61fa 461 has_movbe = ecx & bit_MOVBE;
c2d2fbe7 462 has_popcnt = ecx & bit_POPCNT;
463 has_aes = ecx & bit_AES;
464 has_pclmul = ecx & bit_PCLMUL;
93294988 465 has_fma = ecx & bit_FMA;
db3de906 466 has_f16c = ecx & bit_F16C;
467 has_rdrnd = ecx & bit_RDRND;
32eca732 468 has_xsave = ecx & bit_XSAVE;
4009b53f 469
daf03e2f 470 has_cmpxchg8b = edx & bit_CMPXCHG8B;
471 has_cmov = edx & bit_CMOV;
472 has_mmx = edx & bit_MMX;
32eca732 473 has_fxsr = edx & bit_FXSAVE;
daf03e2f 474 has_sse = edx & bit_SSE;
475 has_sse2 = edx & bit_SSE2;
476
90cfa5fe 477 if (max_level >= 7)
478 {
479 __cpuid_count (7, 0, eax, ebx, ecx, edx);
480
481 has_bmi = ebx & bit_BMI;
7f738025 482 has_hle = ebx & bit_HLE;
91af12fe 483 has_rtm = ebx & bit_RTM;
90cfa5fe 484 has_avx2 = ebx & bit_AVX2;
485 has_bmi2 = ebx & bit_BMI2;
db3de906 486 has_fsgsbase = ebx & bit_FSGSBASE;
eff9fe28 487 has_rdseed = ebx & bit_RDSEED;
41bc5727 488 has_adx = ebx & bit_ADX;
e13e1b39 489 has_avx512f = ebx & bit_AVX512F;
490 has_avx512er = ebx & bit_AVX512ER;
491 has_avx512pf = ebx & bit_AVX512PF;
492 has_avx512cd = ebx & bit_AVX512CD;
fc975a40 493 has_sha = ebx & bit_SHA;
d0b81ec0 494 has_pcommit = ebx & bit_PCOMMIT;
2ed44428 495 has_clflushopt = ebx & bit_CLFLUSHOPT;
741c191b 496 has_clwb = ebx & bit_CLWB;
89e0402e 497 has_avx512dq = ebx & bit_AVX512DQ;
38d90d48 498 has_avx512bw = ebx & bit_AVX512BW;
5bb7556d 499 has_avx512vl = ebx & bit_AVX512VL;
8a12b665 500 has_avx512vl = ebx & bit_AVX512IFMA;
e3659231 501
502 has_prefetchwt1 = ecx & bit_PREFETCHWT1;
afee0628 503 has_avx512vl = ecx & bit_AVX512VBMI;
90cfa5fe 504 }
505
32eca732 506 if (max_level >= 13)
507 {
508 __cpuid_count (13, 1, eax, ebx, ecx, edx);
509
510 has_xsaveopt = eax & bit_XSAVEOPT;
2ed44428 511 has_xsavec = eax & bit_XSAVEC;
512 has_xsaves = eax & bit_XSAVES;
32eca732 513 }
514
ccdeeb71 515 /* Check cpuid level of extended features. */
516 __cpuid (0x80000000, ext_level, ebx, ecx, edx);
517
518 if (ext_level > 0x80000000)
519 {
520 __cpuid (0x80000001, eax, ebx, ecx, edx);
521
522 has_lahf_lm = ecx & bit_LAHF_LM;
523 has_sse4a = ecx & bit_SSE4a;
524 has_abm = ecx & bit_ABM;
525 has_lwp = ecx & bit_LWP;
526 has_fma4 = ecx & bit_FMA4;
527 has_xop = ecx & bit_XOP;
528 has_tbm = ecx & bit_TBM;
529 has_lzcnt = ecx & bit_LZCNT;
530 has_prfchw = ecx & bit_PRFCHW;
531
532 has_longmode = edx & bit_LM;
533 has_3dnowp = edx & bit_3DNOWP;
534 has_3dnow = edx & bit_3DNOW;
f17272b7 535 has_mwaitx = ecx & bit_MWAITX;
ccdeeb71 536 }
537
0c1a9b32 538 /* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv. */
539#define XCR_XFEATURE_ENABLED_MASK 0x0
540#define XSTATE_FP 0x1
541#define XSTATE_SSE 0x2
542#define XSTATE_YMM 0x4
2a7a71ea 543#define XSTATE_OPMASK 0x20
544#define XSTATE_ZMM 0x40
545#define XSTATE_HI_ZMM 0x80
0c1a9b32 546 if (has_osxsave)
547 asm (".byte 0x0f; .byte 0x01; .byte 0xd0"
548 : "=a" (eax), "=d" (edx)
549 : "c" (XCR_XFEATURE_ENABLED_MASK));
550
551 /* Check if SSE and YMM states are supported. */
7c4d0933 552 if (!has_osxsave
553 || (eax & (XSTATE_SSE | XSTATE_YMM)) != (XSTATE_SSE | XSTATE_YMM))
0c1a9b32 554 {
555 has_avx = 0;
556 has_avx2 = 0;
557 has_fma = 0;
558 has_fma4 = 0;
ccdeeb71 559 has_f16c = 0;
0c1a9b32 560 has_xop = 0;
32eca732 561 has_xsave = 0;
562 has_xsaveopt = 0;
2ed44428 563 has_xsaves = 0;
564 has_xsavec = 0;
0c1a9b32 565 }
566
2a7a71ea 567 if (!has_osxsave
568 || (eax &
569 (XSTATE_SSE | XSTATE_YMM | XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM))
570 != (XSTATE_SSE | XSTATE_YMM | XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM))
571 {
572 has_avx512f = 0;
573 has_avx512er = 0;
574 has_avx512pf = 0;
575 has_avx512cd = 0;
576 has_avx512dq = 0;
577 has_avx512bw = 0;
578 has_avx512vl = 0;
579 }
580
78f46d45 581 if (!arch)
582 {
6d17d827 583 if (vendor == signature_AMD_ebx
e35017c0 584 || vendor == signature_CENTAUR_ebx
585 || vendor == signature_CYRIX_ebx
9bfede72 586 || vendor == signature_NSC_ebx)
78f46d45 587 cache = detect_caches_amd (ext_level);
865812bf 588 else if (vendor == signature_INTEL_ebx)
25010f2a 589 {
590 bool xeon_mp = (family == 15 && model == 6);
3ba7ca5c 591 cache = detect_caches_intel (xeon_mp, max_level,
592 ext_level, &l2sizekb);
25010f2a 593 }
78f46d45 594 }
595
865812bf 596 if (vendor == signature_AMD_ebx)
4009b53f 597 {
6ca2db76 598 unsigned int name;
daf03e2f 599
6ca2db76 600 /* Detect geode processor by its processor signature. */
601 if (ext_level > 0x80000001)
602 __cpuid (0x80000002, name, ebx, ecx, edx);
603 else
604 name = 0;
605
865812bf 606 if (name == signature_NSC_ebx)
6ca2db76 607 processor = PROCESSOR_GEODE;
e61df51b 608 else if (has_movbe && family == 22)
75eddf9a 609 processor = PROCESSOR_BTVER2;
ec3f1e8b 610 else if (has_avx2)
611 processor = PROCESSOR_BDVER4;
77aff08f 612 else if (has_xsaveopt)
613 processor = PROCESSOR_BDVER3;
8991ae0a 614 else if (has_bmi)
615 processor = PROCESSOR_BDVER2;
6fc76bb0 616 else if (has_xop)
617 processor = PROCESSOR_BDVER1;
a97faf6b 618 else if (has_sse4a && has_ssse3)
619 processor = PROCESSOR_BTVER1;
6ca2db76 620 else if (has_sse4a)
b60d490a 621 processor = PROCESSOR_AMDFAM10;
6ca2db76 622 else if (has_sse2 || has_longmode)
623 processor = PROCESSOR_K8;
7ddeda06 624 else if (has_3dnowp && family == 6)
6ca2db76 625 processor = PROCESSOR_ATHLON;
626 else if (has_mmx)
627 processor = PROCESSOR_K6;
628 else
629 processor = PROCESSOR_PENTIUM;
4009b53f 630 }
6d17d827 631 else if (vendor == signature_CENTAUR_ebx)
632 {
633 if (arch)
634 {
e35017c0 635 switch (family)
6d17d827 636 {
e35017c0 637 case 6:
6d17d827 638 if (model > 9)
639 /* Use the default detection procedure. */
f1435d0d 640 processor = PROCESSOR_GENERIC;
6d17d827 641 else if (model == 9)
642 cpu = "c3-2";
643 else if (model >= 6)
644 cpu = "c3";
645 else
f1435d0d 646 processor = PROCESSOR_GENERIC;
e35017c0 647 break;
648 case 5:
649 if (has_3dnow)
650 cpu = "winchip2";
651 else if (has_mmx)
652 cpu = "winchip2-c6";
653 else
f1435d0d 654 processor = PROCESSOR_GENERIC;
e35017c0 655 break;
656 default:
657 /* We have no idea. */
f1435d0d 658 processor = PROCESSOR_GENERIC;
6d17d827 659 }
6d17d827 660 }
661 }
4009b53f 662 else
663 {
10e818c2 664 switch (family)
665 {
daf03e2f 666 case 4:
667 processor = PROCESSOR_I486;
668 break;
10e818c2 669 case 5:
daf03e2f 670 processor = PROCESSOR_PENTIUM;
10e818c2 671 break;
672 case 6:
673 processor = PROCESSOR_PENTIUMPRO;
674 break;
675 case 15:
676 processor = PROCESSOR_PENTIUM4;
677 break;
678 default:
daf03e2f 679 /* We have no idea. */
f1435d0d 680 processor = PROCESSOR_GENERIC;
10e818c2 681 }
682 }
683
684 switch (processor)
685 {
686 case PROCESSOR_I386:
daf03e2f 687 /* Default. */
10e818c2 688 break;
689 case PROCESSOR_I486:
690 cpu = "i486";
691 break;
692 case PROCESSOR_PENTIUM:
daf03e2f 693 if (arch && has_mmx)
10e818c2 694 cpu = "pentium-mmx";
695 else
696 cpu = "pentium";
697 break;
698 case PROCESSOR_PENTIUMPRO:
bfb81bed 699 switch (model)
10e818c2 700 {
bfb81bed 701 case 0x1c:
702 case 0x26:
ccc305ff 703 /* Bonnell. */
704 cpu = "bonnell";
bfb81bed 705 break;
b848ffcd 706 case 0x37:
1b738d4d 707 case 0x4a:
b848ffcd 708 case 0x4d:
1b738d4d 709 case 0x5a:
710 case 0x5d:
b848ffcd 711 /* Silvermont. */
ccc305ff 712 cpu = "silvermont";
b848ffcd 713 break;
2f3d7a64 714 case 0x0f:
715 /* Merom. */
716 case 0x17:
717 case 0x1d:
718 /* Penryn. */
719 cpu = "core2";
720 break;
bfb81bed 721 case 0x1a:
722 case 0x1e:
723 case 0x1f:
724 case 0x2e:
2b16463d 725 /* Nehalem. */
ccc305ff 726 cpu = "nehalem";
727 break;
bfb81bed 728 case 0x25:
54ac3049 729 case 0x2c:
bfb81bed 730 case 0x2f:
2b16463d 731 /* Westmere. */
ccc305ff 732 cpu = "westmere";
bfb81bed 733 break;
e4168d53 734 case 0x2a:
9eae7f95 735 case 0x2d:
e4168d53 736 /* Sandy Bridge. */
ccc305ff 737 cpu = "sandybridge";
e4168d53 738 break;
2f3d7a64 739 case 0x3a:
740 case 0x3e:
741 /* Ivy Bridge. */
ccc305ff 742 cpu = "ivybridge";
bfb81bed 743 break;
2f3d7a64 744 case 0x3c:
1b738d4d 745 case 0x3f:
0f227eb8 746 case 0x45:
747 case 0x46:
2f3d7a64 748 /* Haswell. */
ccc305ff 749 cpu = "haswell";
bfb81bed 750 break;
1b738d4d 751 case 0x3d:
ff692203 752 case 0x47:
1b738d4d 753 case 0x4f:
754 case 0x56:
755 /* Broadwell. */
756 cpu = "broadwell";
757 break;
58bb1dbe 758 case 0x4e:
759 case 0x5e:
760 /* Skylake. */
761 cpu = "skylake";
762 break;
1b738d4d 763 case 0x57:
764 /* Knights Landing. */
765 cpu = "knl";
766 break;
bfb81bed 767 default:
768 if (arch)
769 {
59e32513 770 /* This is unknown family 0x6 CPU. */
8a5c90b2 771 /* Assume Knights Landing. */
772 if (has_avx512f)
773 cpu = "knl";
774 /* Assume Broadwell. */
775 else if (has_adx)
f86a627f 776 cpu = "broadwell";
777 else if (has_avx2)
2f3d7a64 778 /* Assume Haswell. */
ccc305ff 779 cpu = "haswell";
2f3d7a64 780 else if (has_avx)
59e32513 781 /* Assume Sandy Bridge. */
ccc305ff 782 cpu = "sandybridge";
59e32513 783 else if (has_sse4_2)
564c5b22 784 {
785 if (has_movbe)
ccc305ff 786 /* Assume Silvermont. */
787 cpu = "silvermont";
564c5b22 788 else
ccc305ff 789 /* Assume Nehalem. */
790 cpu = "nehalem";
564c5b22 791 }
59e32513 792 else if (has_ssse3)
793 {
794 if (has_movbe)
ccc305ff 795 /* Assume Bonnell. */
796 cpu = "bonnell";
59e32513 797 else
798 /* Assume Core 2. */
799 cpu = "core2";
800 }
10b9f8d4 801 else if (has_longmode)
802 /* Perhaps some emulator? Assume x86-64, otherwise gcc
803 -march=native would be unusable for 64-bit compilations,
804 as all the CPUs below are 32-bit only. */
805 cpu = "x86-64";
f83a3614 806 else if (has_sse3)
807 /* It is Core Duo. */
808 cpu = "pentium-m";
809 else if (has_sse2)
810 /* It is Pentium M. */
811 cpu = "pentium-m";
812 else if (has_sse)
813 /* It is Pentium III. */
814 cpu = "pentium3";
815 else if (has_mmx)
816 /* It is Pentium II. */
817 cpu = "pentium2";
bfb81bed 818 else
f83a3614 819 /* Default to Pentium Pro. */
820 cpu = "pentiumpro";
bfb81bed 821 }
daf03e2f 822 else
bfb81bed 823 /* For -mtune, we default to -mtune=generic. */
824 cpu = "generic";
825 break;
4009b53f 826 }
daf03e2f 827 break;
828 case PROCESSOR_PENTIUM4:
829 if (has_sse3)
4009b53f 830 {
daf03e2f 831 if (has_longmode)
832 cpu = "nocona";
4009b53f 833 else
f83a3614 834 cpu = "prescott";
4009b53f 835 }
daf03e2f 836 else
f83a3614 837 cpu = "pentium4";
10e818c2 838 break;
839 case PROCESSOR_GEODE:
840 cpu = "geode";
841 break;
842 case PROCESSOR_K6:
daf03e2f 843 if (arch && has_3dnow)
844 cpu = "k6-3";
10e818c2 845 else
846 cpu = "k6";
847 break;
848 case PROCESSOR_ATHLON:
daf03e2f 849 if (arch && has_sse)
10e818c2 850 cpu = "athlon-4";
851 else
852 cpu = "athlon";
853 break;
10e818c2 854 case PROCESSOR_K8:
daf03e2f 855 if (arch && has_sse3)
856 cpu = "k8-sse3";
857 else
858 cpu = "k8";
10e818c2 859 break;
b60d490a 860 case PROCESSOR_AMDFAM10:
861 cpu = "amdfam10";
862 break;
6fc76bb0 863 case PROCESSOR_BDVER1:
864 cpu = "bdver1";
865 break;
8991ae0a 866 case PROCESSOR_BDVER2:
867 cpu = "bdver2";
868 break;
77aff08f 869 case PROCESSOR_BDVER3:
870 cpu = "bdver3";
871 break;
ec3f1e8b 872 case PROCESSOR_BDVER4:
873 cpu = "bdver4";
874 break;
a97faf6b 875 case PROCESSOR_BTVER1:
876 cpu = "btver1";
877 break;
75eddf9a 878 case PROCESSOR_BTVER2:
879 cpu = "btver2";
880 break;
daf03e2f 881
10e818c2 882 default:
daf03e2f 883 /* Use something reasonable. */
884 if (arch)
885 {
886 if (has_ssse3)
887 cpu = "core2";
888 else if (has_sse3)
889 {
890 if (has_longmode)
891 cpu = "nocona";
892 else
893 cpu = "prescott";
894 }
895 else if (has_sse2)
896 cpu = "pentium4";
897 else if (has_cmov)
898 cpu = "pentiumpro";
899 else if (has_mmx)
900 cpu = "pentium-mmx";
901 else if (has_cmpxchg8b)
902 cpu = "pentium";
903 }
904 else
905 cpu = "generic";
4009b53f 906 }
907
92a5086b 908 if (arch)
909 {
fb0f74a7 910 const char *mmx = has_mmx ? " -mmmx" : " -mno-mmx";
911 const char *mmx3dnow = has_3dnow ? " -m3dnow" : " -mno-3dnow";
912 const char *sse = has_sse ? " -msse" : " -mno-sse";
913 const char *sse2 = has_sse2 ? " -msse2" : " -mno-sse2";
914 const char *sse3 = has_sse3 ? " -msse3" : " -mno-sse3";
915 const char *ssse3 = has_ssse3 ? " -mssse3" : " -mno-ssse3";
916 const char *sse4a = has_sse4a ? " -msse4a" : " -mno-sse4a";
93294988 917 const char *cx16 = has_cmpxchg16b ? " -mcx16" : " -mno-cx16";
918 const char *sahf = has_lahf_lm ? " -msahf" : " -mno-sahf";
919 const char *movbe = has_movbe ? " -mmovbe" : " -mno-movbe";
fb0f74a7 920 const char *aes = has_aes ? " -maes" : " -mno-aes";
fc975a40 921 const char *sha = has_sha ? " -msha" : " -mno-sha";
93294988 922 const char *pclmul = has_pclmul ? " -mpclmul" : " -mno-pclmul";
923 const char *popcnt = has_popcnt ? " -mpopcnt" : " -mno-popcnt";
924 const char *abm = has_abm ? " -mabm" : " -mno-abm";
925 const char *lwp = has_lwp ? " -mlwp" : " -mno-lwp";
926 const char *fma = has_fma ? " -mfma" : " -mno-fma";
927 const char *fma4 = has_fma4 ? " -mfma4" : " -mno-fma4";
928 const char *xop = has_xop ? " -mxop" : " -mno-xop";
929 const char *bmi = has_bmi ? " -mbmi" : " -mno-bmi";
2339767f 930 const char *bmi2 = has_bmi2 ? " -mbmi2" : " -mno-bmi2";
93294988 931 const char *tbm = has_tbm ? " -mtbm" : " -mno-tbm";
932 const char *avx = has_avx ? " -mavx" : " -mno-avx";
d2a15bb8 933 const char *avx2 = has_avx2 ? " -mavx2" : " -mno-avx2";
5042e3a4 934 const char *sse4_2 = has_sse4_2 ? " -msse4.2" : " -mno-sse4.2";
93294988 935 const char *sse4_1 = has_sse4_1 ? " -msse4.1" : " -mno-sse4.1";
78be71f4 936 const char *lzcnt = has_lzcnt ? " -mlzcnt" : " -mno-lzcnt";
c79c9a8d 937 const char *hle = has_hle ? " -mhle" : " -mno-hle";
91af12fe 938 const char *rtm = has_rtm ? " -mrtm" : " -mno-rtm";
db3de906 939 const char *rdrnd = has_rdrnd ? " -mrdrnd" : " -mno-rdrnd";
940 const char *f16c = has_f16c ? " -mf16c" : " -mno-f16c";
941 const char *fsgsbase = has_fsgsbase ? " -mfsgsbase" : " -mno-fsgsbase";
eff9fe28 942 const char *rdseed = has_rdseed ? " -mrdseed" : " -mno-rdseed";
7962a5b1 943 const char *prfchw = has_prfchw ? " -mprfchw" : " -mno-prfchw";
41bc5727 944 const char *adx = has_adx ? " -madx" : " -mno-adx";
32eca732 945 const char *fxsr = has_fxsr ? " -mfxsr" : " -mno-fxsr";
946 const char *xsave = has_xsave ? " -mxsave" : " -mno-xsave";
947 const char *xsaveopt = has_xsaveopt ? " -mxsaveopt" : " -mno-xsaveopt";
e13e1b39 948 const char *avx512f = has_avx512f ? " -mavx512f" : " -mno-avx512f";
949 const char *avx512er = has_avx512er ? " -mavx512er" : " -mno-avx512er";
950 const char *avx512cd = has_avx512cd ? " -mavx512cd" : " -mno-avx512cd";
951 const char *avx512pf = has_avx512pf ? " -mavx512pf" : " -mno-avx512pf";
e3659231 952 const char *prefetchwt1 = has_prefetchwt1 ? " -mprefetchwt1" : " -mno-prefetchwt1";
2ed44428 953 const char *clflushopt = has_clflushopt ? " -mclflushopt" : " -mno-clflushopt";
954 const char *xsavec = has_xsavec ? " -mxsavec" : " -mno-xsavec";
955 const char *xsaves = has_xsaves ? " -mxsaves" : " -mno-xsaves";
89e0402e 956 const char *avx512dq = has_avx512dq ? " -mavx512dq" : " -mno-avx512dq";
38d90d48 957 const char *avx512bw = has_avx512bw ? " -mavx512bw" : " -mno-avx512bw";
5bb7556d 958 const char *avx512vl = has_avx512vl ? " -mavx512vl" : " -mno-avx512vl";
8a12b665 959 const char *avx512ifma = has_avx512ifma ? " -mavx512ifma" : " -mno-avx512ifma";
afee0628 960 const char *avx512vbmi = has_avx512vbmi ? " -mavx512vbmi" : " -mno-avx512vbmi";
741c191b 961 const char *clwb = has_clwb ? " -mclwb" : " -mno-clwb";
d0b81ec0 962 const char *pcommit = has_pcommit ? " -mpcommit" : " -mno-pcommit";
f17272b7 963 const char *mwaitx = has_mwaitx ? " -mmwaitx" : " -mno-mwaitx";
93294988 964
fb0f74a7 965 options = concat (options, mmx, mmx3dnow, sse, sse2, sse3, ssse3,
fc975a40 966 sse4a, cx16, sahf, movbe, aes, sha, pclmul,
2339767f 967 popcnt, abm, lwp, fma, fma4, xop, bmi, bmi2,
91af12fe 968 tbm, avx, avx2, sse4_2, sse4_1, lzcnt, rtm,
32eca732 969 hle, rdrnd, f16c, fsgsbase, rdseed, prfchw, adx,
e13e1b39 970 fxsr, xsave, xsaveopt, avx512f, avx512er,
2ed44428 971 avx512cd, avx512pf, prefetchwt1, clflushopt,
5bb7556d 972 xsavec, xsaves, avx512dq, avx512bw, avx512vl,
f17272b7 973 avx512ifma, avx512vbmi, clwb, pcommit, mwaitx, NULL);
92a5086b 974 }
975
4009b53f 976done:
faa14cce 977 return concat (cache, "-m", argv[0], "=", cpu, options, NULL);
4009b53f 978}
979#else
daf03e2f 980
b587c125 981/* If we are compiling with GCC where %EBX register is fixed, then the
982 driver will just ignore -march and -mtune "native" target and will leave
983 to the newly built compiler to generate code for its default target. */
daf03e2f 984
c01e3606 985const char *host_detect_local_cpu (int, const char **)
4009b53f 986{
faa14cce 987 return NULL;
4009b53f 988}
a29cc4b6 989#endif /* __GNUC__ */