GCC with patches for OS216
Revisión | 6c35d16a3925958b3a22426de0cb8e04f654b6dd (tree) |
---|---|
Tiempo | 2020-06-24 23:57:27 |
Autor | H.J. Lu <hjl.tools@gmai...> |
Commiter | H.J. Lu |
x86: Share _isa_names_table and use cpuinfo.h
Both driver-i386.c and libgcc use CPUID to detect the processor name
as well as available ISAs. To detect the same processor or ISAs, the
same detection logic is duplicated in 2 places. Sometimes only one place
was up to date or got it right. Sometimes both places got it wrong.
1. Add common/config/i386/i386-isas.h to define _isa_names_table.
2. Use isa_names_table to auto-generate ISA command-line options.
3. Use isa_names_table to auto-generate builtin_cpu_supports tests.
4. Use common/config/i386/cpuinfo.h to check available ISAs and detect
newer Intel processors in driver-i386.c and builtin_target.c.
5. Detection of AMD processors and older processors in driver-i386.c is
unchanged.
gcc/
PR target/95843
* common/config/i386/i386-isas.h: New file. Extracted from
gcc/config/i386/i386-builtins.c.
(_isa_names_table): Add option.
(ISA_NAMES_TABLE_START): New.
(ISA_NAMES_TABLE_END): Likewise.
(ISA_NAMES_TABLE_ENTRY): Likewise.
(isa_names_table): Defined with ISA_NAMES_TABLE_START,
ISA_NAMES_TABLE_END and ISA_NAMES_TABLE_ENTRY. Add more ISAs
from enum processor_features.
* config/i386/driver-i386.c: Include
"common/config/i386/cpuinfo.h" and
"common/config/i386/i386-isas.h".
(has_feature): New macro.
(host_detect_local_cpu): Call cpu_indicator_init to get CPU
features. Use has_feature to detect processor features. Call
Call get_intel_cpu to get the newer Intel CPU name. Use
isa_names_table to generate command-line options.
* config/i386/i386-builtins.c: Include
"common/config/i386/i386-isas.h".
(_arch_names_table): Removed.
(isa_names_table): Likewise.
gcc/testsuite/
PR target/95843
* gcc.target/i386/builtin_target.c: Include <stdlib.h>,
../../../common/config/i386/i386-cpuinfo.h and
../../../common/config/i386/cpuinfo.h.
(check_amd_cpu_model): Removed.
(check_intel_cpu_model): Likewise,
(CHECK_builtin_cpu_is): New.
(gcc_assert): New. Defined as assert.
(gcc_unreachable): New. Defined as abort.
(inline): New. Defined as empty.
(ISA_NAMES_TABLE_START): Likewise.
(ISA_NAMES_TABLE_END): Likewise.
(ISA_NAMES_TABLE_ENTRY): New.
(check_features): Include
"../../../common/config/i386/i386-isas.h".
(check_detailed): Call cpu_indicator_init. Always call
check_features. Call get_amd_cpu instead of check_amd_cpu_model.
Call get_intel_cpu instead of check_intel_cpu_model.
@@ -0,0 +1,163 @@ | ||
1 | +/* i386 ISA table. | |
2 | + Copyright (C) 2020 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 | +/* These are the target attribute strings for which a dispatcher is | |
21 | + available, from fold_builtin_cpu. */ | |
22 | +struct _isa_names_table | |
23 | +{ | |
24 | + const char *const name; | |
25 | + const enum processor_features feature; | |
26 | + const enum feature_priority priority; | |
27 | + const char *const option; | |
28 | +}; | |
29 | + | |
30 | +/* NB: isa_names_table is shared by i386-builtins.c, driver-i386.c and | |
31 | + gcc.target/i386/builtin_target.c. isa_names_table is a static const | |
32 | + array in i386-builtins.c and driver-i386.c. But it is a list of | |
33 | + assert statements in gcc.target/i386/builtin_target.c. */ | |
34 | + | |
35 | +#ifndef ISA_NAMES_TABLE_START | |
36 | +# define ISA_NAMES_TABLE_START \ | |
37 | + static const struct _isa_names_table isa_names_table[] = { | |
38 | +#endif | |
39 | + | |
40 | +#ifndef ISA_NAMES_TABLE_END | |
41 | +# define ISA_NAMES_TABLE_END }; | |
42 | +#endif | |
43 | + | |
44 | +#ifndef ISA_NAMES_TABLE_ENTRY | |
45 | +# define ISA_NAMES_TABLE_ENTRY(name, feature, priority, option) \ | |
46 | + {name, feature, priority, option}, | |
47 | +#endif | |
48 | + | |
49 | +ISA_NAMES_TABLE_START | |
50 | + ISA_NAMES_TABLE_ENTRY("cmov", FEATURE_CMOV, P_NONE, NULL) | |
51 | + ISA_NAMES_TABLE_ENTRY("mmx", FEATURE_MMX, P_MMX, "-mmmx") | |
52 | + ISA_NAMES_TABLE_ENTRY("popcnt", FEATURE_POPCNT, P_POPCNT, "-mpopcnt") | |
53 | + ISA_NAMES_TABLE_ENTRY("sse", FEATURE_SSE, P_SSE, "-msse") | |
54 | + ISA_NAMES_TABLE_ENTRY("sse2", FEATURE_SSE2, P_SSE2, "-msse2") | |
55 | + ISA_NAMES_TABLE_ENTRY("sse3", FEATURE_SSE3, P_SSE3, "-msse3") | |
56 | + ISA_NAMES_TABLE_ENTRY("ssse3", FEATURE_SSSE3, P_SSSE3, "-mssse3") | |
57 | + ISA_NAMES_TABLE_ENTRY("sse4.1", FEATURE_SSE4_1, P_SSE4_1, "-msse4.1") | |
58 | + ISA_NAMES_TABLE_ENTRY("sse4.2", FEATURE_SSE4_2, P_SSE4_2, "-msse4.2") | |
59 | + ISA_NAMES_TABLE_ENTRY("avx", FEATURE_AVX, P_AVX, "-mavx") | |
60 | + ISA_NAMES_TABLE_ENTRY("avx2", FEATURE_AVX2, P_AVX2, "-mavx2") | |
61 | + ISA_NAMES_TABLE_ENTRY("sse4a", FEATURE_SSE4_A, P_SSE4_A, "-msse4a") | |
62 | + ISA_NAMES_TABLE_ENTRY("fma4", FEATURE_FMA4, P_FMA4, "-mfma4") | |
63 | + ISA_NAMES_TABLE_ENTRY("xop", FEATURE_XOP, P_XOP, "-mxop") | |
64 | + ISA_NAMES_TABLE_ENTRY("fma", FEATURE_FMA, P_FMA, "-mfma") | |
65 | + ISA_NAMES_TABLE_ENTRY("avx512f", FEATURE_AVX512F, P_AVX512F, | |
66 | + "-mavx512f") | |
67 | + ISA_NAMES_TABLE_ENTRY("bmi", FEATURE_BMI, P_BMI, "-mbmi") | |
68 | + ISA_NAMES_TABLE_ENTRY("bmi2", FEATURE_BMI2, P_BMI2, "-mbmi2") | |
69 | + ISA_NAMES_TABLE_ENTRY("aes", FEATURE_AES, P_AES, "-maes") | |
70 | + ISA_NAMES_TABLE_ENTRY("pclmul", FEATURE_PCLMUL, P_PCLMUL, "-mpclmul") | |
71 | + ISA_NAMES_TABLE_ENTRY("avx512vl", FEATURE_AVX512VL, P_NONE, | |
72 | + "-mavx512vl") | |
73 | + ISA_NAMES_TABLE_ENTRY("avx512bw", FEATURE_AVX512BW, P_NONE, | |
74 | + "-mavx512bw") | |
75 | + ISA_NAMES_TABLE_ENTRY("avx512dq", FEATURE_AVX512DQ, P_NONE, | |
76 | + "-mavx512dq") | |
77 | + ISA_NAMES_TABLE_ENTRY("avx512cd", FEATURE_AVX512CD, P_NONE, | |
78 | + "-mavx512cd") | |
79 | + ISA_NAMES_TABLE_ENTRY("avx512er", FEATURE_AVX512ER, P_NONE, | |
80 | + "-mavx512er") | |
81 | + ISA_NAMES_TABLE_ENTRY("avx512pf", FEATURE_AVX512PF, P_NONE, | |
82 | + "-mavx512pf") | |
83 | + ISA_NAMES_TABLE_ENTRY("avx512vbmi", FEATURE_AVX512VBMI, P_NONE, | |
84 | + "-mavx512vbmi") | |
85 | + ISA_NAMES_TABLE_ENTRY("avx512ifma", FEATURE_AVX512IFMA, P_NONE, | |
86 | + "-mavx512ifma") | |
87 | + ISA_NAMES_TABLE_ENTRY("avx5124vnniw", FEATURE_AVX5124VNNIW, P_NONE, | |
88 | + "-mavx5124vnniw") | |
89 | + ISA_NAMES_TABLE_ENTRY("avx5124fmaps", FEATURE_AVX5124FMAPS, P_NONE, | |
90 | + "-mavx5124fmaps") | |
91 | + ISA_NAMES_TABLE_ENTRY("avx512vpopcntdq", FEATURE_AVX512VPOPCNTDQ, | |
92 | + P_NONE, "-mavx512vpopcntdq") | |
93 | + ISA_NAMES_TABLE_ENTRY("avx512vbmi2", FEATURE_AVX512VBMI2, P_NONE, | |
94 | + "-mavx512vbmi2") | |
95 | + ISA_NAMES_TABLE_ENTRY("gfni", FEATURE_GFNI, P_NONE, "-mgfni") | |
96 | + ISA_NAMES_TABLE_ENTRY("vpclmulqdq", FEATURE_VPCLMULQDQ, P_NONE, | |
97 | + "-mvpclmulqdq") | |
98 | + ISA_NAMES_TABLE_ENTRY("avx512vnni", FEATURE_AVX512VNNI, P_NONE, | |
99 | + "-mavx512vnni") | |
100 | + ISA_NAMES_TABLE_ENTRY("avx512bitalg", FEATURE_AVX512BITALG, P_NONE, | |
101 | + "-mavx512bitalg") | |
102 | + ISA_NAMES_TABLE_ENTRY("avx512bf16", FEATURE_AVX512BF16, P_NONE, | |
103 | + "-mavx512bf16") | |
104 | + ISA_NAMES_TABLE_ENTRY("avx512vp2intersect", FEATURE_AVX512VP2INTERSECT, | |
105 | + P_NONE, "-mavx512vp2intersect") | |
106 | + ISA_NAMES_TABLE_ENTRY("3dnow", FEATURE_3DNOW, P_NONE, "-m3dnow") | |
107 | + ISA_NAMES_TABLE_ENTRY("3dnowp", FEATURE_3DNOWP, P_NONE, NULL) | |
108 | + ISA_NAMES_TABLE_ENTRY("adx", FEATURE_ADX, P_NONE, "-madx") | |
109 | + ISA_NAMES_TABLE_ENTRY("abm", FEATURE_ABM, P_NONE, "-mabm") | |
110 | + ISA_NAMES_TABLE_ENTRY("cldemote", FEATURE_CLDEMOTE, P_NONE, | |
111 | + "-mcldemote") | |
112 | + ISA_NAMES_TABLE_ENTRY("clflushopt", FEATURE_CLFLUSHOPT, P_NONE, | |
113 | + "-mclflushopt") | |
114 | + ISA_NAMES_TABLE_ENTRY("clwb", FEATURE_CLWB, P_NONE, "-mclwb") | |
115 | + ISA_NAMES_TABLE_ENTRY("clzero", FEATURE_CLZERO, P_NONE, "-mclzero") | |
116 | + ISA_NAMES_TABLE_ENTRY("cmpxchg16b", FEATURE_CMPXCHG16B, P_NONE, | |
117 | + "-mcx16") | |
118 | + ISA_NAMES_TABLE_ENTRY("cmpxchg8b", FEATURE_CMPXCHG8B, P_NONE, NULL) | |
119 | + ISA_NAMES_TABLE_ENTRY("enqcmd", FEATURE_ENQCMD, P_NONE, "-menqcmd") | |
120 | + ISA_NAMES_TABLE_ENTRY("f16c", FEATURE_F16C, P_NONE, "-mf16c") | |
121 | + ISA_NAMES_TABLE_ENTRY("fsgsbase", FEATURE_FSGSBASE, P_NONE, | |
122 | + "-mfsgsbase") | |
123 | + ISA_NAMES_TABLE_ENTRY("fxsave", FEATURE_FXSAVE, P_NONE, "-mfxsr") | |
124 | + ISA_NAMES_TABLE_ENTRY("hle", FEATURE_HLE, P_NONE, "-mhle") | |
125 | + ISA_NAMES_TABLE_ENTRY("ibt", FEATURE_IBT, P_NONE, NULL) | |
126 | + ISA_NAMES_TABLE_ENTRY("lahf_lm", FEATURE_LAHF_LM, P_NONE, "-msahf") | |
127 | + ISA_NAMES_TABLE_ENTRY("lm", FEATURE_LM, P_NONE, NULL) | |
128 | + ISA_NAMES_TABLE_ENTRY("lwp", FEATURE_LWP, P_NONE, "-mlwp") | |
129 | + ISA_NAMES_TABLE_ENTRY("lzcnt", FEATURE_LZCNT, P_NONE, "-mlzcnt") | |
130 | + ISA_NAMES_TABLE_ENTRY("movbe", FEATURE_MOVBE, P_NONE, "-mmovbe") | |
131 | + ISA_NAMES_TABLE_ENTRY("movdir64b", FEATURE_MOVDIR64B, P_NONE, | |
132 | + "-mmovdir64b") | |
133 | + ISA_NAMES_TABLE_ENTRY("movdiri", FEATURE_MOVDIRI, P_NONE, "-mmovdiri") | |
134 | + ISA_NAMES_TABLE_ENTRY("mwaitx", FEATURE_MWAITX, P_NONE, "-mmwaitx") | |
135 | + ISA_NAMES_TABLE_ENTRY("osxsave", FEATURE_OSXSAVE, P_NONE, NULL) | |
136 | + ISA_NAMES_TABLE_ENTRY("pconfig", FEATURE_PCONFIG, P_NONE, "-mpconfig") | |
137 | + ISA_NAMES_TABLE_ENTRY("pku", FEATURE_PKU, P_NONE, "-mpku") | |
138 | + ISA_NAMES_TABLE_ENTRY("prefetchwt1", FEATURE_PREFETCHWT1, P_NONE, | |
139 | + "-mprefetchwt1") | |
140 | + ISA_NAMES_TABLE_ENTRY("prfchw", FEATURE_PRFCHW, P_NONE, "-mprfchw") | |
141 | + ISA_NAMES_TABLE_ENTRY("ptwrite", FEATURE_PTWRITE, P_NONE, "-mptwrite") | |
142 | + ISA_NAMES_TABLE_ENTRY("rdpid", FEATURE_RDPID, P_NONE, "-mrdpid") | |
143 | + ISA_NAMES_TABLE_ENTRY("rdrnd", FEATURE_RDRND, P_NONE, "-mrdrnd") | |
144 | + ISA_NAMES_TABLE_ENTRY("rdseed", FEATURE_RDSEED, P_NONE, "-mrdseed") | |
145 | + ISA_NAMES_TABLE_ENTRY("rtm", FEATURE_RTM, P_NONE, "-mrtm") | |
146 | + ISA_NAMES_TABLE_ENTRY("serialize", FEATURE_SERIALIZE, P_NONE, | |
147 | + "-mserialize") | |
148 | + ISA_NAMES_TABLE_ENTRY("sgx", FEATURE_SGX, P_NONE, "-msgx") | |
149 | + ISA_NAMES_TABLE_ENTRY("sha", FEATURE_SHA, P_NONE, "-msha") | |
150 | + ISA_NAMES_TABLE_ENTRY("shstk", FEATURE_SHSTK, P_NONE, "-mshstk") | |
151 | + ISA_NAMES_TABLE_ENTRY("tbm", FEATURE_TBM, P_NONE, "-mtbm") | |
152 | + ISA_NAMES_TABLE_ENTRY("tsxldtrk", FEATURE_TSXLDTRK, P_NONE, | |
153 | + "-mtsxldtrk") | |
154 | + ISA_NAMES_TABLE_ENTRY("vaes", FEATURE_VAES, P_NONE, "-mvaes") | |
155 | + ISA_NAMES_TABLE_ENTRY("waitpkg", FEATURE_WAITPKG, P_NONE, "-mwaitpkg") | |
156 | + ISA_NAMES_TABLE_ENTRY("wbnoinvd", FEATURE_WBNOINVD, P_NONE, | |
157 | + "-mwbnoinvd") | |
158 | + ISA_NAMES_TABLE_ENTRY("xsave", FEATURE_XSAVE, P_NONE, "-mxsave") | |
159 | + ISA_NAMES_TABLE_ENTRY("xsavec", FEATURE_XSAVEC, P_NONE, "-mxsavec") | |
160 | + ISA_NAMES_TABLE_ENTRY("xsaveopt", FEATURE_XSAVEOPT, P_NONE, | |
161 | + "-mxsaveopt") | |
162 | + ISA_NAMES_TABLE_ENTRY("xsaves", FEATURE_XSAVES, P_NONE, "-mxsaves") | |
163 | +ISA_NAMES_TABLE_END |
@@ -28,6 +28,8 @@ const char *host_detect_local_cpu (int argc, const char **argv); | ||
28 | 28 | |
29 | 29 | #if defined(__GNUC__) && (__GNUC__ >= 5 || !defined(__PIC__)) |
30 | 30 | #include "cpuid.h" |
31 | +#include "common/config/i386/cpuinfo.h" | |
32 | +#include "common/config/i386/i386-isas.h" | |
31 | 33 | |
32 | 34 | struct cache_desc |
33 | 35 | { |
@@ -388,53 +390,13 @@ const char *host_detect_local_cpu (int argc, const char **argv) | ||
388 | 390 | const char *cache = ""; |
389 | 391 | const char *options = ""; |
390 | 392 | |
391 | - unsigned int eax, ebx, ecx, edx; | |
393 | + unsigned int ebx, ecx, edx; | |
392 | 394 | |
393 | 395 | unsigned int max_level, ext_level; |
394 | 396 | |
395 | 397 | unsigned int vendor; |
396 | 398 | unsigned int model, family; |
397 | 399 | |
398 | - unsigned int has_sse3, has_ssse3, has_cmpxchg16b; | |
399 | - unsigned int has_cmpxchg8b, has_cmov, has_mmx, has_sse, has_sse2; | |
400 | - | |
401 | - /* Extended features */ | |
402 | - unsigned int has_lahf_lm = 0, has_sse4a = 0; | |
403 | - unsigned int has_longmode = 0, has_3dnowp = 0, has_3dnow = 0; | |
404 | - unsigned int has_movbe = 0, has_sse4_1 = 0, has_sse4_2 = 0; | |
405 | - unsigned int has_popcnt = 0, has_aes = 0, has_avx = 0, has_avx2 = 0; | |
406 | - unsigned int has_pclmul = 0, has_abm = 0, has_lwp = 0; | |
407 | - unsigned int has_fma = 0, has_fma4 = 0, has_xop = 0; | |
408 | - unsigned int has_bmi = 0, has_bmi2 = 0, has_tbm = 0, has_lzcnt = 0; | |
409 | - unsigned int has_hle = 0, has_rtm = 0, has_sgx = 0; | |
410 | - unsigned int has_pconfig = 0, has_wbnoinvd = 0; | |
411 | - unsigned int has_rdrnd = 0, has_f16c = 0, has_fsgsbase = 0; | |
412 | - unsigned int has_rdseed = 0, has_prfchw = 0, has_adx = 0; | |
413 | - unsigned int has_osxsave = 0, has_fxsr = 0, has_xsave = 0, has_xsaveopt = 0; | |
414 | - unsigned int has_avx512er = 0, has_avx512pf = 0, has_avx512cd = 0; | |
415 | - unsigned int has_avx512f = 0, has_sha = 0, has_prefetchwt1 = 0; | |
416 | - unsigned int has_clflushopt = 0, has_xsavec = 0, has_xsaves = 0; | |
417 | - unsigned int has_avx512dq = 0, has_avx512bw = 0, has_avx512vl = 0; | |
418 | - unsigned int has_avx512vbmi = 0, has_avx512ifma = 0, has_clwb = 0; | |
419 | - unsigned int has_mwaitx = 0, has_clzero = 0, has_pku = 0, has_rdpid = 0; | |
420 | - unsigned int has_avx5124fmaps = 0, has_avx5124vnniw = 0; | |
421 | - unsigned int has_gfni = 0, has_avx512vbmi2 = 0; | |
422 | - unsigned int has_avx512bitalg = 0; | |
423 | - unsigned int has_avx512vpopcntdq = 0; | |
424 | - unsigned int has_shstk = 0; | |
425 | - unsigned int has_avx512vnni = 0, has_vaes = 0; | |
426 | - unsigned int has_vpclmulqdq = 0; | |
427 | - unsigned int has_avx512vp2intersect = 0; | |
428 | - unsigned int has_movdiri = 0, has_movdir64b = 0; | |
429 | - unsigned int has_enqcmd = 0; | |
430 | - unsigned int has_waitpkg = 0; | |
431 | - unsigned int has_cldemote = 0; | |
432 | - unsigned int has_avx512bf16 = 0; | |
433 | - unsigned int has_serialize = 0; | |
434 | - unsigned int has_tsxldtrk = 0; | |
435 | - | |
436 | - unsigned int has_ptwrite = 0; | |
437 | - | |
438 | 400 | bool arch; |
439 | 401 | |
440 | 402 | unsigned int l2sizekb = 0; |
@@ -447,210 +409,27 @@ const char *host_detect_local_cpu (int argc, const char **argv) | ||
447 | 409 | if (!arch && strcmp (argv[0], "tune")) |
448 | 410 | return NULL; |
449 | 411 | |
450 | - max_level = __get_cpuid_max (0, &vendor); | |
451 | - if (max_level < 1) | |
452 | - goto done; | |
453 | - | |
454 | - __cpuid (1, eax, ebx, ecx, edx); | |
412 | + struct __processor_model cpu_model = { }; | |
413 | + struct __processor_model2 cpu_model2 = { }; | |
414 | + unsigned int cpu_features2[SIZE_OF_CPU_FEATURES] = { }; | |
455 | 415 | |
456 | - model = (eax >> 4) & 0x0f; | |
457 | - family = (eax >> 8) & 0x0f; | |
458 | - if (vendor == signature_INTEL_ebx | |
459 | - || vendor == signature_AMD_ebx) | |
460 | - { | |
461 | - unsigned int extended_model, extended_family; | |
462 | - | |
463 | - extended_model = (eax >> 12) & 0xf0; | |
464 | - extended_family = (eax >> 20) & 0xff; | |
465 | - if (family == 0x0f) | |
466 | - { | |
467 | - family += extended_family; | |
468 | - model += extended_model; | |
469 | - } | |
470 | - else if (family == 0x06) | |
471 | - model += extended_model; | |
472 | - } | |
473 | - | |
474 | - has_sse3 = ecx & bit_SSE3; | |
475 | - has_ssse3 = ecx & bit_SSSE3; | |
476 | - has_sse4_1 = ecx & bit_SSE4_1; | |
477 | - has_sse4_2 = ecx & bit_SSE4_2; | |
478 | - has_avx = ecx & bit_AVX; | |
479 | - has_osxsave = ecx & bit_OSXSAVE; | |
480 | - has_cmpxchg16b = ecx & bit_CMPXCHG16B; | |
481 | - has_movbe = ecx & bit_MOVBE; | |
482 | - has_popcnt = ecx & bit_POPCNT; | |
483 | - has_aes = ecx & bit_AES; | |
484 | - has_pclmul = ecx & bit_PCLMUL; | |
485 | - has_fma = ecx & bit_FMA; | |
486 | - has_f16c = ecx & bit_F16C; | |
487 | - has_rdrnd = ecx & bit_RDRND; | |
488 | - has_xsave = ecx & bit_XSAVE; | |
489 | - | |
490 | - has_cmpxchg8b = edx & bit_CMPXCHG8B; | |
491 | - has_cmov = edx & bit_CMOV; | |
492 | - has_mmx = edx & bit_MMX; | |
493 | - has_fxsr = edx & bit_FXSAVE; | |
494 | - has_sse = edx & bit_SSE; | |
495 | - has_sse2 = edx & bit_SSE2; | |
496 | - | |
497 | - if (max_level >= 7) | |
498 | - { | |
499 | - __cpuid_count (7, 0, eax, ebx, ecx, edx); | |
500 | - | |
501 | - has_bmi = ebx & bit_BMI; | |
502 | - has_sgx = ebx & bit_SGX; | |
503 | - has_hle = ebx & bit_HLE; | |
504 | - has_rtm = ebx & bit_RTM; | |
505 | - has_avx2 = ebx & bit_AVX2; | |
506 | - has_bmi2 = ebx & bit_BMI2; | |
507 | - has_fsgsbase = ebx & bit_FSGSBASE; | |
508 | - has_rdseed = ebx & bit_RDSEED; | |
509 | - has_adx = ebx & bit_ADX; | |
510 | - has_avx512f = ebx & bit_AVX512F; | |
511 | - has_avx512er = ebx & bit_AVX512ER; | |
512 | - has_avx512pf = ebx & bit_AVX512PF; | |
513 | - has_avx512cd = ebx & bit_AVX512CD; | |
514 | - has_sha = ebx & bit_SHA; | |
515 | - has_clflushopt = ebx & bit_CLFLUSHOPT; | |
516 | - has_clwb = ebx & bit_CLWB; | |
517 | - has_avx512dq = ebx & bit_AVX512DQ; | |
518 | - has_avx512bw = ebx & bit_AVX512BW; | |
519 | - has_avx512vl = ebx & bit_AVX512VL; | |
520 | - has_avx512ifma = ebx & bit_AVX512IFMA; | |
521 | - | |
522 | - has_prefetchwt1 = ecx & bit_PREFETCHWT1; | |
523 | - has_avx512vbmi = ecx & bit_AVX512VBMI; | |
524 | - has_pku = ecx & bit_OSPKE; | |
525 | - has_avx512vbmi2 = ecx & bit_AVX512VBMI2; | |
526 | - has_avx512vnni = ecx & bit_AVX512VNNI; | |
527 | - has_rdpid = ecx & bit_RDPID; | |
528 | - has_gfni = ecx & bit_GFNI; | |
529 | - has_vaes = ecx & bit_VAES; | |
530 | - has_vpclmulqdq = ecx & bit_VPCLMULQDQ; | |
531 | - has_avx512bitalg = ecx & bit_AVX512BITALG; | |
532 | - has_avx512vpopcntdq = ecx & bit_AVX512VPOPCNTDQ; | |
533 | - has_movdiri = ecx & bit_MOVDIRI; | |
534 | - has_movdir64b = ecx & bit_MOVDIR64B; | |
535 | - has_enqcmd = ecx & bit_ENQCMD; | |
536 | - has_cldemote = ecx & bit_CLDEMOTE; | |
537 | - | |
538 | - has_avx5124vnniw = edx & bit_AVX5124VNNIW; | |
539 | - has_avx5124fmaps = edx & bit_AVX5124FMAPS; | |
540 | - has_avx512vp2intersect = edx & bit_AVX512VP2INTERSECT; | |
541 | - has_serialize = edx & bit_SERIALIZE; | |
542 | - has_tsxldtrk = edx & bit_TSXLDTRK; | |
543 | - | |
544 | - has_shstk = ecx & bit_SHSTK; | |
545 | - has_pconfig = edx & bit_PCONFIG; | |
546 | - has_waitpkg = ecx & bit_WAITPKG; | |
547 | - | |
548 | - __cpuid_count (7, 1, eax, ebx, ecx, edx); | |
549 | - has_avx512bf16 = eax & bit_AVX512BF16; | |
550 | - } | |
551 | - | |
552 | - if (max_level >= 13) | |
553 | - { | |
554 | - __cpuid_count (13, 1, eax, ebx, ecx, edx); | |
555 | - | |
556 | - has_xsaveopt = eax & bit_XSAVEOPT; | |
557 | - has_xsavec = eax & bit_XSAVEC; | |
558 | - has_xsaves = eax & bit_XSAVES; | |
559 | - } | |
560 | - | |
561 | - if (max_level >= 0x14) | |
562 | - { | |
563 | - __cpuid_count (0x14, 0, eax, ebx, ecx, edx); | |
564 | - | |
565 | - has_ptwrite = ebx & bit_PTWRITE; | |
566 | - } | |
567 | - | |
568 | - /* Check cpuid level of extended features. */ | |
569 | - __cpuid (0x80000000, ext_level, ebx, ecx, edx); | |
570 | - | |
571 | - if (ext_level >= 0x80000001) | |
572 | - { | |
573 | - __cpuid (0x80000001, eax, ebx, ecx, edx); | |
574 | - | |
575 | - has_lahf_lm = ecx & bit_LAHF_LM; | |
576 | - has_sse4a = ecx & bit_SSE4a; | |
577 | - has_abm = ecx & bit_ABM; | |
578 | - has_lwp = ecx & bit_LWP; | |
579 | - has_fma4 = ecx & bit_FMA4; | |
580 | - has_xop = ecx & bit_XOP; | |
581 | - has_tbm = ecx & bit_TBM; | |
582 | - has_lzcnt = ecx & bit_LZCNT; | |
583 | - has_prfchw = ecx & bit_PRFCHW; | |
584 | - | |
585 | - has_longmode = edx & bit_LM; | |
586 | - has_3dnowp = edx & bit_3DNOWP; | |
587 | - has_3dnow = edx & bit_3DNOW; | |
588 | - has_mwaitx = ecx & bit_MWAITX; | |
589 | - } | |
590 | - | |
591 | - if (ext_level >= 0x80000008) | |
592 | - { | |
593 | - __cpuid (0x80000008, eax, ebx, ecx, edx); | |
594 | - has_clzero = ebx & bit_CLZERO; | |
595 | - has_wbnoinvd = ebx & bit_WBNOINVD; | |
596 | - } | |
597 | - | |
598 | - /* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv. */ | |
599 | -#define XCR_XFEATURE_ENABLED_MASK 0x0 | |
600 | -#define XSTATE_FP 0x1 | |
601 | -#define XSTATE_SSE 0x2 | |
602 | -#define XSTATE_YMM 0x4 | |
603 | -#define XSTATE_OPMASK 0x20 | |
604 | -#define XSTATE_ZMM 0x40 | |
605 | -#define XSTATE_HI_ZMM 0x80 | |
606 | - | |
607 | -#define XCR_AVX_ENABLED_MASK \ | |
608 | - (XSTATE_SSE | XSTATE_YMM) | |
609 | -#define XCR_AVX512F_ENABLED_MASK \ | |
610 | - (XSTATE_SSE | XSTATE_YMM | XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM) | |
611 | - | |
612 | - if (has_osxsave) | |
613 | - asm (".byte 0x0f; .byte 0x01; .byte 0xd0" | |
614 | - : "=a" (eax), "=d" (edx) | |
615 | - : "c" (XCR_XFEATURE_ENABLED_MASK)); | |
616 | - else | |
617 | - eax = 0; | |
618 | - | |
619 | - /* Check if AVX registers are supported. */ | |
620 | - if ((eax & XCR_AVX_ENABLED_MASK) != XCR_AVX_ENABLED_MASK) | |
621 | - { | |
622 | - has_avx = 0; | |
623 | - has_avx2 = 0; | |
624 | - has_fma = 0; | |
625 | - has_fma4 = 0; | |
626 | - has_f16c = 0; | |
627 | - has_xop = 0; | |
628 | - has_xsave = 0; | |
629 | - has_xsaveopt = 0; | |
630 | - has_xsaves = 0; | |
631 | - has_xsavec = 0; | |
632 | - } | |
416 | + if (cpu_indicator_init (&cpu_model, &cpu_model2, cpu_features2) != 0) | |
417 | + goto done; | |
633 | 418 | |
634 | - /* Check if AVX512F registers are supported. */ | |
635 | - if ((eax & XCR_AVX512F_ENABLED_MASK) != XCR_AVX512F_ENABLED_MASK) | |
636 | - { | |
637 | - has_avx512f = 0; | |
638 | - has_avx512er = 0; | |
639 | - has_avx512pf = 0; | |
640 | - has_avx512cd = 0; | |
641 | - has_avx512dq = 0; | |
642 | - has_avx512bw = 0; | |
643 | - has_avx512vl = 0; | |
644 | - } | |
419 | + vendor = cpu_model.__cpu_vendor; | |
420 | + family = cpu_model2.__cpu_family; | |
421 | + model = cpu_model2.__cpu_model; | |
422 | + max_level = cpu_model2.__cpu_max_level; | |
423 | + ext_level = cpu_model2.__cpu_ext_level; | |
645 | 424 | |
646 | 425 | if (!arch) |
647 | 426 | { |
648 | - if (vendor == signature_AMD_ebx | |
649 | - || vendor == signature_CENTAUR_ebx | |
650 | - || vendor == signature_CYRIX_ebx | |
651 | - || vendor == signature_NSC_ebx) | |
427 | + if (vendor == VENDOR_AMD | |
428 | + || vendor == VENDOR_CENTAUR | |
429 | + || vendor == VENDOR_CYRIX | |
430 | + || vendor == VENDOR_NSC) | |
652 | 431 | cache = detect_caches_amd (ext_level); |
653 | - else if (vendor == signature_INTEL_ebx) | |
432 | + else if (vendor == VENDOR_INTEL) | |
654 | 433 | { |
655 | 434 | bool xeon_mp = (family == 15 && model == 6); |
656 | 435 | cache = detect_caches_intel (xeon_mp, max_level, |
@@ -658,7 +437,11 @@ const char *host_detect_local_cpu (int argc, const char **argv) | ||
658 | 437 | } |
659 | 438 | } |
660 | 439 | |
661 | - if (vendor == signature_AMD_ebx) | |
440 | + /* Extended features */ | |
441 | +#define has_feature(f) \ | |
442 | + has_cpu_feature (&cpu_model, cpu_features2, f) | |
443 | + | |
444 | + if (vendor == VENDOR_AMD) | |
662 | 445 | { |
663 | 446 | unsigned int name; |
664 | 447 |
@@ -670,34 +453,36 @@ const char *host_detect_local_cpu (int argc, const char **argv) | ||
670 | 453 | |
671 | 454 | if (name == signature_NSC_ebx) |
672 | 455 | processor = PROCESSOR_GEODE; |
673 | - else if (has_movbe && family == 22) | |
456 | + else if (has_feature (FEATURE_MOVBE) && family == 22) | |
674 | 457 | processor = PROCESSOR_BTVER2; |
675 | - else if (has_clwb) | |
458 | + else if (has_feature (FEATURE_CLWB)) | |
676 | 459 | processor = PROCESSOR_ZNVER2; |
677 | - else if (has_clzero) | |
460 | + else if (has_feature (FEATURE_CLZERO)) | |
678 | 461 | processor = PROCESSOR_ZNVER1; |
679 | - else if (has_avx2) | |
680 | - processor = PROCESSOR_BDVER4; | |
681 | - else if (has_xsaveopt) | |
682 | - processor = PROCESSOR_BDVER3; | |
683 | - else if (has_bmi) | |
684 | - processor = PROCESSOR_BDVER2; | |
685 | - else if (has_xop) | |
462 | + else if (has_feature (FEATURE_AVX2)) | |
463 | + processor = PROCESSOR_BDVER4; | |
464 | + else if (has_feature (FEATURE_XSAVEOPT)) | |
465 | + processor = PROCESSOR_BDVER3; | |
466 | + else if (has_feature (FEATURE_BMI)) | |
467 | + processor = PROCESSOR_BDVER2; | |
468 | + else if (has_feature (FEATURE_XOP)) | |
686 | 469 | processor = PROCESSOR_BDVER1; |
687 | - else if (has_sse4a && has_ssse3) | |
688 | - processor = PROCESSOR_BTVER1; | |
689 | - else if (has_sse4a) | |
470 | + else if (has_feature (FEATURE_SSE4_A) | |
471 | + && has_feature (FEATURE_SSSE3)) | |
472 | + processor = PROCESSOR_BTVER1; | |
473 | + else if (has_feature (FEATURE_SSE4_A)) | |
690 | 474 | processor = PROCESSOR_AMDFAM10; |
691 | - else if (has_sse2 || has_longmode) | |
475 | + else if (has_feature (FEATURE_SSE2) | |
476 | + || has_feature (FEATURE_LM)) | |
692 | 477 | processor = PROCESSOR_K8; |
693 | - else if (has_3dnowp && family == 6) | |
478 | + else if (has_feature (FEATURE_3DNOWP) && family == 6) | |
694 | 479 | processor = PROCESSOR_ATHLON; |
695 | - else if (has_mmx) | |
480 | + else if (has_feature (FEATURE_MMX)) | |
696 | 481 | processor = PROCESSOR_K6; |
697 | 482 | else |
698 | 483 | processor = PROCESSOR_PENTIUM; |
699 | 484 | } |
700 | - else if (vendor == signature_CENTAUR_ebx) | |
485 | + else if (vendor == VENDOR_CENTAUR) | |
701 | 486 | { |
702 | 487 | processor = PROCESSOR_GENERIC; |
703 | 488 |
@@ -708,12 +493,13 @@ const char *host_detect_local_cpu (int argc, const char **argv) | ||
708 | 493 | break; |
709 | 494 | |
710 | 495 | case 5: |
711 | - if (has_3dnow || has_mmx) | |
496 | + if (has_feature (FEATURE_3DNOW) | |
497 | + || has_feature (FEATURE_MMX)) | |
712 | 498 | processor = PROCESSOR_I486; |
713 | 499 | break; |
714 | 500 | |
715 | 501 | case 6: |
716 | - if (has_longmode) | |
502 | + if (has_feature (FEATURE_LM)) | |
717 | 503 | processor = PROCESSOR_K8; |
718 | 504 | else if (model >= 9) |
719 | 505 | processor = PROCESSOR_PENTIUMPRO; |
@@ -749,11 +535,11 @@ const char *host_detect_local_cpu (int argc, const char **argv) | ||
749 | 535 | /* Default. */ |
750 | 536 | break; |
751 | 537 | case PROCESSOR_I486: |
752 | - if (arch && vendor == signature_CENTAUR_ebx) | |
538 | + if (arch && vendor == VENDOR_CENTAUR) | |
753 | 539 | { |
754 | 540 | if (model >= 6) |
755 | 541 | cpu = "c3"; |
756 | - else if (has_3dnow) | |
542 | + else if (has_feature (FEATURE_3DNOW)) | |
757 | 543 | cpu = "winchip2"; |
758 | 544 | else |
759 | 545 | /* Assume WinChip C6. */ |
@@ -763,226 +549,104 @@ const char *host_detect_local_cpu (int argc, const char **argv) | ||
763 | 549 | cpu = "i486"; |
764 | 550 | break; |
765 | 551 | case PROCESSOR_PENTIUM: |
766 | - if (arch && has_mmx) | |
552 | + if (arch && has_feature (FEATURE_MMX)) | |
767 | 553 | cpu = "pentium-mmx"; |
768 | 554 | else |
769 | 555 | cpu = "pentium"; |
770 | 556 | break; |
771 | 557 | case PROCESSOR_PENTIUMPRO: |
772 | - switch (model) | |
558 | + cpu = get_intel_cpu (&cpu_model, &cpu_model2, cpu_features2, 0); | |
559 | + if (cpu == NULL) | |
773 | 560 | { |
774 | - case 0x1c: | |
775 | - case 0x26: | |
776 | - /* Bonnell. */ | |
777 | - cpu = "bonnell"; | |
778 | - break; | |
779 | - case 0x37: | |
780 | - case 0x4a: | |
781 | - case 0x4d: | |
782 | - case 0x5d: | |
783 | - /* Silvermont. */ | |
784 | - case 0x4c: | |
785 | - case 0x5a: | |
786 | - case 0x75: | |
787 | - /* Airmont. */ | |
788 | - cpu = "silvermont"; | |
789 | - break; | |
790 | - case 0x5c: | |
791 | - case 0x5f: | |
792 | - /* Goldmont. */ | |
793 | - cpu = "goldmont"; | |
794 | - break; | |
795 | - case 0x7a: | |
796 | - /* Goldmont Plus. */ | |
797 | - cpu = "goldmont-plus"; | |
798 | - break; | |
799 | - case 0x86: | |
800 | - case 0x96: | |
801 | - case 0x9c: | |
802 | - /* Tremont. */ | |
803 | - cpu = "tremont"; | |
804 | - break; | |
805 | - case 0x0f: | |
806 | - /* Merom. */ | |
807 | - case 0x17: | |
808 | - case 0x1d: | |
809 | - /* Penryn. */ | |
810 | - cpu = "core2"; | |
811 | - break; | |
812 | - case 0x1a: | |
813 | - case 0x1e: | |
814 | - case 0x1f: | |
815 | - case 0x2e: | |
816 | - /* Nehalem. */ | |
817 | - cpu = "nehalem"; | |
818 | - break; | |
819 | - case 0x25: | |
820 | - case 0x2c: | |
821 | - case 0x2f: | |
822 | - /* Westmere. */ | |
823 | - cpu = "westmere"; | |
824 | - break; | |
825 | - case 0x2a: | |
826 | - case 0x2d: | |
827 | - /* Sandy Bridge. */ | |
828 | - cpu = "sandybridge"; | |
829 | - break; | |
830 | - case 0x3a: | |
831 | - case 0x3e: | |
832 | - /* Ivy Bridge. */ | |
833 | - cpu = "ivybridge"; | |
834 | - break; | |
835 | - case 0x3c: | |
836 | - case 0x3f: | |
837 | - case 0x45: | |
838 | - case 0x46: | |
839 | - /* Haswell. */ | |
840 | - cpu = "haswell"; | |
841 | - break; | |
842 | - case 0x3d: | |
843 | - case 0x47: | |
844 | - case 0x4f: | |
845 | - case 0x56: | |
846 | - /* Broadwell. */ | |
847 | - cpu = "broadwell"; | |
848 | - break; | |
849 | - case 0x4e: | |
850 | - case 0x5e: | |
851 | - /* Skylake. */ | |
852 | - case 0x8e: | |
853 | - case 0x9e: | |
854 | - /* Kaby Lake. */ | |
855 | - case 0xa5: | |
856 | - case 0xa6: | |
857 | - /* Comet Lake. */ | |
858 | - cpu = "skylake"; | |
859 | - break; | |
860 | - case 0x55: | |
861 | - if (has_avx512vnni) | |
862 | - /* Cascade Lake. */ | |
863 | - cpu = "cascadelake"; | |
864 | - else | |
865 | - /* Skylake with AVX-512. */ | |
866 | - cpu = "skylake-avx512"; | |
867 | - break; | |
868 | - case 0x6a: | |
869 | - case 0x6c: | |
870 | - /* Ice Lake server. */ | |
871 | - cpu = "icelake-server"; | |
872 | - break; | |
873 | - case 0x7e: | |
874 | - case 0x7d: | |
875 | - case 0x9d: | |
876 | - /* Ice Lake client. */ | |
877 | - cpu = "icelake-client"; | |
878 | - break; | |
879 | - case 0x8c: | |
880 | - case 0x8d: | |
881 | - /* Tiger Lake. */ | |
882 | - cpu = "tigerlake"; | |
883 | - break; | |
884 | - case 0x57: | |
885 | - /* Knights Landing. */ | |
886 | - cpu = "knl"; | |
887 | - break; | |
888 | - case 0x66: | |
889 | - /* Cannon Lake. */ | |
890 | - cpu = "cannonlake"; | |
891 | - break; | |
892 | - case 0x85: | |
893 | - /* Knights Mill. */ | |
894 | - cpu = "knm"; | |
895 | - break; | |
896 | - default: | |
897 | 561 | if (arch) |
898 | 562 | { |
899 | 563 | /* This is unknown family 0x6 CPU. */ |
900 | - if (has_avx) | |
901 | - { | |
902 | - /* Assume Tiger Lake */ | |
903 | - if (has_avx512vp2intersect) | |
904 | - cpu = "tigerlake"; | |
905 | - /* Assume Cooper Lake */ | |
906 | - else if (has_avx512bf16) | |
907 | - cpu = "cooperlake"; | |
908 | - /* Assume Ice Lake Server. */ | |
909 | - else if (has_wbnoinvd) | |
910 | - cpu = "icelake-server"; | |
564 | + if (has_feature (FEATURE_AVX)) | |
565 | + { | |
566 | + /* Assume Tiger Lake */ | |
567 | + if (has_feature (FEATURE_AVX512VP2INTERSECT)) | |
568 | + cpu = "tigerlake"; | |
569 | + /* Assume Cooper Lake */ | |
570 | + else if (has_feature (FEATURE_AVX512BF16)) | |
571 | + cpu = "cooperlake"; | |
572 | + /* Assume Ice Lake Server. */ | |
573 | + else if (has_feature (FEATURE_WBNOINVD)) | |
574 | + cpu = "icelake-server"; | |
911 | 575 | /* Assume Ice Lake. */ |
912 | - else if (has_avx512bitalg) | |
576 | + else if (has_feature (FEATURE_AVX512BITALG)) | |
913 | 577 | cpu = "icelake-client"; |
914 | 578 | /* Assume Cannon Lake. */ |
915 | - else if (has_avx512vbmi) | |
579 | + else if (has_feature (FEATURE_AVX512VBMI)) | |
916 | 580 | cpu = "cannonlake"; |
917 | 581 | /* Assume Knights Mill. */ |
918 | - else if (has_avx5124vnniw) | |
582 | + else if (has_feature (FEATURE_AVX5124VNNIW)) | |
919 | 583 | cpu = "knm"; |
920 | 584 | /* Assume Knights Landing. */ |
921 | - else if (has_avx512er) | |
585 | + else if (has_feature (FEATURE_AVX512ER)) | |
922 | 586 | cpu = "knl"; |
923 | 587 | /* Assume Skylake with AVX-512. */ |
924 | - else if (has_avx512f) | |
588 | + else if (has_feature (FEATURE_AVX512F)) | |
925 | 589 | cpu = "skylake-avx512"; |
926 | 590 | /* Assume Skylake. */ |
927 | - else if (has_clflushopt) | |
591 | + else if (has_feature (FEATURE_CLFLUSHOPT)) | |
928 | 592 | cpu = "skylake"; |
929 | 593 | /* Assume Broadwell. */ |
930 | - else if (has_adx) | |
594 | + else if (has_feature (FEATURE_ADX)) | |
931 | 595 | cpu = "broadwell"; |
932 | - else if (has_avx2) | |
596 | + else if (has_feature (FEATURE_AVX2)) | |
933 | 597 | /* Assume Haswell. */ |
934 | 598 | cpu = "haswell"; |
935 | 599 | else |
936 | 600 | /* Assume Sandy Bridge. */ |
937 | 601 | cpu = "sandybridge"; |
938 | 602 | } |
939 | - else if (has_sse4_2) | |
603 | + else if (has_feature (FEATURE_SSE4_2)) | |
940 | 604 | { |
941 | - if (has_gfni) | |
605 | + if (has_feature (FEATURE_GFNI)) | |
942 | 606 | /* Assume Tremont. */ |
943 | 607 | cpu = "tremont"; |
944 | - else if (has_sgx) | |
608 | + else if (has_feature (FEATURE_SGX)) | |
945 | 609 | /* Assume Goldmont Plus. */ |
946 | 610 | cpu = "goldmont-plus"; |
947 | - else if (has_xsave) | |
611 | + else if (has_feature (FEATURE_XSAVE)) | |
948 | 612 | /* Assume Goldmont. */ |
949 | 613 | cpu = "goldmont"; |
950 | - else if (has_movbe) | |
614 | + else if (has_feature (FEATURE_MOVBE)) | |
951 | 615 | /* Assume Silvermont. */ |
952 | 616 | cpu = "silvermont"; |
953 | 617 | else |
954 | 618 | /* Assume Nehalem. */ |
955 | 619 | cpu = "nehalem"; |
956 | 620 | } |
957 | - else if (has_ssse3) | |
621 | + else if (has_feature (FEATURE_SSSE3)) | |
958 | 622 | { |
959 | - if (has_movbe) | |
623 | + if (has_feature (FEATURE_MOVBE)) | |
960 | 624 | /* Assume Bonnell. */ |
961 | 625 | cpu = "bonnell"; |
962 | 626 | else |
963 | 627 | /* Assume Core 2. */ |
964 | 628 | cpu = "core2"; |
965 | 629 | } |
966 | - else if (has_longmode) | |
630 | + else if (has_feature (FEATURE_LM)) | |
967 | 631 | /* Perhaps some emulator? Assume x86-64, otherwise gcc |
968 | 632 | -march=native would be unusable for 64-bit compilations, |
969 | 633 | as all the CPUs below are 32-bit only. */ |
970 | 634 | cpu = "x86-64"; |
971 | - else if (has_sse3) | |
635 | + else if (has_feature (FEATURE_SSE3)) | |
972 | 636 | { |
973 | - if (vendor == signature_CENTAUR_ebx) | |
637 | + if (vendor == VENDOR_CENTAUR) | |
974 | 638 | /* C7 / Eden "Esther" */ |
975 | 639 | cpu = "c7"; |
976 | 640 | else |
977 | 641 | /* It is Core Duo. */ |
978 | 642 | cpu = "pentium-m"; |
979 | 643 | } |
980 | - else if (has_sse2) | |
644 | + else if (has_feature (FEATURE_SSE2)) | |
981 | 645 | /* It is Pentium M. */ |
982 | 646 | cpu = "pentium-m"; |
983 | - else if (has_sse) | |
647 | + else if (has_feature (FEATURE_SSE)) | |
984 | 648 | { |
985 | - if (vendor == signature_CENTAUR_ebx) | |
649 | + if (vendor == VENDOR_CENTAUR) | |
986 | 650 | { |
987 | 651 | if (model >= 9) |
988 | 652 | /* Eden "Nehemiah" */ |
@@ -994,7 +658,7 @@ const char *host_detect_local_cpu (int argc, const char **argv) | ||
994 | 658 | /* It is Pentium III. */ |
995 | 659 | cpu = "pentium3"; |
996 | 660 | } |
997 | - else if (has_mmx) | |
661 | + else if (has_feature (FEATURE_MMX)) | |
998 | 662 | /* It is Pentium II. */ |
999 | 663 | cpu = "pentium2"; |
1000 | 664 | else |
@@ -1004,13 +668,12 @@ const char *host_detect_local_cpu (int argc, const char **argv) | ||
1004 | 668 | else |
1005 | 669 | /* For -mtune, we default to -mtune=generic. */ |
1006 | 670 | cpu = "generic"; |
1007 | - break; | |
1008 | 671 | } |
1009 | 672 | break; |
1010 | 673 | case PROCESSOR_PENTIUM4: |
1011 | - if (has_sse3) | |
674 | + if (has_feature (FEATURE_SSE3)) | |
1012 | 675 | { |
1013 | - if (has_longmode) | |
676 | + if (has_feature (FEATURE_LM)) | |
1014 | 677 | cpu = "nocona"; |
1015 | 678 | else |
1016 | 679 | cpu = "prescott"; |
@@ -1022,13 +685,13 @@ const char *host_detect_local_cpu (int argc, const char **argv) | ||
1022 | 685 | cpu = "geode"; |
1023 | 686 | break; |
1024 | 687 | case PROCESSOR_K6: |
1025 | - if (arch && has_3dnow) | |
688 | + if (arch && has_feature (FEATURE_3DNOW)) | |
1026 | 689 | cpu = "k6-3"; |
1027 | 690 | else |
1028 | 691 | cpu = "k6"; |
1029 | 692 | break; |
1030 | 693 | case PROCESSOR_ATHLON: |
1031 | - if (arch && has_sse) | |
694 | + if (arch && has_feature (FEATURE_SSE)) | |
1032 | 695 | cpu = "athlon-4"; |
1033 | 696 | else |
1034 | 697 | cpu = "athlon"; |
@@ -1036,22 +699,22 @@ const char *host_detect_local_cpu (int argc, const char **argv) | ||
1036 | 699 | case PROCESSOR_K8: |
1037 | 700 | if (arch) |
1038 | 701 | { |
1039 | - if (vendor == signature_CENTAUR_ebx) | |
702 | + if (vendor == VENDOR_CENTAUR) | |
1040 | 703 | { |
1041 | - if (has_sse4_1) | |
704 | + if (has_feature (FEATURE_SSE4_1)) | |
1042 | 705 | /* Nano 3000 | Nano dual / quad core | Eden X4 */ |
1043 | 706 | cpu = "nano-3000"; |
1044 | - else if (has_ssse3) | |
707 | + else if (has_feature (FEATURE_SSSE3)) | |
1045 | 708 | /* Nano 1000 | Nano 2000 */ |
1046 | 709 | cpu = "nano"; |
1047 | - else if (has_sse3) | |
710 | + else if (has_feature (FEATURE_SSE3)) | |
1048 | 711 | /* Eden X2 */ |
1049 | 712 | cpu = "eden-x2"; |
1050 | 713 | else |
1051 | 714 | /* Default to k8 */ |
1052 | 715 | cpu = "k8"; |
1053 | 716 | } |
1054 | - else if (has_sse3) | |
717 | + else if (has_feature (FEATURE_SSE3)) | |
1055 | 718 | cpu = "k8-sse3"; |
1056 | 719 | else |
1057 | 720 | cpu = "k8"; |
@@ -1092,27 +755,27 @@ const char *host_detect_local_cpu (int argc, const char **argv) | ||
1092 | 755 | /* Use something reasonable. */ |
1093 | 756 | if (arch) |
1094 | 757 | { |
1095 | - if (has_ssse3) | |
758 | + if (has_feature (FEATURE_SSSE3)) | |
1096 | 759 | cpu = "core2"; |
1097 | - else if (has_sse3) | |
760 | + else if (has_feature (FEATURE_SSE3)) | |
1098 | 761 | { |
1099 | - if (has_longmode) | |
762 | + if (has_feature (FEATURE_LM)) | |
1100 | 763 | cpu = "nocona"; |
1101 | 764 | else |
1102 | 765 | cpu = "prescott"; |
1103 | 766 | } |
1104 | - else if (has_longmode) | |
767 | + else if (has_feature (FEATURE_LM)) | |
1105 | 768 | /* Perhaps some emulator? Assume x86-64, otherwise gcc |
1106 | 769 | -march=native would be unusable for 64-bit compilations, |
1107 | 770 | as all the CPUs below are 32-bit only. */ |
1108 | 771 | cpu = "x86-64"; |
1109 | - else if (has_sse2) | |
772 | + else if (has_feature (FEATURE_SSE2)) | |
1110 | 773 | cpu = "pentium4"; |
1111 | - else if (has_cmov) | |
774 | + else if (has_feature (FEATURE_CMOV)) | |
1112 | 775 | cpu = "pentiumpro"; |
1113 | - else if (has_mmx) | |
776 | + else if (has_feature (FEATURE_MMX)) | |
1114 | 777 | cpu = "pentium-mmx"; |
1115 | - else if (has_cmpxchg8b) | |
778 | + else if (has_feature (FEATURE_CMPXCHG8B)) | |
1116 | 779 | cpu = "pentium"; |
1117 | 780 | } |
1118 | 781 | else |
@@ -1121,101 +784,18 @@ const char *host_detect_local_cpu (int argc, const char **argv) | ||
1121 | 784 | |
1122 | 785 | if (arch) |
1123 | 786 | { |
1124 | - const char *mmx = has_mmx ? " -mmmx" : " -mno-mmx"; | |
1125 | - const char *mmx3dnow = has_3dnow ? " -m3dnow" : " -mno-3dnow"; | |
1126 | - const char *sse = has_sse ? " -msse" : " -mno-sse"; | |
1127 | - const char *sse2 = has_sse2 ? " -msse2" : " -mno-sse2"; | |
1128 | - const char *sse3 = has_sse3 ? " -msse3" : " -mno-sse3"; | |
1129 | - const char *ssse3 = has_ssse3 ? " -mssse3" : " -mno-ssse3"; | |
1130 | - const char *sse4a = has_sse4a ? " -msse4a" : " -mno-sse4a"; | |
1131 | - const char *cx16 = has_cmpxchg16b ? " -mcx16" : " -mno-cx16"; | |
1132 | - const char *sahf = has_lahf_lm ? " -msahf" : " -mno-sahf"; | |
1133 | - const char *movbe = has_movbe ? " -mmovbe" : " -mno-movbe"; | |
1134 | - const char *aes = has_aes ? " -maes" : " -mno-aes"; | |
1135 | - const char *sha = has_sha ? " -msha" : " -mno-sha"; | |
1136 | - const char *pclmul = has_pclmul ? " -mpclmul" : " -mno-pclmul"; | |
1137 | - const char *popcnt = has_popcnt ? " -mpopcnt" : " -mno-popcnt"; | |
1138 | - const char *abm = has_abm ? " -mabm" : " -mno-abm"; | |
1139 | - const char *lwp = has_lwp ? " -mlwp" : " -mno-lwp"; | |
1140 | - const char *fma = has_fma ? " -mfma" : " -mno-fma"; | |
1141 | - const char *fma4 = has_fma4 ? " -mfma4" : " -mno-fma4"; | |
1142 | - const char *xop = has_xop ? " -mxop" : " -mno-xop"; | |
1143 | - const char *bmi = has_bmi ? " -mbmi" : " -mno-bmi"; | |
1144 | - const char *pconfig = has_pconfig ? " -mpconfig" : " -mno-pconfig"; | |
1145 | - const char *wbnoinvd = has_wbnoinvd ? " -mwbnoinvd" : " -mno-wbnoinvd"; | |
1146 | - const char *sgx = has_sgx ? " -msgx" : " -mno-sgx"; | |
1147 | - const char *bmi2 = has_bmi2 ? " -mbmi2" : " -mno-bmi2"; | |
1148 | - const char *tbm = has_tbm ? " -mtbm" : " -mno-tbm"; | |
1149 | - const char *avx = has_avx ? " -mavx" : " -mno-avx"; | |
1150 | - const char *avx2 = has_avx2 ? " -mavx2" : " -mno-avx2"; | |
1151 | - const char *sse4_2 = has_sse4_2 ? " -msse4.2" : " -mno-sse4.2"; | |
1152 | - const char *sse4_1 = has_sse4_1 ? " -msse4.1" : " -mno-sse4.1"; | |
1153 | - const char *lzcnt = has_lzcnt ? " -mlzcnt" : " -mno-lzcnt"; | |
1154 | - const char *hle = has_hle ? " -mhle" : " -mno-hle"; | |
1155 | - const char *rtm = has_rtm ? " -mrtm" : " -mno-rtm"; | |
1156 | - const char *rdrnd = has_rdrnd ? " -mrdrnd" : " -mno-rdrnd"; | |
1157 | - const char *f16c = has_f16c ? " -mf16c" : " -mno-f16c"; | |
1158 | - const char *fsgsbase = has_fsgsbase ? " -mfsgsbase" : " -mno-fsgsbase"; | |
1159 | - const char *rdseed = has_rdseed ? " -mrdseed" : " -mno-rdseed"; | |
1160 | - const char *prfchw = has_prfchw ? " -mprfchw" : " -mno-prfchw"; | |
1161 | - const char *adx = has_adx ? " -madx" : " -mno-adx"; | |
1162 | - const char *fxsr = has_fxsr ? " -mfxsr" : " -mno-fxsr"; | |
1163 | - const char *xsave = has_xsave ? " -mxsave" : " -mno-xsave"; | |
1164 | - const char *xsaveopt = has_xsaveopt ? " -mxsaveopt" : " -mno-xsaveopt"; | |
1165 | - const char *avx512f = has_avx512f ? " -mavx512f" : " -mno-avx512f"; | |
1166 | - const char *avx512er = has_avx512er ? " -mavx512er" : " -mno-avx512er"; | |
1167 | - const char *avx512cd = has_avx512cd ? " -mavx512cd" : " -mno-avx512cd"; | |
1168 | - const char *avx512pf = has_avx512pf ? " -mavx512pf" : " -mno-avx512pf"; | |
1169 | - const char *prefetchwt1 = has_prefetchwt1 ? " -mprefetchwt1" : " -mno-prefetchwt1"; | |
1170 | - const char *clflushopt = has_clflushopt ? " -mclflushopt" : " -mno-clflushopt"; | |
1171 | - const char *xsavec = has_xsavec ? " -mxsavec" : " -mno-xsavec"; | |
1172 | - const char *xsaves = has_xsaves ? " -mxsaves" : " -mno-xsaves"; | |
1173 | - const char *avx512dq = has_avx512dq ? " -mavx512dq" : " -mno-avx512dq"; | |
1174 | - const char *avx512bw = has_avx512bw ? " -mavx512bw" : " -mno-avx512bw"; | |
1175 | - const char *avx512vl = has_avx512vl ? " -mavx512vl" : " -mno-avx512vl"; | |
1176 | - const char *avx512ifma = has_avx512ifma ? " -mavx512ifma" : " -mno-avx512ifma"; | |
1177 | - const char *avx512vbmi = has_avx512vbmi ? " -mavx512vbmi" : " -mno-avx512vbmi"; | |
1178 | - const char *avx5124vnniw = has_avx5124vnniw ? " -mavx5124vnniw" : " -mno-avx5124vnniw"; | |
1179 | - const char *avx512vbmi2 = has_avx512vbmi2 ? " -mavx512vbmi2" : " -mno-avx512vbmi2"; | |
1180 | - const char *avx512vnni = has_avx512vnni ? " -mavx512vnni" : " -mno-avx512vnni"; | |
1181 | - const char *avx5124fmaps = has_avx5124fmaps ? " -mavx5124fmaps" : " -mno-avx5124fmaps"; | |
1182 | - const char *clwb = has_clwb ? " -mclwb" : " -mno-clwb"; | |
1183 | - const char *mwaitx = has_mwaitx ? " -mmwaitx" : " -mno-mwaitx"; | |
1184 | - const char *clzero = has_clzero ? " -mclzero" : " -mno-clzero"; | |
1185 | - const char *pku = has_pku ? " -mpku" : " -mno-pku"; | |
1186 | - const char *rdpid = has_rdpid ? " -mrdpid" : " -mno-rdpid"; | |
1187 | - const char *gfni = has_gfni ? " -mgfni" : " -mno-gfni"; | |
1188 | - const char *shstk = has_shstk ? " -mshstk" : " -mno-shstk"; | |
1189 | - const char *vaes = has_vaes ? " -mvaes" : " -mno-vaes"; | |
1190 | - const char *vpclmulqdq = has_vpclmulqdq ? " -mvpclmulqdq" : " -mno-vpclmulqdq"; | |
1191 | - const char *avx512vp2intersect = has_avx512vp2intersect ? " -mavx512vp2intersect" : " -mno-avx512vp2intersect"; | |
1192 | - const char *tsxldtrk = has_tsxldtrk ? " -mtsxldtrk " : " -mno-tsxldtrk"; | |
1193 | - const char *avx512bitalg = has_avx512bitalg ? " -mavx512bitalg" : " -mno-avx512bitalg"; | |
1194 | - const char *avx512vpopcntdq = has_avx512vpopcntdq ? " -mavx512vpopcntdq" : " -mno-avx512vpopcntdq"; | |
1195 | - const char *movdiri = has_movdiri ? " -mmovdiri" : " -mno-movdiri"; | |
1196 | - const char *movdir64b = has_movdir64b ? " -mmovdir64b" : " -mno-movdir64b"; | |
1197 | - const char *enqcmd = has_enqcmd ? " -menqcmd" : " -mno-enqcmd"; | |
1198 | - const char *waitpkg = has_waitpkg ? " -mwaitpkg" : " -mno-waitpkg"; | |
1199 | - const char *cldemote = has_cldemote ? " -mcldemote" : " -mno-cldemote"; | |
1200 | - const char *serialize = has_serialize ? " -mserialize" : " -mno-serialize"; | |
1201 | - const char *ptwrite = has_ptwrite ? " -mptwrite" : " -mno-ptwrite"; | |
1202 | - const char *avx512bf16 = has_avx512bf16 ? " -mavx512bf16" : " -mno-avx512bf16"; | |
1203 | - | |
1204 | - options = concat (options, mmx, mmx3dnow, sse, sse2, sse3, ssse3, | |
1205 | - sse4a, cx16, sahf, movbe, aes, sha, pclmul, | |
1206 | - popcnt, abm, lwp, fma, fma4, xop, bmi, sgx, bmi2, | |
1207 | - pconfig, wbnoinvd, | |
1208 | - tbm, avx, avx2, sse4_2, sse4_1, lzcnt, rtm, | |
1209 | - hle, rdrnd, f16c, fsgsbase, rdseed, prfchw, adx, | |
1210 | - fxsr, xsave, xsaveopt, avx512f, avx512er, | |
1211 | - avx512cd, avx512pf, prefetchwt1, clflushopt, | |
1212 | - xsavec, xsaves, avx512dq, avx512bw, avx512vl, | |
1213 | - avx512ifma, avx512vbmi, avx5124fmaps, avx5124vnniw, | |
1214 | - clwb, mwaitx, clzero, pku, rdpid, gfni, shstk, | |
1215 | - avx512vbmi2, avx512vnni, vaes, vpclmulqdq, | |
1216 | - avx512bitalg, avx512vpopcntdq, movdiri, movdir64b, | |
1217 | - waitpkg, cldemote, ptwrite, avx512bf16, enqcmd, | |
1218 | - avx512vp2intersect, serialize, tsxldtrk, NULL); | |
787 | + unsigned int i; | |
788 | + const char *const neg_option = " -mno-"; | |
789 | + for (i = 0; i < ARRAY_SIZE (isa_names_table); i++) | |
790 | + if (isa_names_table[i].option) | |
791 | + { | |
792 | + if (has_feature (isa_names_table[i].feature)) | |
793 | + options = concat (options, " ", | |
794 | + isa_names_table[i].option, NULL); | |
795 | + else | |
796 | + options = concat (options, neg_option, | |
797 | + isa_names_table[i].option + 2, NULL); | |
798 | + } | |
1219 | 799 | } |
1220 | 800 | |
1221 | 801 | done: |
@@ -90,6 +90,7 @@ along with GCC; see the file COPYING3. If not see | ||
90 | 90 | #include "debug.h" |
91 | 91 | #include "dwarf2out.h" |
92 | 92 | #include "i386-builtins.h" |
93 | +#include "common/config/i386/i386-isas.h" | |
93 | 94 | |
94 | 95 | #undef BDESC |
95 | 96 | #undef BDESC_FIRST |
@@ -1835,57 +1836,6 @@ ix86_builtin_reciprocal (tree fndecl) | ||
1835 | 1836 | } |
1836 | 1837 | } |
1837 | 1838 | |
1838 | -/* These are the target attribute strings for which a dispatcher is | |
1839 | - available, from fold_builtin_cpu. */ | |
1840 | -struct _isa_names_table | |
1841 | -{ | |
1842 | - const char *const name; | |
1843 | - const enum processor_features feature; | |
1844 | - const enum feature_priority priority; | |
1845 | -}; | |
1846 | - | |
1847 | -static const _isa_names_table isa_names_table[] = | |
1848 | -{ | |
1849 | - {"cmov", FEATURE_CMOV, P_NONE}, | |
1850 | - {"mmx", FEATURE_MMX, P_MMX}, | |
1851 | - {"popcnt", FEATURE_POPCNT, P_POPCNT}, | |
1852 | - {"sse", FEATURE_SSE, P_SSE}, | |
1853 | - {"sse2", FEATURE_SSE2, P_SSE2}, | |
1854 | - {"sse3", FEATURE_SSE3, P_SSE3}, | |
1855 | - {"ssse3", FEATURE_SSSE3, P_SSSE3}, | |
1856 | - {"sse4a", FEATURE_SSE4_A, P_SSE4_A}, | |
1857 | - {"sse4.1", FEATURE_SSE4_1, P_SSE4_1}, | |
1858 | - {"sse4.2", FEATURE_SSE4_2, P_SSE4_2}, | |
1859 | - {"avx", FEATURE_AVX, P_AVX}, | |
1860 | - {"fma4", FEATURE_FMA4, P_FMA4}, | |
1861 | - {"xop", FEATURE_XOP, P_XOP}, | |
1862 | - {"fma", FEATURE_FMA, P_FMA}, | |
1863 | - {"avx2", FEATURE_AVX2, P_AVX2}, | |
1864 | - {"avx512f", FEATURE_AVX512F, P_AVX512F}, | |
1865 | - {"bmi", FEATURE_BMI, P_BMI}, | |
1866 | - {"bmi2", FEATURE_BMI2, P_BMI2}, | |
1867 | - {"aes", FEATURE_AES, P_AES}, | |
1868 | - {"pclmul", FEATURE_PCLMUL, P_PCLMUL}, | |
1869 | - {"avx512vl",FEATURE_AVX512VL, P_NONE}, | |
1870 | - {"avx512bw",FEATURE_AVX512BW, P_NONE}, | |
1871 | - {"avx512dq",FEATURE_AVX512DQ, P_NONE}, | |
1872 | - {"avx512cd",FEATURE_AVX512CD, P_NONE}, | |
1873 | - {"avx512er",FEATURE_AVX512ER, P_NONE}, | |
1874 | - {"avx512pf",FEATURE_AVX512PF, P_NONE}, | |
1875 | - {"avx512vbmi",FEATURE_AVX512VBMI, P_NONE}, | |
1876 | - {"avx512ifma",FEATURE_AVX512IFMA, P_NONE}, | |
1877 | - {"avx5124vnniw",FEATURE_AVX5124VNNIW, P_NONE}, | |
1878 | - {"avx5124fmaps",FEATURE_AVX5124FMAPS, P_NONE}, | |
1879 | - {"avx512vpopcntdq",FEATURE_AVX512VPOPCNTDQ, P_NONE}, | |
1880 | - {"avx512vbmi2", FEATURE_AVX512VBMI2, P_NONE}, | |
1881 | - {"gfni", FEATURE_GFNI, P_NONE}, | |
1882 | - {"vpclmulqdq", FEATURE_VPCLMULQDQ, P_NONE}, | |
1883 | - {"avx512vnni", FEATURE_AVX512VNNI, P_NONE}, | |
1884 | - {"avx512bitalg", FEATURE_AVX512BITALG, P_NONE}, | |
1885 | - {"avx512bf16", FEATURE_AVX512BF16, P_NONE}, | |
1886 | - {"avx512vp2intersect",FEATURE_AVX512VP2INTERSECT, P_NONE} | |
1887 | -}; | |
1888 | - | |
1889 | 1839 | /* This parses the attribute arguments to target in DECL and determines |
1890 | 1840 | the right builtin to use to match the platform specification. |
1891 | 1841 | It returns the priority value for this version decl. If PREDICATE_LIST |
@@ -7,348 +7,53 @@ | ||
7 | 7 | /* { dg-do run } */ |
8 | 8 | |
9 | 9 | #include <assert.h> |
10 | +#include <stdlib.h> | |
10 | 11 | #include "cpuid.h" |
11 | - | |
12 | -/* Check if the Intel CPU model and sub-model are identified. */ | |
13 | -static void | |
14 | -check_intel_cpu_model (unsigned int family, unsigned int model, | |
15 | - unsigned int brand_id) | |
16 | -{ | |
17 | - /* Parse family and model only if brand ID is 0. */ | |
18 | - if (brand_id == 0) | |
19 | - { | |
20 | - switch (family) | |
21 | - { | |
22 | - case 0x5: | |
23 | - /* Pentium. */ | |
24 | - break; | |
25 | - case 0x6: | |
26 | - switch (model) | |
27 | - { | |
28 | - case 0x1c: | |
29 | - case 0x26: | |
30 | - /* Atom. */ | |
31 | - assert (__builtin_cpu_is ("atom")); | |
32 | - break; | |
33 | - case 0x37: | |
34 | - case 0x4a: | |
35 | - case 0x4d: | |
36 | - case 0x5a: | |
37 | - case 0x5d: | |
38 | - /* Silvermont. */ | |
39 | - assert (__builtin_cpu_is ("silvermont")); | |
40 | - break; | |
41 | - case 0x5c: | |
42 | - case 0x5f: | |
43 | - /* Goldmont. */ | |
44 | - assert (__builtin_cpu_is ("goldmont")); | |
45 | - break; | |
46 | - case 0x7a: | |
47 | - /* Goldmont Plus. */ | |
48 | - assert (__builtin_cpu_is ("goldmont-plus")); | |
49 | - break; | |
50 | - case 0x57: | |
51 | - /* Knights Landing. */ | |
52 | - assert (__builtin_cpu_is ("knl")); | |
53 | - break; | |
54 | - case 0x85: | |
55 | - /* Knights Mill */ | |
56 | - assert (__builtin_cpu_is ("knm")); | |
57 | - break; | |
58 | - case 0x1a: | |
59 | - case 0x1e: | |
60 | - case 0x1f: | |
61 | - case 0x2e: | |
62 | - /* Nehalem. */ | |
63 | - assert (__builtin_cpu_is ("corei7")); | |
64 | - assert (__builtin_cpu_is ("nehalem")); | |
65 | - break; | |
66 | - case 0x25: | |
67 | - case 0x2c: | |
68 | - case 0x2f: | |
69 | - /* Westmere. */ | |
70 | - assert (__builtin_cpu_is ("corei7")); | |
71 | - assert (__builtin_cpu_is ("westmere")); | |
72 | - break; | |
73 | - case 0x2a: | |
74 | - case 0x2d: | |
75 | - /* Sandy Bridge. */ | |
76 | - assert (__builtin_cpu_is ("corei7")); | |
77 | - assert (__builtin_cpu_is ("sandybridge")); | |
78 | - break; | |
79 | - case 0x3a: | |
80 | - case 0x3e: | |
81 | - /* Ivy Bridge. */ | |
82 | - assert (__builtin_cpu_is ("corei7")); | |
83 | - assert (__builtin_cpu_is ("ivybridge")); | |
84 | - break; | |
85 | - case 0x3c: | |
86 | - case 0x3f: | |
87 | - case 0x45: | |
88 | - case 0x46: | |
89 | - /* Haswell. */ | |
90 | - assert (__builtin_cpu_is ("corei7")); | |
91 | - assert (__builtin_cpu_is ("haswell")); | |
92 | - break; | |
93 | - case 0x3d: | |
94 | - case 0x47: | |
95 | - case 0x4f: | |
96 | - case 0x56: | |
97 | - /* Broadwell. */ | |
98 | - assert (__builtin_cpu_is ("corei7")); | |
99 | - assert (__builtin_cpu_is ("broadwell")); | |
100 | - break; | |
101 | - case 0x4e: | |
102 | - case 0x5e: | |
103 | - /* Skylake. */ | |
104 | - case 0x8e: | |
105 | - case 0x9e: | |
106 | - /* Kaby Lake. */ | |
107 | - assert (__builtin_cpu_is ("corei7")); | |
108 | - assert (__builtin_cpu_is ("skylake")); | |
109 | - break; | |
110 | - case 0x55: | |
111 | - { | |
112 | - unsigned int eax, ebx, ecx, edx; | |
113 | - __cpuid_count (7, 0, eax, ebx, ecx, edx); | |
114 | - assert (__builtin_cpu_is ("corei7")); | |
115 | - if (ecx & bit_AVX512VNNI) | |
116 | - /* Cascade Lake. */ | |
117 | - assert (__builtin_cpu_is ("cascadelake")); | |
118 | - else | |
119 | - /* Skylake with AVX-512 support. */ | |
120 | - assert (__builtin_cpu_is ("skylake-avx512")); | |
121 | - break; | |
122 | - } | |
123 | - case 0x66: | |
124 | - /* Cannon Lake. */ | |
125 | - assert (__builtin_cpu_is ("cannonlake")); | |
126 | - break; | |
127 | - case 0x17: | |
128 | - case 0x1d: | |
129 | - /* Penryn. */ | |
130 | - case 0x0f: | |
131 | - /* Merom. */ | |
132 | - assert (__builtin_cpu_is ("core2")); | |
133 | - break; | |
134 | - default: | |
135 | - break; | |
136 | - } | |
137 | - break; | |
138 | - default: | |
139 | - /* We have no idea. */ | |
140 | - break; | |
141 | - } | |
142 | - } | |
143 | -} | |
144 | - | |
145 | -/* Check if the AMD CPU model and sub-model are identified. */ | |
146 | -static void | |
147 | -check_amd_cpu_model (unsigned int family, unsigned int model) | |
148 | -{ | |
149 | - switch (family) | |
150 | - { | |
151 | - /* AMD Family 10h. */ | |
152 | - case 0x10: | |
153 | - switch (model) | |
154 | - { | |
155 | - case 0x2: | |
156 | - /* Barcelona. */ | |
157 | - assert (__builtin_cpu_is ("amdfam10h")); | |
158 | - assert (__builtin_cpu_is ("barcelona")); | |
159 | - break; | |
160 | - case 0x4: | |
161 | - /* Shanghai. */ | |
162 | - assert (__builtin_cpu_is ("amdfam10h")); | |
163 | - assert (__builtin_cpu_is ("shanghai")); | |
164 | - break; | |
165 | - case 0x8: | |
166 | - /* Istanbul. */ | |
167 | - assert (__builtin_cpu_is ("amdfam10h")); | |
168 | - assert (__builtin_cpu_is ("istanbul")); | |
169 | - break; | |
170 | - default: | |
171 | - break; | |
172 | - } | |
173 | - break; | |
174 | - /* AMD Family 15h. */ | |
175 | - case 0x15: | |
176 | - assert (__builtin_cpu_is ("amdfam15h")); | |
177 | - /* Bulldozer version 1. */ | |
178 | - if ( model <= 0xf) | |
179 | - assert (__builtin_cpu_is ("bdver1")); | |
180 | - /* Bulldozer version 2. */ | |
181 | - if (model >= 0x10 && model <= 0x1f) | |
182 | - assert (__builtin_cpu_is ("bdver2")); | |
183 | - break; | |
184 | - default: | |
185 | - break; | |
186 | - } | |
187 | -} | |
12 | +#define CHECK___builtin_cpu_is(cpu) assert (__builtin_cpu_is (cpu)) | |
13 | +#define gcc_assert(a) assert (a) | |
14 | +#define gcc_unreachable() abort () | |
15 | +#define inline | |
16 | +#include "../../../common/config/i386/i386-cpuinfo.h" | |
17 | +#include "../../../common/config/i386/cpuinfo.h" | |
188 | 18 | |
189 | 19 | /* Check if the ISA features are identified. */ |
190 | 20 | static void |
191 | -check_features (unsigned int ecx, unsigned int edx, | |
192 | - int max_cpuid_level) | |
21 | +check_features (struct __processor_model *cpu_model, | |
22 | + unsigned int *cpu_features2) | |
193 | 23 | { |
194 | - unsigned int eax, ebx; | |
195 | - unsigned int ext_level; | |
196 | - | |
197 | - if (edx & bit_CMOV) | |
198 | - assert (__builtin_cpu_supports ("cmov")); | |
199 | - if (edx & bit_MMX) | |
200 | - assert (__builtin_cpu_supports ("mmx")); | |
201 | - if (edx & bit_SSE) | |
202 | - assert (__builtin_cpu_supports ("sse")); | |
203 | - if (edx & bit_SSE2) | |
204 | - assert (__builtin_cpu_supports ("sse2")); | |
205 | - if (ecx & bit_POPCNT) | |
206 | - assert (__builtin_cpu_supports ("popcnt")); | |
207 | - if (ecx & bit_AES) | |
208 | - assert (__builtin_cpu_supports ("aes")); | |
209 | - if (ecx & bit_PCLMUL) | |
210 | - assert (__builtin_cpu_supports ("pclmul")); | |
211 | - if (ecx & bit_SSE3) | |
212 | - assert (__builtin_cpu_supports ("sse3")); | |
213 | - if (ecx & bit_SSSE3) | |
214 | - assert (__builtin_cpu_supports ("ssse3")); | |
215 | - if (ecx & bit_SSE4_1) | |
216 | - assert (__builtin_cpu_supports ("sse4.1")); | |
217 | - if (ecx & bit_SSE4_2) | |
218 | - assert (__builtin_cpu_supports ("sse4.2")); | |
219 | - if (ecx & bit_AVX) | |
220 | - assert (__builtin_cpu_supports ("avx")); | |
221 | - if (ecx & bit_FMA) | |
222 | - assert (__builtin_cpu_supports ("fma")); | |
223 | - | |
224 | - /* Get advanced features at level 7 (eax = 7, ecx = 0). */ | |
225 | - if (max_cpuid_level >= 7) | |
226 | - { | |
227 | - __cpuid_count (7, 0, eax, ebx, ecx, edx); | |
228 | - if (ebx & bit_BMI) | |
229 | - assert (__builtin_cpu_supports ("bmi")); | |
230 | - if (ebx & bit_AVX2) | |
231 | - assert (__builtin_cpu_supports ("avx2")); | |
232 | - if (ebx & bit_BMI2) | |
233 | - assert (__builtin_cpu_supports ("bmi2")); | |
234 | - if (ebx & bit_AVX512F) | |
235 | - assert (__builtin_cpu_supports ("avx512f")); | |
236 | - if (ebx & bit_AVX512VL) | |
237 | - assert (__builtin_cpu_supports ("avx512vl")); | |
238 | - if (ebx & bit_AVX512BW) | |
239 | - assert (__builtin_cpu_supports ("avx512bw")); | |
240 | - if (ebx & bit_AVX512DQ) | |
241 | - assert (__builtin_cpu_supports ("avx512dq")); | |
242 | - if (ebx & bit_AVX512CD) | |
243 | - assert (__builtin_cpu_supports ("avx512cd")); | |
244 | - if (ebx & bit_AVX512PF) | |
245 | - assert (__builtin_cpu_supports ("avx512pf")); | |
246 | - if (ebx & bit_AVX512ER) | |
247 | - assert (__builtin_cpu_supports ("avx512er")); | |
248 | - if (ebx & bit_AVX512IFMA) | |
249 | - assert (__builtin_cpu_supports ("avx512ifma")); | |
250 | - if (ecx & bit_AVX512VBMI) | |
251 | - assert (__builtin_cpu_supports ("avx512vbmi")); | |
252 | - if (ecx & bit_AVX512VBMI2) | |
253 | - assert (__builtin_cpu_supports ("avx512vbmi2")); | |
254 | - if (ecx & bit_GFNI) | |
255 | - assert (__builtin_cpu_supports ("gfni")); | |
256 | - if (ecx & bit_VPCLMULQDQ) | |
257 | - assert (__builtin_cpu_supports ("vpclmulqdq")); | |
258 | - if (ecx & bit_AVX512VNNI) | |
259 | - assert (__builtin_cpu_supports ("avx512vnni")); | |
260 | - if (ecx & bit_AVX512BITALG) | |
261 | - assert (__builtin_cpu_supports ("avx512bitalg")); | |
262 | - if (ecx & bit_AVX512VPOPCNTDQ) | |
263 | - assert (__builtin_cpu_supports ("avx512vpopcntdq")); | |
264 | - if (edx & bit_AVX5124VNNIW) | |
265 | - assert (__builtin_cpu_supports ("avx5124vnniw")); | |
266 | - if (edx & bit_AVX5124FMAPS) | |
267 | - assert (__builtin_cpu_supports ("avx5124fmaps")); | |
268 | - | |
269 | - __cpuid_count (7, 1, eax, ebx, ecx, edx); | |
270 | - if (eax & bit_AVX512BF16) | |
271 | - assert (__builtin_cpu_supports ("avx512bf16")); | |
272 | - } | |
273 | - | |
274 | - /* Check cpuid level of extended features. */ | |
275 | - __cpuid (0x80000000, ext_level, ebx, ecx, edx); | |
276 | - | |
277 | - if (ext_level >= 0x80000001) | |
278 | - { | |
279 | - __cpuid (0x80000001, eax, ebx, ecx, edx); | |
280 | - | |
281 | - if (ecx & bit_SSE4a) | |
282 | - assert (__builtin_cpu_supports ("sse4a")); | |
283 | - if (ecx & bit_FMA4) | |
284 | - assert (__builtin_cpu_supports ("fma4")); | |
285 | - if (ecx & bit_XOP) | |
286 | - assert (__builtin_cpu_supports ("xop")); | |
287 | - } | |
288 | -} | |
289 | - | |
290 | -static int __attribute__ ((noinline)) | |
291 | -__get_cpuid_output (unsigned int __level, | |
292 | - unsigned int *__eax, unsigned int *__ebx, | |
293 | - unsigned int *__ecx, unsigned int *__edx) | |
294 | -{ | |
295 | - return __get_cpuid (__level, __eax, __ebx, __ecx, __edx); | |
24 | +#define has_feature(f) \ | |
25 | + has_cpu_feature (cpu_model, cpu_features2, f) | |
26 | +#define ISA_NAMES_TABLE_START | |
27 | +#define ISA_NAMES_TABLE_END | |
28 | +#define ISA_NAMES_TABLE_ENTRY(name, feature, priority, option) \ | |
29 | + assert (!!has_feature (feature) == !!__builtin_cpu_supports (name)); | |
30 | +#include "../../../common/config/i386/i386-isas.h" | |
296 | 31 | } |
297 | 32 | |
298 | 33 | static int |
299 | 34 | check_detailed () |
300 | 35 | { |
301 | - unsigned int eax, ebx, ecx, edx; | |
302 | - | |
303 | - int max_level; | |
304 | - unsigned int vendor; | |
305 | - unsigned int model, family, brand_id; | |
306 | - unsigned int extended_model, extended_family; | |
307 | - | |
308 | - /* Assume cpuid insn present. Run in level 0 to get vendor id. */ | |
309 | - if (!__get_cpuid_output (0, &eax, &ebx, &ecx, &edx)) | |
310 | - return 0; | |
36 | + struct __processor_model cpu_model = { 0 }; | |
37 | + struct __processor_model2 cpu_model2 = { 0 }; | |
38 | + unsigned int cpu_features2[SIZE_OF_CPU_FEATURES] = { 0 }; | |
311 | 39 | |
312 | - vendor = ebx; | |
313 | - max_level = eax; | |
314 | - | |
315 | - if (max_level < 1) | |
316 | - return 0; | |
317 | - | |
318 | - if (!__get_cpuid_output (1, &eax, &ebx, &ecx, &edx)) | |
40 | + if (cpu_indicator_init (&cpu_model, &cpu_model2, cpu_features2) != 0) | |
319 | 41 | return 0; |
320 | 42 | |
321 | - model = (eax >> 4) & 0x0f; | |
322 | - family = (eax >> 8) & 0x0f; | |
323 | - brand_id = ebx & 0xff; | |
324 | - extended_model = (eax >> 12) & 0xf0; | |
325 | - extended_family = (eax >> 20) & 0xff; | |
43 | + check_features (&cpu_model, cpu_features2); | |
326 | 44 | |
327 | - if (vendor == signature_INTEL_ebx) | |
45 | + switch (cpu_model.__cpu_vendor) | |
328 | 46 | { |
47 | + case VENDOR_INTEL: | |
329 | 48 | assert (__builtin_cpu_is ("intel")); |
330 | - /* Adjust family and model for Intel CPUs. */ | |
331 | - if (family == 0x0f) | |
332 | - { | |
333 | - family += extended_family; | |
334 | - model += extended_model; | |
335 | - } | |
336 | - else if (family == 0x06) | |
337 | - model += extended_model; | |
338 | - check_intel_cpu_model (family, model, brand_id); | |
339 | - check_features (ecx, edx, max_level); | |
340 | - } | |
341 | - else if (vendor == signature_AMD_ebx) | |
342 | - { | |
49 | + get_intel_cpu (&cpu_model, &cpu_model2, cpu_features2, 0); | |
50 | + break; | |
51 | + case VENDOR_AMD: | |
343 | 52 | assert (__builtin_cpu_is ("amd")); |
344 | - /* Adjust model and family for AMD CPUS. */ | |
345 | - if (family == 0x0f) | |
346 | - { | |
347 | - family += extended_family; | |
348 | - model += (extended_model << 4); | |
349 | - } | |
350 | - check_amd_cpu_model (family, model); | |
351 | - check_features (ecx, edx, max_level); | |
53 | + get_amd_cpu (&cpu_model, &cpu_model2, cpu_features2); | |
54 | + break; | |
55 | + default: | |
56 | + break; | |
352 | 57 | } |
353 | 58 | |
354 | 59 | return 0; |