]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/i386/driver-i386.c
re PR tree-optimization/71488 (Wrong code for vector comparisons with ivybridge and...
[thirdparty/gcc.git] / gcc / config / i386 / driver-i386.c
CommitLineData
fa959ce4 1/* Subroutines for the gcc driver.
818ab71a 2 Copyright (C) 2006-2016 Free Software Foundation, Inc.
fa959ce4
MM
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
2f83c7d6 8the Free Software Foundation; either version 3, or (at your option)
fa959ce4
MM
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
2f83c7d6
NC
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
fa959ce4
MM
19
20#include "config.h"
21#include "system.h"
edccdcb1
L
22#include "coretypes.h"
23#include "tm.h"
fa959ce4 24
895016f6
UB
25const char *host_detect_local_cpu (int argc, const char **argv);
26
02147868 27#if defined(__GNUC__) && (__GNUC__ >= 5 || !defined(__PIC__))
b3172cab 28#include "cpuid.h"
fa959ce4 29
cb0dee88
UB
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. */
2711355f
ZD
39
40static char *
cb0dee88 41describe_cache (struct cache_desc level1, struct cache_desc level2)
2711355f 42{
f4a1dd0d 43 char size[100], line[100], size2[100];
2711355f 44
cb0dee88
UB
45 /* At the moment, gcc does not use the information
46 about the associativity of the cache. */
47
f3afc8a7
UB
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);
2711355f 52
f3afc8a7
UB
53 snprintf (size2, sizeof (size2),
54 "--param l2-cache-size=%u ", level2.sizekb);
2711355f 55
f3afc8a7 56 return concat (size, line, size2, NULL);
f4a1dd0d
ZM
57}
58
cb0dee88
UB
59/* Detect L2 cache parameters using CPUID extended function 0x80000006. */
60
f4a1dd0d 61static void
cb0dee88 62detect_l2_cache (struct cache_desc *level2)
f4a1dd0d 63{
cb0dee88
UB
64 unsigned eax, ebx, ecx, edx;
65 unsigned assoc;
f4a1dd0d
ZM
66
67 __cpuid (0x80000006, eax, ebx, ecx, edx);
68
cb0dee88
UB
69 level2->sizekb = (ecx >> 16) & 0xffff;
70 level2->line = ecx & 0xff;
71
f4a1dd0d
ZM
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;
cb0dee88
UB
81
82 level2->assoc = assoc;
2711355f
ZD
83}
84
85/* Returns the description of caches for an AMD processor. */
86
d3bfe4de 87static const char *
2711355f
ZD
88detect_caches_amd (unsigned max_ext_level)
89{
90 unsigned eax, ebx, ecx, edx;
cb0dee88
UB
91
92 struct cache_desc level1, level2 = {0, 0, 0};
2711355f
ZD
93
94 if (max_ext_level < 0x80000005)
d3bfe4de 95 return "";
2711355f 96
b3172cab 97 __cpuid (0x80000005, eax, ebx, ecx, edx);
2711355f 98
cb0dee88
UB
99 level1.sizekb = (ecx >> 24) & 0xff;
100 level1.assoc = (ecx >> 16) & 0xff;
101 level1.line = ecx & 0xff;
2711355f 102
f4a1dd0d 103 if (max_ext_level >= 0x80000006)
cb0dee88 104 detect_l2_cache (&level2);
f4a1dd0d 105
cb0dee88 106 return describe_cache (level1, level2);
2711355f
ZD
107}
108
cb0dee88
UB
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. */
2711355f
ZD
113
114static void
cb0dee88
UB
115decode_caches_intel (unsigned reg, bool xeon_mp,
116 struct cache_desc *level1, struct cache_desc *level2)
2711355f 117{
cb0dee88
UB
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;
f313cce5
UB
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;
cb0dee88
UB
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;
f313cce5
UB
177 case 0x48:
178 level2->sizekb = 3072; level2->assoc = 12; level2->line = 64;
179 break;
cb0dee88
UB
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;
f313cce5
UB
221 case 0x80:
222 level2->sizekb = 512; level2->assoc = 8; level2->line = 64;
223 break;
cb0dee88
UB
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}
2711355f 246
cb0dee88 247/* Detect cache parameters using CPUID function 2. */
2711355f 248
cb0dee88
UB
249static void
250detect_caches_cpuid2 (bool xeon_mp,
251 struct cache_desc *level1, struct cache_desc *level2)
252{
dc8bd8d9
UB
253 unsigned regs[4];
254 int nreps, i;
cb0dee88 255
dc8bd8d9 256 __cpuid (2, regs[0], regs[1], regs[2], regs[3]);
cb0dee88 257
dc8bd8d9
UB
258 nreps = regs[0] & 0x0f;
259 regs[0] &= ~0x0f;
cb0dee88
UB
260
261 while (--nreps >= 0)
2711355f 262 {
dc8bd8d9
UB
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);
cb0dee88
UB
266
267 if (nreps)
dc8bd8d9 268 __cpuid (2, regs[0], regs[1], regs[2], regs[3]);
cb0dee88
UB
269 }
270}
2711355f 271
cb0dee88
UB
272/* Detect cache parameters using CPUID function 4. This
273 method doesn't require hardcoded tables. */
2711355f 274
cb0dee88
UB
275enum cache_type
276{
277 CACHE_END = 0,
278 CACHE_DATA = 1,
279 CACHE_INST = 2,
280 CACHE_UNIFIED = 3
281};
282
283static void
a0463099
AK
284detect_caches_cpuid4 (struct cache_desc *level1, struct cache_desc *level2,
285 struct cache_desc *level3)
cb0dee88
UB
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;
a0463099
AK
310 case 3:
311 cache = level3;
312 break;
cb0dee88
UB
313 default:
314 cache = NULL;
315 }
316
317 if (cache)
318 {
319 unsigned sets = ecx + 1;
dc8bd8d9 320 unsigned part = ((ebx >> 12) & 0x03ff) + 1;
cb0dee88 321
dc8bd8d9 322 cache->assoc = ((ebx >> 22) & 0x03ff) + 1;
cb0dee88 323 cache->line = (ebx & 0x0fff) + 1;
cb0dee88
UB
324
325 cache->sizekb = (cache->assoc * part
326 * cache->line * sets) / 1024;
a0463099 327 }
cb0dee88 328 }
2711355f
ZD
329 default:
330 break;
331 }
332 }
333}
334
cb0dee88 335/* Returns the description of caches for an Intel processor. */
2711355f 336
d3bfe4de 337static const char *
a0463099
AK
338detect_caches_intel (bool xeon_mp, unsigned max_level,
339 unsigned max_ext_level, unsigned *l2sizekb)
2711355f 340{
a0463099 341 struct cache_desc level1 = {0, 0, 0}, level2 = {0, 0, 0}, level3 = {0, 0, 0};
2711355f 342
cb0dee88 343 if (max_level >= 4)
a0463099 344 detect_caches_cpuid4 (&level1, &level2, &level3);
cb0dee88
UB
345 else if (max_level >= 2)
346 detect_caches_cpuid2 (xeon_mp, &level1, &level2);
347 else
d3bfe4de 348 return "";
2711355f 349
cb0dee88 350 if (level1.sizekb == 0)
d3bfe4de 351 return "";
2711355f 352
a0463099
AK
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
cb0dee88
UB
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);
f4a1dd0d 362
a0463099
AK
363 *l2sizekb = level2.sizekb;
364
cb0dee88 365 return describe_cache (level1, level2);
2711355f
ZD
366}
367
fa959ce4
MM
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. */
b3172cab 380
fa959ce4
MM
381const char *host_detect_local_cpu (int argc, const char **argv)
382{
b3172cab
UB
383 enum processor_type processor = PROCESSOR_I386;
384 const char *cpu = "i386";
385
2711355f 386 const char *cache = "";
5be6cb59 387 const char *options = "";
b3172cab 388
cb0dee88 389 unsigned int eax, ebx, ecx, edx;
b3172cab
UB
390
391 unsigned int max_level, ext_level;
cb0dee88 392
fa959ce4 393 unsigned int vendor;
cb0dee88 394 unsigned int model, family;
b3172cab
UB
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;
634fa334 402 unsigned int has_movbe = 0, has_sse4_1 = 0, has_sse4_2 = 0;
7afac110 403 unsigned int has_popcnt = 0, has_aes = 0, has_avx = 0, has_avx2 = 0;
8ad9d49e 404 unsigned int has_pclmul = 0, has_abm = 0, has_lwp = 0;
5eed4f27 405 unsigned int has_fma = 0, has_fma4 = 0, has_xop = 0;
82feeb8d 406 unsigned int has_bmi = 0, has_bmi2 = 0, has_tbm = 0, has_lzcnt = 0;
76a02e42 407 unsigned int has_hle = 0, has_rtm = 0;
d1925759 408 unsigned int has_rdrnd = 0, has_f16c = 0, has_fsgsbase = 0;
d05e383b 409 unsigned int has_rdseed = 0, has_prfchw = 0, has_adx = 0;
3a0d99bb 410 unsigned int has_osxsave = 0, has_fxsr = 0, has_xsave = 0, has_xsaveopt = 0;
3f97cb0b 411 unsigned int has_avx512er = 0, has_avx512pf = 0, has_avx512cd = 0;
43b3f52f 412 unsigned int has_avx512f = 0, has_sha = 0, has_prefetchwt1 = 0;
9cdea277 413 unsigned int has_clflushopt = 0, has_xsavec = 0, has_xsaves = 0;
f4af595f 414 unsigned int has_avx512dq = 0, has_avx512bw = 0, has_avx512vl = 0;
9c3bca11 415 unsigned int has_avx512vbmi = 0, has_avx512ifma = 0, has_clwb = 0;
500a08b2 416 unsigned int has_pcommit = 0, has_mwaitx = 0;
41a4ef22 417 unsigned int has_clzero = 0, has_pku = 0;
b3172cab 418
edccdcb1
L
419 bool arch;
420
a0463099
AK
421 unsigned int l2sizekb = 0;
422
edccdcb1
L
423 if (argc < 1)
424 return NULL;
425
b3172cab
UB
426 arch = !strcmp (argv[0], "arch");
427
edccdcb1 428 if (!arch && strcmp (argv[0], "tune"))
fa959ce4
MM
429 return NULL;
430
b3172cab
UB
431 max_level = __get_cpuid_max (0, &vendor);
432 if (max_level < 1)
fa959ce4 433 goto done;
fa959ce4 434
b3172cab 435 __cpuid (1, eax, ebx, ecx, edx);
fa959ce4 436
cb0dee88 437 model = (eax >> 4) & 0x0f;
b3172cab 438 family = (eax >> 8) & 0x0f;
d478ac59
GG
439 if (vendor == signature_INTEL_ebx
440 || vendor == signature_AMD_ebx)
37c50435
L
441 {
442 unsigned int extended_model, extended_family;
443
444 extended_model = (eax >> 12) & 0xf0;
445 extended_family = (eax >> 20) & 0xff;
446 if (family == 0x0f)
447 {
448 family += extended_family;
449 model += extended_model;
450 }
451 else if (family == 0x06)
452 model += extended_model;
453 }
b3172cab
UB
454
455 has_sse3 = ecx & bit_SSE3;
456 has_ssse3 = ecx & bit_SSSE3;
634fa334
L
457 has_sse4_1 = ecx & bit_SSE4_1;
458 has_sse4_2 = ecx & bit_SSE4_2;
459 has_avx = ecx & bit_AVX;
a91529c4 460 has_osxsave = ecx & bit_OSXSAVE;
b3172cab 461 has_cmpxchg16b = ecx & bit_CMPXCHG16B;
cabf85c3 462 has_movbe = ecx & bit_MOVBE;
634fa334
L
463 has_popcnt = ecx & bit_POPCNT;
464 has_aes = ecx & bit_AES;
465 has_pclmul = ecx & bit_PCLMUL;
5eed4f27 466 has_fma = ecx & bit_FMA;
d1925759
L
467 has_f16c = ecx & bit_F16C;
468 has_rdrnd = ecx & bit_RDRND;
3a0d99bb 469 has_xsave = ecx & bit_XSAVE;
fa959ce4 470
b3172cab
UB
471 has_cmpxchg8b = edx & bit_CMPXCHG8B;
472 has_cmov = edx & bit_CMOV;
473 has_mmx = edx & bit_MMX;
3a0d99bb 474 has_fxsr = edx & bit_FXSAVE;
b3172cab
UB
475 has_sse = edx & bit_SSE;
476 has_sse2 = edx & bit_SSE2;
477
2c9b39ef
L
478 if (max_level >= 7)
479 {
480 __cpuid_count (7, 0, eax, ebx, ecx, edx);
481
482 has_bmi = ebx & bit_BMI;
5dcfdccd 483 has_hle = ebx & bit_HLE;
76a02e42 484 has_rtm = ebx & bit_RTM;
2c9b39ef
L
485 has_avx2 = ebx & bit_AVX2;
486 has_bmi2 = ebx & bit_BMI2;
d1925759 487 has_fsgsbase = ebx & bit_FSGSBASE;
4c340b5d 488 has_rdseed = ebx & bit_RDSEED;
d05e383b 489 has_adx = ebx & bit_ADX;
3f97cb0b
AI
490 has_avx512f = ebx & bit_AVX512F;
491 has_avx512er = ebx & bit_AVX512ER;
492 has_avx512pf = ebx & bit_AVX512PF;
493 has_avx512cd = ebx & bit_AVX512CD;
c1618f82 494 has_sha = ebx & bit_SHA;
36e9b73e 495 has_pcommit = ebx & bit_PCOMMIT;
9cdea277 496 has_clflushopt = ebx & bit_CLFLUSHOPT;
9c3bca11 497 has_clwb = ebx & bit_CLWB;
07165dd7 498 has_avx512dq = ebx & bit_AVX512DQ;
b525d943 499 has_avx512bw = ebx & bit_AVX512BW;
f4af595f 500 has_avx512vl = ebx & bit_AVX512VL;
4190ea38 501 has_avx512vl = ebx & bit_AVX512IFMA;
43b3f52f
IT
502
503 has_prefetchwt1 = ecx & bit_PREFETCHWT1;
41a4ef22
KY
504 has_avx512vbmi = ecx & bit_AVX512VBMI;
505 has_pku = ecx & bit_OSPKE;
2c9b39ef
L
506 }
507
3a0d99bb
AI
508 if (max_level >= 13)
509 {
510 __cpuid_count (13, 1, eax, ebx, ecx, edx);
511
512 has_xsaveopt = eax & bit_XSAVEOPT;
9cdea277
IT
513 has_xsavec = eax & bit_XSAVEC;
514 has_xsaves = eax & bit_XSAVES;
3a0d99bb
AI
515 }
516
d0b50387
JJ
517 /* Check cpuid level of extended features. */
518 __cpuid (0x80000000, ext_level, ebx, ecx, edx);
519
520 if (ext_level > 0x80000000)
521 {
522 __cpuid (0x80000001, eax, ebx, ecx, edx);
523
524 has_lahf_lm = ecx & bit_LAHF_LM;
525 has_sse4a = ecx & bit_SSE4a;
526 has_abm = ecx & bit_ABM;
527 has_lwp = ecx & bit_LWP;
528 has_fma4 = ecx & bit_FMA4;
529 has_xop = ecx & bit_XOP;
530 has_tbm = ecx & bit_TBM;
531 has_lzcnt = ecx & bit_LZCNT;
532 has_prfchw = ecx & bit_PRFCHW;
533
534 has_longmode = edx & bit_LM;
535 has_3dnowp = edx & bit_3DNOWP;
536 has_3dnow = edx & bit_3DNOW;
500a08b2 537 has_mwaitx = ecx & bit_MWAITX;
9ce29eb0
VK
538
539 __cpuid (0x80000008, eax, ebx, ecx, edx);
540 has_clzero = ebx & bit_CLZERO;
d0b50387
JJ
541 }
542
a91529c4
L
543 /* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv. */
544#define XCR_XFEATURE_ENABLED_MASK 0x0
545#define XSTATE_FP 0x1
546#define XSTATE_SSE 0x2
547#define XSTATE_YMM 0x4
2c12f2f4
IT
548#define XSTATE_OPMASK 0x20
549#define XSTATE_ZMM 0x40
550#define XSTATE_HI_ZMM 0x80
a91529c4
L
551 if (has_osxsave)
552 asm (".byte 0x0f; .byte 0x01; .byte 0xd0"
553 : "=a" (eax), "=d" (edx)
554 : "c" (XCR_XFEATURE_ENABLED_MASK));
555
556 /* Check if SSE and YMM states are supported. */
953ac966
AN
557 if (!has_osxsave
558 || (eax & (XSTATE_SSE | XSTATE_YMM)) != (XSTATE_SSE | XSTATE_YMM))
a91529c4
L
559 {
560 has_avx = 0;
561 has_avx2 = 0;
562 has_fma = 0;
563 has_fma4 = 0;
d0b50387 564 has_f16c = 0;
a91529c4 565 has_xop = 0;
3a0d99bb
AI
566 has_xsave = 0;
567 has_xsaveopt = 0;
9cdea277
IT
568 has_xsaves = 0;
569 has_xsavec = 0;
a91529c4
L
570 }
571
2c12f2f4
IT
572 if (!has_osxsave
573 || (eax &
574 (XSTATE_SSE | XSTATE_YMM | XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM))
575 != (XSTATE_SSE | XSTATE_YMM | XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM))
576 {
577 has_avx512f = 0;
578 has_avx512er = 0;
579 has_avx512pf = 0;
580 has_avx512cd = 0;
581 has_avx512dq = 0;
582 has_avx512bw = 0;
583 has_avx512vl = 0;
584 }
585
2711355f
ZD
586 if (!arch)
587 {
19db293a 588 if (vendor == signature_AMD_ebx
af0e415b
UB
589 || vendor == signature_CENTAUR_ebx
590 || vendor == signature_CYRIX_ebx
7b9d1bd8 591 || vendor == signature_NSC_ebx)
2711355f 592 cache = detect_caches_amd (ext_level);
ef64d158 593 else if (vendor == signature_INTEL_ebx)
cb0dee88
UB
594 {
595 bool xeon_mp = (family == 15 && model == 6);
a0463099
AK
596 cache = detect_caches_intel (xeon_mp, max_level,
597 ext_level, &l2sizekb);
cb0dee88 598 }
2711355f
ZD
599 }
600
ef64d158 601 if (vendor == signature_AMD_ebx)
fa959ce4 602 {
fbdf817d 603 unsigned int name;
b3172cab 604
fbdf817d
UB
605 /* Detect geode processor by its processor signature. */
606 if (ext_level > 0x80000001)
607 __cpuid (0x80000002, name, ebx, ecx, edx);
608 else
609 name = 0;
610
ef64d158 611 if (name == signature_NSC_ebx)
fbdf817d 612 processor = PROCESSOR_GEODE;
d478ac59 613 else if (has_movbe && family == 22)
e32bfc16 614 processor = PROCESSOR_BTVER2;
9ce29eb0
VK
615 else if (has_clzero)
616 processor = PROCESSOR_ZNVER1;
ed97ad47
GG
617 else if (has_avx2)
618 processor = PROCESSOR_BDVER4;
eb2f2b44
GG
619 else if (has_xsaveopt)
620 processor = PROCESSOR_BDVER3;
4d652a18
HJ
621 else if (has_bmi)
622 processor = PROCESSOR_BDVER2;
1133125e
HJ
623 else if (has_xop)
624 processor = PROCESSOR_BDVER1;
14b52538
CF
625 else if (has_sse4a && has_ssse3)
626 processor = PROCESSOR_BTVER1;
fbdf817d 627 else if (has_sse4a)
35a63f21 628 processor = PROCESSOR_AMDFAM10;
fbdf817d
UB
629 else if (has_sse2 || has_longmode)
630 processor = PROCESSOR_K8;
f7593cb4 631 else if (has_3dnowp && family == 6)
fbdf817d
UB
632 processor = PROCESSOR_ATHLON;
633 else if (has_mmx)
634 processor = PROCESSOR_K6;
635 else
636 processor = PROCESSOR_PENTIUM;
fa959ce4 637 }
19db293a
UB
638 else if (vendor == signature_CENTAUR_ebx)
639 {
4bdf739d
UB
640 processor = PROCESSOR_GENERIC;
641
642 switch (family)
19db293a 643 {
4bdf739d
UB
644 default:
645 /* We have no idea. */
646 break;
647
648 case 5:
649 if (has_3dnow || has_mmx)
650 processor = PROCESSOR_I486;
651 break;
652
653 case 6:
d3606ee3
JM
654 if (has_longmode)
655 processor = PROCESSOR_K8;
656 else if (model > 9)
4bdf739d
UB
657 /* Use the default detection procedure. */
658 ;
659 else if (model == 9)
660 processor = PROCESSOR_PENTIUMPRO;
661 else if (model >= 6)
662 processor = PROCESSOR_I486;
19db293a
UB
663 }
664 }
fa959ce4
MM
665 else
666 {
edccdcb1
L
667 switch (family)
668 {
b3172cab
UB
669 case 4:
670 processor = PROCESSOR_I486;
671 break;
edccdcb1 672 case 5:
b3172cab 673 processor = PROCESSOR_PENTIUM;
edccdcb1
L
674 break;
675 case 6:
676 processor = PROCESSOR_PENTIUMPRO;
677 break;
678 case 15:
679 processor = PROCESSOR_PENTIUM4;
680 break;
681 default:
b3172cab 682 /* We have no idea. */
9d532162 683 processor = PROCESSOR_GENERIC;
edccdcb1
L
684 }
685 }
686
687 switch (processor)
688 {
689 case PROCESSOR_I386:
b3172cab 690 /* Default. */
edccdcb1
L
691 break;
692 case PROCESSOR_I486:
4bdf739d
UB
693 if (arch && vendor == signature_CENTAUR_ebx)
694 {
695 if (model >= 6)
696 cpu = "c3";
697 else if (has_3dnow)
698 cpu = "winchip2";
699 else
700 /* Assume WinChip C6. */
701 cpu = "winchip-c6";
702 }
703 else
704 cpu = "i486";
edccdcb1
L
705 break;
706 case PROCESSOR_PENTIUM:
b3172cab 707 if (arch && has_mmx)
edccdcb1
L
708 cpu = "pentium-mmx";
709 else
710 cpu = "pentium";
711 break;
712 case PROCESSOR_PENTIUMPRO:
44f276c6 713 switch (model)
edccdcb1 714 {
44f276c6
L
715 case 0x1c:
716 case 0x26:
d3c11974
L
717 /* Bonnell. */
718 cpu = "bonnell";
44f276c6 719 break;
e5287671 720 case 0x37:
c8f2dff2 721 case 0x4a:
e5287671 722 case 0x4d:
c8f2dff2
L
723 case 0x5a:
724 case 0x5d:
e5287671 725 /* Silvermont. */
d3c11974 726 cpu = "silvermont";
e5287671 727 break;
992592ec
CW
728 case 0x0f:
729 /* Merom. */
730 case 0x17:
731 case 0x1d:
732 /* Penryn. */
733 cpu = "core2";
734 break;
44f276c6
L
735 case 0x1a:
736 case 0x1e:
737 case 0x1f:
738 case 0x2e:
eefe143b 739 /* Nehalem. */
d3c11974
L
740 cpu = "nehalem";
741 break;
44f276c6 742 case 0x25:
12bbb78f 743 case 0x2c:
44f276c6 744 case 0x2f:
eefe143b 745 /* Westmere. */
d3c11974 746 cpu = "westmere";
44f276c6 747 break;
35758e5b 748 case 0x2a:
815cecbe 749 case 0x2d:
35758e5b 750 /* Sandy Bridge. */
d3c11974 751 cpu = "sandybridge";
35758e5b 752 break;
992592ec
CW
753 case 0x3a:
754 case 0x3e:
755 /* Ivy Bridge. */
d3c11974 756 cpu = "ivybridge";
44f276c6 757 break;
992592ec 758 case 0x3c:
c8f2dff2 759 case 0x3f:
d0cf4e84
L
760 case 0x45:
761 case 0x46:
992592ec 762 /* Haswell. */
d3c11974 763 cpu = "haswell";
44f276c6 764 break;
c8f2dff2 765 case 0x3d:
dc04bc84 766 case 0x47:
c8f2dff2
L
767 case 0x4f:
768 case 0x56:
769 /* Broadwell. */
770 cpu = "broadwell";
771 break;
3e0f3349
YR
772 case 0x4e:
773 case 0x5e:
774 /* Skylake. */
775 cpu = "skylake";
776 break;
c8f2dff2
L
777 case 0x57:
778 /* Knights Landing. */
779 cpu = "knl";
780 break;
44f276c6
L
781 default:
782 if (arch)
783 {
4ffae7ff 784 /* This is unknown family 0x6 CPU. */
52747219
IT
785 /* Assume Knights Landing. */
786 if (has_avx512f)
787 cpu = "knl";
788 /* Assume Broadwell. */
789 else if (has_adx)
19ac6899
TI
790 cpu = "broadwell";
791 else if (has_avx2)
992592ec 792 /* Assume Haswell. */
d3c11974 793 cpu = "haswell";
992592ec 794 else if (has_avx)
4ffae7ff 795 /* Assume Sandy Bridge. */
d3c11974 796 cpu = "sandybridge";
4ffae7ff 797 else if (has_sse4_2)
0b871ccf
YR
798 {
799 if (has_movbe)
d3c11974
L
800 /* Assume Silvermont. */
801 cpu = "silvermont";
0b871ccf 802 else
d3c11974
L
803 /* Assume Nehalem. */
804 cpu = "nehalem";
0b871ccf 805 }
4ffae7ff
L
806 else if (has_ssse3)
807 {
808 if (has_movbe)
d3c11974
L
809 /* Assume Bonnell. */
810 cpu = "bonnell";
4ffae7ff
L
811 else
812 /* Assume Core 2. */
813 cpu = "core2";
814 }
8d37375b
JJ
815 else if (has_longmode)
816 /* Perhaps some emulator? Assume x86-64, otherwise gcc
817 -march=native would be unusable for 64-bit compilations,
818 as all the CPUs below are 32-bit only. */
819 cpu = "x86-64";
fb112177
L
820 else if (has_sse3)
821 /* It is Core Duo. */
822 cpu = "pentium-m";
823 else if (has_sse2)
824 /* It is Pentium M. */
825 cpu = "pentium-m";
826 else if (has_sse)
4bdf739d
UB
827 {
828 if (vendor == signature_CENTAUR_ebx)
829 cpu = "c3-2";
830 else
831 /* It is Pentium III. */
832 cpu = "pentium3";
833 }
fb112177
L
834 else if (has_mmx)
835 /* It is Pentium II. */
836 cpu = "pentium2";
44f276c6 837 else
fb112177
L
838 /* Default to Pentium Pro. */
839 cpu = "pentiumpro";
44f276c6 840 }
b3172cab 841 else
44f276c6
L
842 /* For -mtune, we default to -mtune=generic. */
843 cpu = "generic";
844 break;
fa959ce4 845 }
b3172cab
UB
846 break;
847 case PROCESSOR_PENTIUM4:
848 if (has_sse3)
fa959ce4 849 {
b3172cab
UB
850 if (has_longmode)
851 cpu = "nocona";
fa959ce4 852 else
fb112177 853 cpu = "prescott";
fa959ce4 854 }
b3172cab 855 else
fb112177 856 cpu = "pentium4";
edccdcb1
L
857 break;
858 case PROCESSOR_GEODE:
859 cpu = "geode";
860 break;
861 case PROCESSOR_K6:
b3172cab
UB
862 if (arch && has_3dnow)
863 cpu = "k6-3";
edccdcb1
L
864 else
865 cpu = "k6";
866 break;
867 case PROCESSOR_ATHLON:
b3172cab 868 if (arch && has_sse)
edccdcb1
L
869 cpu = "athlon-4";
870 else
871 cpu = "athlon";
872 break;
edccdcb1 873 case PROCESSOR_K8:
d3606ee3
JM
874 if (arch)
875 {
876 if (vendor == signature_CENTAUR_ebx)
877 {
878 if (has_sse4_1)
879 /* Nano 3000 | Nano dual / quad core | Eden X4 */
880 cpu = "nano-3000";
881 else if (has_ssse3)
882 /* Nano 1000 | Nano 2000 */
883 cpu = "nano";
884 else if (has_sse3)
885 /* Eden X2 */
886 cpu = "eden-x2";
887 else
888 /* Default to k8 */
889 cpu = "k8";
890 }
891 else if (has_sse3)
892 cpu = "k8-sse3";
893 else
894 cpu = "k8";
895 }
b3172cab 896 else
d3606ee3 897 /* For -mtune, we default to -mtune=k8 */
b3172cab 898 cpu = "k8";
edccdcb1 899 break;
35a63f21
DR
900 case PROCESSOR_AMDFAM10:
901 cpu = "amdfam10";
902 break;
1133125e
HJ
903 case PROCESSOR_BDVER1:
904 cpu = "bdver1";
905 break;
4d652a18
HJ
906 case PROCESSOR_BDVER2:
907 cpu = "bdver2";
908 break;
eb2f2b44
GG
909 case PROCESSOR_BDVER3:
910 cpu = "bdver3";
911 break;
ed97ad47
GG
912 case PROCESSOR_BDVER4:
913 cpu = "bdver4";
914 break;
9ce29eb0
VK
915 case PROCESSOR_ZNVER1:
916 cpu = "znver1";
917 break;
14b52538
CF
918 case PROCESSOR_BTVER1:
919 cpu = "btver1";
920 break;
e32bfc16
VK
921 case PROCESSOR_BTVER2:
922 cpu = "btver2";
923 break;
b3172cab 924
edccdcb1 925 default:
b3172cab
UB
926 /* Use something reasonable. */
927 if (arch)
928 {
929 if (has_ssse3)
930 cpu = "core2";
931 else if (has_sse3)
932 {
933 if (has_longmode)
934 cpu = "nocona";
935 else
936 cpu = "prescott";
937 }
4bdf739d
UB
938 else if (has_longmode)
939 /* Perhaps some emulator? Assume x86-64, otherwise gcc
940 -march=native would be unusable for 64-bit compilations,
941 as all the CPUs below are 32-bit only. */
942 cpu = "x86-64";
b3172cab
UB
943 else if (has_sse2)
944 cpu = "pentium4";
945 else if (has_cmov)
946 cpu = "pentiumpro";
947 else if (has_mmx)
948 cpu = "pentium-mmx";
949 else if (has_cmpxchg8b)
950 cpu = "pentium";
951 }
952 else
953 cpu = "generic";
fa959ce4
MM
954 }
955
5be6cb59
UB
956 if (arch)
957 {
11c2aa39
UB
958 const char *mmx = has_mmx ? " -mmmx" : " -mno-mmx";
959 const char *mmx3dnow = has_3dnow ? " -m3dnow" : " -mno-3dnow";
960 const char *sse = has_sse ? " -msse" : " -mno-sse";
961 const char *sse2 = has_sse2 ? " -msse2" : " -mno-sse2";
962 const char *sse3 = has_sse3 ? " -msse3" : " -mno-sse3";
963 const char *ssse3 = has_ssse3 ? " -mssse3" : " -mno-ssse3";
964 const char *sse4a = has_sse4a ? " -msse4a" : " -mno-sse4a";
5eed4f27
L
965 const char *cx16 = has_cmpxchg16b ? " -mcx16" : " -mno-cx16";
966 const char *sahf = has_lahf_lm ? " -msahf" : " -mno-sahf";
967 const char *movbe = has_movbe ? " -mmovbe" : " -mno-movbe";
11c2aa39 968 const char *aes = has_aes ? " -maes" : " -mno-aes";
c1618f82 969 const char *sha = has_sha ? " -msha" : " -mno-sha";
5eed4f27
L
970 const char *pclmul = has_pclmul ? " -mpclmul" : " -mno-pclmul";
971 const char *popcnt = has_popcnt ? " -mpopcnt" : " -mno-popcnt";
972 const char *abm = has_abm ? " -mabm" : " -mno-abm";
973 const char *lwp = has_lwp ? " -mlwp" : " -mno-lwp";
974 const char *fma = has_fma ? " -mfma" : " -mno-fma";
975 const char *fma4 = has_fma4 ? " -mfma4" : " -mno-fma4";
976 const char *xop = has_xop ? " -mxop" : " -mno-xop";
977 const char *bmi = has_bmi ? " -mbmi" : " -mno-bmi";
82feeb8d 978 const char *bmi2 = has_bmi2 ? " -mbmi2" : " -mno-bmi2";
5eed4f27
L
979 const char *tbm = has_tbm ? " -mtbm" : " -mno-tbm";
980 const char *avx = has_avx ? " -mavx" : " -mno-avx";
7afac110 981 const char *avx2 = has_avx2 ? " -mavx2" : " -mno-avx2";
642a011d 982 const char *sse4_2 = has_sse4_2 ? " -msse4.2" : " -mno-sse4.2";
5eed4f27 983 const char *sse4_1 = has_sse4_1 ? " -msse4.1" : " -mno-sse4.1";
3ed2c643 984 const char *lzcnt = has_lzcnt ? " -mlzcnt" : " -mno-lzcnt";
38d7f26e 985 const char *hle = has_hle ? " -mhle" : " -mno-hle";
76a02e42 986 const char *rtm = has_rtm ? " -mrtm" : " -mno-rtm";
d1925759
L
987 const char *rdrnd = has_rdrnd ? " -mrdrnd" : " -mno-rdrnd";
988 const char *f16c = has_f16c ? " -mf16c" : " -mno-f16c";
989 const char *fsgsbase = has_fsgsbase ? " -mfsgsbase" : " -mno-fsgsbase";
4c340b5d 990 const char *rdseed = has_rdseed ? " -mrdseed" : " -mno-rdseed";
e61c94dd 991 const char *prfchw = has_prfchw ? " -mprfchw" : " -mno-prfchw";
d05e383b 992 const char *adx = has_adx ? " -madx" : " -mno-adx";
3a0d99bb
AI
993 const char *fxsr = has_fxsr ? " -mfxsr" : " -mno-fxsr";
994 const char *xsave = has_xsave ? " -mxsave" : " -mno-xsave";
995 const char *xsaveopt = has_xsaveopt ? " -mxsaveopt" : " -mno-xsaveopt";
3f97cb0b
AI
996 const char *avx512f = has_avx512f ? " -mavx512f" : " -mno-avx512f";
997 const char *avx512er = has_avx512er ? " -mavx512er" : " -mno-avx512er";
998 const char *avx512cd = has_avx512cd ? " -mavx512cd" : " -mno-avx512cd";
999 const char *avx512pf = has_avx512pf ? " -mavx512pf" : " -mno-avx512pf";
43b3f52f 1000 const char *prefetchwt1 = has_prefetchwt1 ? " -mprefetchwt1" : " -mno-prefetchwt1";
9cdea277
IT
1001 const char *clflushopt = has_clflushopt ? " -mclflushopt" : " -mno-clflushopt";
1002 const char *xsavec = has_xsavec ? " -mxsavec" : " -mno-xsavec";
1003 const char *xsaves = has_xsaves ? " -mxsaves" : " -mno-xsaves";
07165dd7 1004 const char *avx512dq = has_avx512dq ? " -mavx512dq" : " -mno-avx512dq";
b525d943 1005 const char *avx512bw = has_avx512bw ? " -mavx512bw" : " -mno-avx512bw";
f4af595f 1006 const char *avx512vl = has_avx512vl ? " -mavx512vl" : " -mno-avx512vl";
4190ea38 1007 const char *avx512ifma = has_avx512ifma ? " -mavx512ifma" : " -mno-avx512ifma";
3dcc8af5 1008 const char *avx512vbmi = has_avx512vbmi ? " -mavx512vbmi" : " -mno-avx512vbmi";
9c3bca11 1009 const char *clwb = has_clwb ? " -mclwb" : " -mno-clwb";
36e9b73e 1010 const char *pcommit = has_pcommit ? " -mpcommit" : " -mno-pcommit";
500a08b2 1011 const char *mwaitx = has_mwaitx ? " -mmwaitx" : " -mno-mwaitx";
9ce29eb0 1012 const char *clzero = has_clzero ? " -mclzero" : " -mno-clzero";
41a4ef22 1013 const char *pku = has_pku ? " -mpku" : " -mno-pku";
11c2aa39 1014 options = concat (options, mmx, mmx3dnow, sse, sse2, sse3, ssse3,
c1618f82 1015 sse4a, cx16, sahf, movbe, aes, sha, pclmul,
82feeb8d 1016 popcnt, abm, lwp, fma, fma4, xop, bmi, bmi2,
76a02e42 1017 tbm, avx, avx2, sse4_2, sse4_1, lzcnt, rtm,
3a0d99bb 1018 hle, rdrnd, f16c, fsgsbase, rdseed, prfchw, adx,
3f97cb0b 1019 fxsr, xsave, xsaveopt, avx512f, avx512er,
9cdea277 1020 avx512cd, avx512pf, prefetchwt1, clflushopt,
f4af595f 1021 xsavec, xsaves, avx512dq, avx512bw, avx512vl,
9ce29eb0 1022 avx512ifma, avx512vbmi, clwb, pcommit, mwaitx,
41a4ef22 1023 clzero, pku, NULL);
5be6cb59
UB
1024 }
1025
fa959ce4 1026done:
f3afc8a7 1027 return concat (cache, "-m", argv[0], "=", cpu, options, NULL);
fa959ce4
MM
1028}
1029#else
b3172cab 1030
02147868
UB
1031/* If we are compiling with GCC where %EBX register is fixed, then the
1032 driver will just ignore -march and -mtune "native" target and will leave
1033 to the newly built compiler to generate code for its default target. */
b3172cab 1034
997ef9e7 1035const char *host_detect_local_cpu (int, const char **)
fa959ce4 1036{
f3afc8a7 1037 return NULL;
fa959ce4 1038}
a6ecb05c 1039#endif /* __GNUC__ */