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.
This commit is contained in:
parent
acba4660b4
commit
6c35d16a39
163
gcc/common/config/i386/i386-isas.h
Normal file
163
gcc/common/config/i386/i386-isas.h
Normal file
@ -0,0 +1,163 @@
|
||||
/* i386 ISA table.
|
||||
Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GCC.
|
||||
|
||||
GCC is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
GCC is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GCC; see the file COPYING3. If not see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* These are the target attribute strings for which a dispatcher is
|
||||
available, from fold_builtin_cpu. */
|
||||
struct _isa_names_table
|
||||
{
|
||||
const char *const name;
|
||||
const enum processor_features feature;
|
||||
const enum feature_priority priority;
|
||||
const char *const option;
|
||||
};
|
||||
|
||||
/* NB: isa_names_table is shared by i386-builtins.c, driver-i386.c and
|
||||
gcc.target/i386/builtin_target.c. isa_names_table is a static const
|
||||
array in i386-builtins.c and driver-i386.c. But it is a list of
|
||||
assert statements in gcc.target/i386/builtin_target.c. */
|
||||
|
||||
#ifndef ISA_NAMES_TABLE_START
|
||||
# define ISA_NAMES_TABLE_START \
|
||||
static const struct _isa_names_table isa_names_table[] = {
|
||||
#endif
|
||||
|
||||
#ifndef ISA_NAMES_TABLE_END
|
||||
# define ISA_NAMES_TABLE_END };
|
||||
#endif
|
||||
|
||||
#ifndef ISA_NAMES_TABLE_ENTRY
|
||||
# define ISA_NAMES_TABLE_ENTRY(name, feature, priority, option) \
|
||||
{name, feature, priority, option},
|
||||
#endif
|
||||
|
||||
ISA_NAMES_TABLE_START
|
||||
ISA_NAMES_TABLE_ENTRY("cmov", FEATURE_CMOV, P_NONE, NULL)
|
||||
ISA_NAMES_TABLE_ENTRY("mmx", FEATURE_MMX, P_MMX, "-mmmx")
|
||||
ISA_NAMES_TABLE_ENTRY("popcnt", FEATURE_POPCNT, P_POPCNT, "-mpopcnt")
|
||||
ISA_NAMES_TABLE_ENTRY("sse", FEATURE_SSE, P_SSE, "-msse")
|
||||
ISA_NAMES_TABLE_ENTRY("sse2", FEATURE_SSE2, P_SSE2, "-msse2")
|
||||
ISA_NAMES_TABLE_ENTRY("sse3", FEATURE_SSE3, P_SSE3, "-msse3")
|
||||
ISA_NAMES_TABLE_ENTRY("ssse3", FEATURE_SSSE3, P_SSSE3, "-mssse3")
|
||||
ISA_NAMES_TABLE_ENTRY("sse4.1", FEATURE_SSE4_1, P_SSE4_1, "-msse4.1")
|
||||
ISA_NAMES_TABLE_ENTRY("sse4.2", FEATURE_SSE4_2, P_SSE4_2, "-msse4.2")
|
||||
ISA_NAMES_TABLE_ENTRY("avx", FEATURE_AVX, P_AVX, "-mavx")
|
||||
ISA_NAMES_TABLE_ENTRY("avx2", FEATURE_AVX2, P_AVX2, "-mavx2")
|
||||
ISA_NAMES_TABLE_ENTRY("sse4a", FEATURE_SSE4_A, P_SSE4_A, "-msse4a")
|
||||
ISA_NAMES_TABLE_ENTRY("fma4", FEATURE_FMA4, P_FMA4, "-mfma4")
|
||||
ISA_NAMES_TABLE_ENTRY("xop", FEATURE_XOP, P_XOP, "-mxop")
|
||||
ISA_NAMES_TABLE_ENTRY("fma", FEATURE_FMA, P_FMA, "-mfma")
|
||||
ISA_NAMES_TABLE_ENTRY("avx512f", FEATURE_AVX512F, P_AVX512F,
|
||||
"-mavx512f")
|
||||
ISA_NAMES_TABLE_ENTRY("bmi", FEATURE_BMI, P_BMI, "-mbmi")
|
||||
ISA_NAMES_TABLE_ENTRY("bmi2", FEATURE_BMI2, P_BMI2, "-mbmi2")
|
||||
ISA_NAMES_TABLE_ENTRY("aes", FEATURE_AES, P_AES, "-maes")
|
||||
ISA_NAMES_TABLE_ENTRY("pclmul", FEATURE_PCLMUL, P_PCLMUL, "-mpclmul")
|
||||
ISA_NAMES_TABLE_ENTRY("avx512vl", FEATURE_AVX512VL, P_NONE,
|
||||
"-mavx512vl")
|
||||
ISA_NAMES_TABLE_ENTRY("avx512bw", FEATURE_AVX512BW, P_NONE,
|
||||
"-mavx512bw")
|
||||
ISA_NAMES_TABLE_ENTRY("avx512dq", FEATURE_AVX512DQ, P_NONE,
|
||||
"-mavx512dq")
|
||||
ISA_NAMES_TABLE_ENTRY("avx512cd", FEATURE_AVX512CD, P_NONE,
|
||||
"-mavx512cd")
|
||||
ISA_NAMES_TABLE_ENTRY("avx512er", FEATURE_AVX512ER, P_NONE,
|
||||
"-mavx512er")
|
||||
ISA_NAMES_TABLE_ENTRY("avx512pf", FEATURE_AVX512PF, P_NONE,
|
||||
"-mavx512pf")
|
||||
ISA_NAMES_TABLE_ENTRY("avx512vbmi", FEATURE_AVX512VBMI, P_NONE,
|
||||
"-mavx512vbmi")
|
||||
ISA_NAMES_TABLE_ENTRY("avx512ifma", FEATURE_AVX512IFMA, P_NONE,
|
||||
"-mavx512ifma")
|
||||
ISA_NAMES_TABLE_ENTRY("avx5124vnniw", FEATURE_AVX5124VNNIW, P_NONE,
|
||||
"-mavx5124vnniw")
|
||||
ISA_NAMES_TABLE_ENTRY("avx5124fmaps", FEATURE_AVX5124FMAPS, P_NONE,
|
||||
"-mavx5124fmaps")
|
||||
ISA_NAMES_TABLE_ENTRY("avx512vpopcntdq", FEATURE_AVX512VPOPCNTDQ,
|
||||
P_NONE, "-mavx512vpopcntdq")
|
||||
ISA_NAMES_TABLE_ENTRY("avx512vbmi2", FEATURE_AVX512VBMI2, P_NONE,
|
||||
"-mavx512vbmi2")
|
||||
ISA_NAMES_TABLE_ENTRY("gfni", FEATURE_GFNI, P_NONE, "-mgfni")
|
||||
ISA_NAMES_TABLE_ENTRY("vpclmulqdq", FEATURE_VPCLMULQDQ, P_NONE,
|
||||
"-mvpclmulqdq")
|
||||
ISA_NAMES_TABLE_ENTRY("avx512vnni", FEATURE_AVX512VNNI, P_NONE,
|
||||
"-mavx512vnni")
|
||||
ISA_NAMES_TABLE_ENTRY("avx512bitalg", FEATURE_AVX512BITALG, P_NONE,
|
||||
"-mavx512bitalg")
|
||||
ISA_NAMES_TABLE_ENTRY("avx512bf16", FEATURE_AVX512BF16, P_NONE,
|
||||
"-mavx512bf16")
|
||||
ISA_NAMES_TABLE_ENTRY("avx512vp2intersect", FEATURE_AVX512VP2INTERSECT,
|
||||
P_NONE, "-mavx512vp2intersect")
|
||||
ISA_NAMES_TABLE_ENTRY("3dnow", FEATURE_3DNOW, P_NONE, "-m3dnow")
|
||||
ISA_NAMES_TABLE_ENTRY("3dnowp", FEATURE_3DNOWP, P_NONE, NULL)
|
||||
ISA_NAMES_TABLE_ENTRY("adx", FEATURE_ADX, P_NONE, "-madx")
|
||||
ISA_NAMES_TABLE_ENTRY("abm", FEATURE_ABM, P_NONE, "-mabm")
|
||||
ISA_NAMES_TABLE_ENTRY("cldemote", FEATURE_CLDEMOTE, P_NONE,
|
||||
"-mcldemote")
|
||||
ISA_NAMES_TABLE_ENTRY("clflushopt", FEATURE_CLFLUSHOPT, P_NONE,
|
||||
"-mclflushopt")
|
||||
ISA_NAMES_TABLE_ENTRY("clwb", FEATURE_CLWB, P_NONE, "-mclwb")
|
||||
ISA_NAMES_TABLE_ENTRY("clzero", FEATURE_CLZERO, P_NONE, "-mclzero")
|
||||
ISA_NAMES_TABLE_ENTRY("cmpxchg16b", FEATURE_CMPXCHG16B, P_NONE,
|
||||
"-mcx16")
|
||||
ISA_NAMES_TABLE_ENTRY("cmpxchg8b", FEATURE_CMPXCHG8B, P_NONE, NULL)
|
||||
ISA_NAMES_TABLE_ENTRY("enqcmd", FEATURE_ENQCMD, P_NONE, "-menqcmd")
|
||||
ISA_NAMES_TABLE_ENTRY("f16c", FEATURE_F16C, P_NONE, "-mf16c")
|
||||
ISA_NAMES_TABLE_ENTRY("fsgsbase", FEATURE_FSGSBASE, P_NONE,
|
||||
"-mfsgsbase")
|
||||
ISA_NAMES_TABLE_ENTRY("fxsave", FEATURE_FXSAVE, P_NONE, "-mfxsr")
|
||||
ISA_NAMES_TABLE_ENTRY("hle", FEATURE_HLE, P_NONE, "-mhle")
|
||||
ISA_NAMES_TABLE_ENTRY("ibt", FEATURE_IBT, P_NONE, NULL)
|
||||
ISA_NAMES_TABLE_ENTRY("lahf_lm", FEATURE_LAHF_LM, P_NONE, "-msahf")
|
||||
ISA_NAMES_TABLE_ENTRY("lm", FEATURE_LM, P_NONE, NULL)
|
||||
ISA_NAMES_TABLE_ENTRY("lwp", FEATURE_LWP, P_NONE, "-mlwp")
|
||||
ISA_NAMES_TABLE_ENTRY("lzcnt", FEATURE_LZCNT, P_NONE, "-mlzcnt")
|
||||
ISA_NAMES_TABLE_ENTRY("movbe", FEATURE_MOVBE, P_NONE, "-mmovbe")
|
||||
ISA_NAMES_TABLE_ENTRY("movdir64b", FEATURE_MOVDIR64B, P_NONE,
|
||||
"-mmovdir64b")
|
||||
ISA_NAMES_TABLE_ENTRY("movdiri", FEATURE_MOVDIRI, P_NONE, "-mmovdiri")
|
||||
ISA_NAMES_TABLE_ENTRY("mwaitx", FEATURE_MWAITX, P_NONE, "-mmwaitx")
|
||||
ISA_NAMES_TABLE_ENTRY("osxsave", FEATURE_OSXSAVE, P_NONE, NULL)
|
||||
ISA_NAMES_TABLE_ENTRY("pconfig", FEATURE_PCONFIG, P_NONE, "-mpconfig")
|
||||
ISA_NAMES_TABLE_ENTRY("pku", FEATURE_PKU, P_NONE, "-mpku")
|
||||
ISA_NAMES_TABLE_ENTRY("prefetchwt1", FEATURE_PREFETCHWT1, P_NONE,
|
||||
"-mprefetchwt1")
|
||||
ISA_NAMES_TABLE_ENTRY("prfchw", FEATURE_PRFCHW, P_NONE, "-mprfchw")
|
||||
ISA_NAMES_TABLE_ENTRY("ptwrite", FEATURE_PTWRITE, P_NONE, "-mptwrite")
|
||||
ISA_NAMES_TABLE_ENTRY("rdpid", FEATURE_RDPID, P_NONE, "-mrdpid")
|
||||
ISA_NAMES_TABLE_ENTRY("rdrnd", FEATURE_RDRND, P_NONE, "-mrdrnd")
|
||||
ISA_NAMES_TABLE_ENTRY("rdseed", FEATURE_RDSEED, P_NONE, "-mrdseed")
|
||||
ISA_NAMES_TABLE_ENTRY("rtm", FEATURE_RTM, P_NONE, "-mrtm")
|
||||
ISA_NAMES_TABLE_ENTRY("serialize", FEATURE_SERIALIZE, P_NONE,
|
||||
"-mserialize")
|
||||
ISA_NAMES_TABLE_ENTRY("sgx", FEATURE_SGX, P_NONE, "-msgx")
|
||||
ISA_NAMES_TABLE_ENTRY("sha", FEATURE_SHA, P_NONE, "-msha")
|
||||
ISA_NAMES_TABLE_ENTRY("shstk", FEATURE_SHSTK, P_NONE, "-mshstk")
|
||||
ISA_NAMES_TABLE_ENTRY("tbm", FEATURE_TBM, P_NONE, "-mtbm")
|
||||
ISA_NAMES_TABLE_ENTRY("tsxldtrk", FEATURE_TSXLDTRK, P_NONE,
|
||||
"-mtsxldtrk")
|
||||
ISA_NAMES_TABLE_ENTRY("vaes", FEATURE_VAES, P_NONE, "-mvaes")
|
||||
ISA_NAMES_TABLE_ENTRY("waitpkg", FEATURE_WAITPKG, P_NONE, "-mwaitpkg")
|
||||
ISA_NAMES_TABLE_ENTRY("wbnoinvd", FEATURE_WBNOINVD, P_NONE,
|
||||
"-mwbnoinvd")
|
||||
ISA_NAMES_TABLE_ENTRY("xsave", FEATURE_XSAVE, P_NONE, "-mxsave")
|
||||
ISA_NAMES_TABLE_ENTRY("xsavec", FEATURE_XSAVEC, P_NONE, "-mxsavec")
|
||||
ISA_NAMES_TABLE_ENTRY("xsaveopt", FEATURE_XSAVEOPT, P_NONE,
|
||||
"-mxsaveopt")
|
||||
ISA_NAMES_TABLE_ENTRY("xsaves", FEATURE_XSAVES, P_NONE, "-mxsaves")
|
||||
ISA_NAMES_TABLE_END
|
@ -28,6 +28,8 @@ const char *host_detect_local_cpu (int argc, const char **argv);
|
||||
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 5 || !defined(__PIC__))
|
||||
#include "cpuid.h"
|
||||
#include "common/config/i386/cpuinfo.h"
|
||||
#include "common/config/i386/i386-isas.h"
|
||||
|
||||
struct cache_desc
|
||||
{
|
||||
@ -388,53 +390,13 @@ const char *host_detect_local_cpu (int argc, const char **argv)
|
||||
const char *cache = "";
|
||||
const char *options = "";
|
||||
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
unsigned int ebx, ecx, edx;
|
||||
|
||||
unsigned int max_level, ext_level;
|
||||
|
||||
unsigned int vendor;
|
||||
unsigned int model, family;
|
||||
|
||||
unsigned int has_sse3, has_ssse3, has_cmpxchg16b;
|
||||
unsigned int has_cmpxchg8b, has_cmov, has_mmx, has_sse, has_sse2;
|
||||
|
||||
/* Extended features */
|
||||
unsigned int has_lahf_lm = 0, has_sse4a = 0;
|
||||
unsigned int has_longmode = 0, has_3dnowp = 0, has_3dnow = 0;
|
||||
unsigned int has_movbe = 0, has_sse4_1 = 0, has_sse4_2 = 0;
|
||||
unsigned int has_popcnt = 0, has_aes = 0, has_avx = 0, has_avx2 = 0;
|
||||
unsigned int has_pclmul = 0, has_abm = 0, has_lwp = 0;
|
||||
unsigned int has_fma = 0, has_fma4 = 0, has_xop = 0;
|
||||
unsigned int has_bmi = 0, has_bmi2 = 0, has_tbm = 0, has_lzcnt = 0;
|
||||
unsigned int has_hle = 0, has_rtm = 0, has_sgx = 0;
|
||||
unsigned int has_pconfig = 0, has_wbnoinvd = 0;
|
||||
unsigned int has_rdrnd = 0, has_f16c = 0, has_fsgsbase = 0;
|
||||
unsigned int has_rdseed = 0, has_prfchw = 0, has_adx = 0;
|
||||
unsigned int has_osxsave = 0, has_fxsr = 0, has_xsave = 0, has_xsaveopt = 0;
|
||||
unsigned int has_avx512er = 0, has_avx512pf = 0, has_avx512cd = 0;
|
||||
unsigned int has_avx512f = 0, has_sha = 0, has_prefetchwt1 = 0;
|
||||
unsigned int has_clflushopt = 0, has_xsavec = 0, has_xsaves = 0;
|
||||
unsigned int has_avx512dq = 0, has_avx512bw = 0, has_avx512vl = 0;
|
||||
unsigned int has_avx512vbmi = 0, has_avx512ifma = 0, has_clwb = 0;
|
||||
unsigned int has_mwaitx = 0, has_clzero = 0, has_pku = 0, has_rdpid = 0;
|
||||
unsigned int has_avx5124fmaps = 0, has_avx5124vnniw = 0;
|
||||
unsigned int has_gfni = 0, has_avx512vbmi2 = 0;
|
||||
unsigned int has_avx512bitalg = 0;
|
||||
unsigned int has_avx512vpopcntdq = 0;
|
||||
unsigned int has_shstk = 0;
|
||||
unsigned int has_avx512vnni = 0, has_vaes = 0;
|
||||
unsigned int has_vpclmulqdq = 0;
|
||||
unsigned int has_avx512vp2intersect = 0;
|
||||
unsigned int has_movdiri = 0, has_movdir64b = 0;
|
||||
unsigned int has_enqcmd = 0;
|
||||
unsigned int has_waitpkg = 0;
|
||||
unsigned int has_cldemote = 0;
|
||||
unsigned int has_avx512bf16 = 0;
|
||||
unsigned int has_serialize = 0;
|
||||
unsigned int has_tsxldtrk = 0;
|
||||
|
||||
unsigned int has_ptwrite = 0;
|
||||
|
||||
bool arch;
|
||||
|
||||
unsigned int l2sizekb = 0;
|
||||
@ -447,210 +409,27 @@ const char *host_detect_local_cpu (int argc, const char **argv)
|
||||
if (!arch && strcmp (argv[0], "tune"))
|
||||
return NULL;
|
||||
|
||||
max_level = __get_cpuid_max (0, &vendor);
|
||||
if (max_level < 1)
|
||||
struct __processor_model cpu_model = { };
|
||||
struct __processor_model2 cpu_model2 = { };
|
||||
unsigned int cpu_features2[SIZE_OF_CPU_FEATURES] = { };
|
||||
|
||||
if (cpu_indicator_init (&cpu_model, &cpu_model2, cpu_features2) != 0)
|
||||
goto done;
|
||||
|
||||
__cpuid (1, eax, ebx, ecx, edx);
|
||||
|
||||
model = (eax >> 4) & 0x0f;
|
||||
family = (eax >> 8) & 0x0f;
|
||||
if (vendor == signature_INTEL_ebx
|
||||
|| vendor == signature_AMD_ebx)
|
||||
{
|
||||
unsigned int extended_model, extended_family;
|
||||
|
||||
extended_model = (eax >> 12) & 0xf0;
|
||||
extended_family = (eax >> 20) & 0xff;
|
||||
if (family == 0x0f)
|
||||
{
|
||||
family += extended_family;
|
||||
model += extended_model;
|
||||
}
|
||||
else if (family == 0x06)
|
||||
model += extended_model;
|
||||
}
|
||||
|
||||
has_sse3 = ecx & bit_SSE3;
|
||||
has_ssse3 = ecx & bit_SSSE3;
|
||||
has_sse4_1 = ecx & bit_SSE4_1;
|
||||
has_sse4_2 = ecx & bit_SSE4_2;
|
||||
has_avx = ecx & bit_AVX;
|
||||
has_osxsave = ecx & bit_OSXSAVE;
|
||||
has_cmpxchg16b = ecx & bit_CMPXCHG16B;
|
||||
has_movbe = ecx & bit_MOVBE;
|
||||
has_popcnt = ecx & bit_POPCNT;
|
||||
has_aes = ecx & bit_AES;
|
||||
has_pclmul = ecx & bit_PCLMUL;
|
||||
has_fma = ecx & bit_FMA;
|
||||
has_f16c = ecx & bit_F16C;
|
||||
has_rdrnd = ecx & bit_RDRND;
|
||||
has_xsave = ecx & bit_XSAVE;
|
||||
|
||||
has_cmpxchg8b = edx & bit_CMPXCHG8B;
|
||||
has_cmov = edx & bit_CMOV;
|
||||
has_mmx = edx & bit_MMX;
|
||||
has_fxsr = edx & bit_FXSAVE;
|
||||
has_sse = edx & bit_SSE;
|
||||
has_sse2 = edx & bit_SSE2;
|
||||
|
||||
if (max_level >= 7)
|
||||
{
|
||||
__cpuid_count (7, 0, eax, ebx, ecx, edx);
|
||||
|
||||
has_bmi = ebx & bit_BMI;
|
||||
has_sgx = ebx & bit_SGX;
|
||||
has_hle = ebx & bit_HLE;
|
||||
has_rtm = ebx & bit_RTM;
|
||||
has_avx2 = ebx & bit_AVX2;
|
||||
has_bmi2 = ebx & bit_BMI2;
|
||||
has_fsgsbase = ebx & bit_FSGSBASE;
|
||||
has_rdseed = ebx & bit_RDSEED;
|
||||
has_adx = ebx & bit_ADX;
|
||||
has_avx512f = ebx & bit_AVX512F;
|
||||
has_avx512er = ebx & bit_AVX512ER;
|
||||
has_avx512pf = ebx & bit_AVX512PF;
|
||||
has_avx512cd = ebx & bit_AVX512CD;
|
||||
has_sha = ebx & bit_SHA;
|
||||
has_clflushopt = ebx & bit_CLFLUSHOPT;
|
||||
has_clwb = ebx & bit_CLWB;
|
||||
has_avx512dq = ebx & bit_AVX512DQ;
|
||||
has_avx512bw = ebx & bit_AVX512BW;
|
||||
has_avx512vl = ebx & bit_AVX512VL;
|
||||
has_avx512ifma = ebx & bit_AVX512IFMA;
|
||||
|
||||
has_prefetchwt1 = ecx & bit_PREFETCHWT1;
|
||||
has_avx512vbmi = ecx & bit_AVX512VBMI;
|
||||
has_pku = ecx & bit_OSPKE;
|
||||
has_avx512vbmi2 = ecx & bit_AVX512VBMI2;
|
||||
has_avx512vnni = ecx & bit_AVX512VNNI;
|
||||
has_rdpid = ecx & bit_RDPID;
|
||||
has_gfni = ecx & bit_GFNI;
|
||||
has_vaes = ecx & bit_VAES;
|
||||
has_vpclmulqdq = ecx & bit_VPCLMULQDQ;
|
||||
has_avx512bitalg = ecx & bit_AVX512BITALG;
|
||||
has_avx512vpopcntdq = ecx & bit_AVX512VPOPCNTDQ;
|
||||
has_movdiri = ecx & bit_MOVDIRI;
|
||||
has_movdir64b = ecx & bit_MOVDIR64B;
|
||||
has_enqcmd = ecx & bit_ENQCMD;
|
||||
has_cldemote = ecx & bit_CLDEMOTE;
|
||||
|
||||
has_avx5124vnniw = edx & bit_AVX5124VNNIW;
|
||||
has_avx5124fmaps = edx & bit_AVX5124FMAPS;
|
||||
has_avx512vp2intersect = edx & bit_AVX512VP2INTERSECT;
|
||||
has_serialize = edx & bit_SERIALIZE;
|
||||
has_tsxldtrk = edx & bit_TSXLDTRK;
|
||||
|
||||
has_shstk = ecx & bit_SHSTK;
|
||||
has_pconfig = edx & bit_PCONFIG;
|
||||
has_waitpkg = ecx & bit_WAITPKG;
|
||||
|
||||
__cpuid_count (7, 1, eax, ebx, ecx, edx);
|
||||
has_avx512bf16 = eax & bit_AVX512BF16;
|
||||
}
|
||||
|
||||
if (max_level >= 13)
|
||||
{
|
||||
__cpuid_count (13, 1, eax, ebx, ecx, edx);
|
||||
|
||||
has_xsaveopt = eax & bit_XSAVEOPT;
|
||||
has_xsavec = eax & bit_XSAVEC;
|
||||
has_xsaves = eax & bit_XSAVES;
|
||||
}
|
||||
|
||||
if (max_level >= 0x14)
|
||||
{
|
||||
__cpuid_count (0x14, 0, eax, ebx, ecx, edx);
|
||||
|
||||
has_ptwrite = ebx & bit_PTWRITE;
|
||||
}
|
||||
|
||||
/* Check cpuid level of extended features. */
|
||||
__cpuid (0x80000000, ext_level, ebx, ecx, edx);
|
||||
|
||||
if (ext_level >= 0x80000001)
|
||||
{
|
||||
__cpuid (0x80000001, eax, ebx, ecx, edx);
|
||||
|
||||
has_lahf_lm = ecx & bit_LAHF_LM;
|
||||
has_sse4a = ecx & bit_SSE4a;
|
||||
has_abm = ecx & bit_ABM;
|
||||
has_lwp = ecx & bit_LWP;
|
||||
has_fma4 = ecx & bit_FMA4;
|
||||
has_xop = ecx & bit_XOP;
|
||||
has_tbm = ecx & bit_TBM;
|
||||
has_lzcnt = ecx & bit_LZCNT;
|
||||
has_prfchw = ecx & bit_PRFCHW;
|
||||
|
||||
has_longmode = edx & bit_LM;
|
||||
has_3dnowp = edx & bit_3DNOWP;
|
||||
has_3dnow = edx & bit_3DNOW;
|
||||
has_mwaitx = ecx & bit_MWAITX;
|
||||
}
|
||||
|
||||
if (ext_level >= 0x80000008)
|
||||
{
|
||||
__cpuid (0x80000008, eax, ebx, ecx, edx);
|
||||
has_clzero = ebx & bit_CLZERO;
|
||||
has_wbnoinvd = ebx & bit_WBNOINVD;
|
||||
}
|
||||
|
||||
/* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv. */
|
||||
#define XCR_XFEATURE_ENABLED_MASK 0x0
|
||||
#define XSTATE_FP 0x1
|
||||
#define XSTATE_SSE 0x2
|
||||
#define XSTATE_YMM 0x4
|
||||
#define XSTATE_OPMASK 0x20
|
||||
#define XSTATE_ZMM 0x40
|
||||
#define XSTATE_HI_ZMM 0x80
|
||||
|
||||
#define XCR_AVX_ENABLED_MASK \
|
||||
(XSTATE_SSE | XSTATE_YMM)
|
||||
#define XCR_AVX512F_ENABLED_MASK \
|
||||
(XSTATE_SSE | XSTATE_YMM | XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM)
|
||||
|
||||
if (has_osxsave)
|
||||
asm (".byte 0x0f; .byte 0x01; .byte 0xd0"
|
||||
: "=a" (eax), "=d" (edx)
|
||||
: "c" (XCR_XFEATURE_ENABLED_MASK));
|
||||
else
|
||||
eax = 0;
|
||||
|
||||
/* Check if AVX registers are supported. */
|
||||
if ((eax & XCR_AVX_ENABLED_MASK) != XCR_AVX_ENABLED_MASK)
|
||||
{
|
||||
has_avx = 0;
|
||||
has_avx2 = 0;
|
||||
has_fma = 0;
|
||||
has_fma4 = 0;
|
||||
has_f16c = 0;
|
||||
has_xop = 0;
|
||||
has_xsave = 0;
|
||||
has_xsaveopt = 0;
|
||||
has_xsaves = 0;
|
||||
has_xsavec = 0;
|
||||
}
|
||||
|
||||
/* Check if AVX512F registers are supported. */
|
||||
if ((eax & XCR_AVX512F_ENABLED_MASK) != XCR_AVX512F_ENABLED_MASK)
|
||||
{
|
||||
has_avx512f = 0;
|
||||
has_avx512er = 0;
|
||||
has_avx512pf = 0;
|
||||
has_avx512cd = 0;
|
||||
has_avx512dq = 0;
|
||||
has_avx512bw = 0;
|
||||
has_avx512vl = 0;
|
||||
}
|
||||
vendor = cpu_model.__cpu_vendor;
|
||||
family = cpu_model2.__cpu_family;
|
||||
model = cpu_model2.__cpu_model;
|
||||
max_level = cpu_model2.__cpu_max_level;
|
||||
ext_level = cpu_model2.__cpu_ext_level;
|
||||
|
||||
if (!arch)
|
||||
{
|
||||
if (vendor == signature_AMD_ebx
|
||||
|| vendor == signature_CENTAUR_ebx
|
||||
|| vendor == signature_CYRIX_ebx
|
||||
|| vendor == signature_NSC_ebx)
|
||||
if (vendor == VENDOR_AMD
|
||||
|| vendor == VENDOR_CENTAUR
|
||||
|| vendor == VENDOR_CYRIX
|
||||
|| vendor == VENDOR_NSC)
|
||||
cache = detect_caches_amd (ext_level);
|
||||
else if (vendor == signature_INTEL_ebx)
|
||||
else if (vendor == VENDOR_INTEL)
|
||||
{
|
||||
bool xeon_mp = (family == 15 && model == 6);
|
||||
cache = detect_caches_intel (xeon_mp, max_level,
|
||||
@ -658,7 +437,11 @@ const char *host_detect_local_cpu (int argc, const char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (vendor == signature_AMD_ebx)
|
||||
/* Extended features */
|
||||
#define has_feature(f) \
|
||||
has_cpu_feature (&cpu_model, cpu_features2, f)
|
||||
|
||||
if (vendor == VENDOR_AMD)
|
||||
{
|
||||
unsigned int name;
|
||||
|
||||
@ -670,34 +453,36 @@ const char *host_detect_local_cpu (int argc, const char **argv)
|
||||
|
||||
if (name == signature_NSC_ebx)
|
||||
processor = PROCESSOR_GEODE;
|
||||
else if (has_movbe && family == 22)
|
||||
else if (has_feature (FEATURE_MOVBE) && family == 22)
|
||||
processor = PROCESSOR_BTVER2;
|
||||
else if (has_clwb)
|
||||
else if (has_feature (FEATURE_CLWB))
|
||||
processor = PROCESSOR_ZNVER2;
|
||||
else if (has_clzero)
|
||||
else if (has_feature (FEATURE_CLZERO))
|
||||
processor = PROCESSOR_ZNVER1;
|
||||
else if (has_avx2)
|
||||
processor = PROCESSOR_BDVER4;
|
||||
else if (has_xsaveopt)
|
||||
processor = PROCESSOR_BDVER3;
|
||||
else if (has_bmi)
|
||||
processor = PROCESSOR_BDVER2;
|
||||
else if (has_xop)
|
||||
else if (has_feature (FEATURE_AVX2))
|
||||
processor = PROCESSOR_BDVER4;
|
||||
else if (has_feature (FEATURE_XSAVEOPT))
|
||||
processor = PROCESSOR_BDVER3;
|
||||
else if (has_feature (FEATURE_BMI))
|
||||
processor = PROCESSOR_BDVER2;
|
||||
else if (has_feature (FEATURE_XOP))
|
||||
processor = PROCESSOR_BDVER1;
|
||||
else if (has_sse4a && has_ssse3)
|
||||
processor = PROCESSOR_BTVER1;
|
||||
else if (has_sse4a)
|
||||
else if (has_feature (FEATURE_SSE4_A)
|
||||
&& has_feature (FEATURE_SSSE3))
|
||||
processor = PROCESSOR_BTVER1;
|
||||
else if (has_feature (FEATURE_SSE4_A))
|
||||
processor = PROCESSOR_AMDFAM10;
|
||||
else if (has_sse2 || has_longmode)
|
||||
else if (has_feature (FEATURE_SSE2)
|
||||
|| has_feature (FEATURE_LM))
|
||||
processor = PROCESSOR_K8;
|
||||
else if (has_3dnowp && family == 6)
|
||||
else if (has_feature (FEATURE_3DNOWP) && family == 6)
|
||||
processor = PROCESSOR_ATHLON;
|
||||
else if (has_mmx)
|
||||
else if (has_feature (FEATURE_MMX))
|
||||
processor = PROCESSOR_K6;
|
||||
else
|
||||
processor = PROCESSOR_PENTIUM;
|
||||
}
|
||||
else if (vendor == signature_CENTAUR_ebx)
|
||||
else if (vendor == VENDOR_CENTAUR)
|
||||
{
|
||||
processor = PROCESSOR_GENERIC;
|
||||
|
||||
@ -708,12 +493,13 @@ const char *host_detect_local_cpu (int argc, const char **argv)
|
||||
break;
|
||||
|
||||
case 5:
|
||||
if (has_3dnow || has_mmx)
|
||||
if (has_feature (FEATURE_3DNOW)
|
||||
|| has_feature (FEATURE_MMX))
|
||||
processor = PROCESSOR_I486;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
if (has_longmode)
|
||||
if (has_feature (FEATURE_LM))
|
||||
processor = PROCESSOR_K8;
|
||||
else if (model >= 9)
|
||||
processor = PROCESSOR_PENTIUMPRO;
|
||||
@ -749,11 +535,11 @@ const char *host_detect_local_cpu (int argc, const char **argv)
|
||||
/* Default. */
|
||||
break;
|
||||
case PROCESSOR_I486:
|
||||
if (arch && vendor == signature_CENTAUR_ebx)
|
||||
if (arch && vendor == VENDOR_CENTAUR)
|
||||
{
|
||||
if (model >= 6)
|
||||
cpu = "c3";
|
||||
else if (has_3dnow)
|
||||
else if (has_feature (FEATURE_3DNOW))
|
||||
cpu = "winchip2";
|
||||
else
|
||||
/* Assume WinChip C6. */
|
||||
@ -763,226 +549,104 @@ const char *host_detect_local_cpu (int argc, const char **argv)
|
||||
cpu = "i486";
|
||||
break;
|
||||
case PROCESSOR_PENTIUM:
|
||||
if (arch && has_mmx)
|
||||
if (arch && has_feature (FEATURE_MMX))
|
||||
cpu = "pentium-mmx";
|
||||
else
|
||||
cpu = "pentium";
|
||||
break;
|
||||
case PROCESSOR_PENTIUMPRO:
|
||||
switch (model)
|
||||
cpu = get_intel_cpu (&cpu_model, &cpu_model2, cpu_features2, 0);
|
||||
if (cpu == NULL)
|
||||
{
|
||||
case 0x1c:
|
||||
case 0x26:
|
||||
/* Bonnell. */
|
||||
cpu = "bonnell";
|
||||
break;
|
||||
case 0x37:
|
||||
case 0x4a:
|
||||
case 0x4d:
|
||||
case 0x5d:
|
||||
/* Silvermont. */
|
||||
case 0x4c:
|
||||
case 0x5a:
|
||||
case 0x75:
|
||||
/* Airmont. */
|
||||
cpu = "silvermont";
|
||||
break;
|
||||
case 0x5c:
|
||||
case 0x5f:
|
||||
/* Goldmont. */
|
||||
cpu = "goldmont";
|
||||
break;
|
||||
case 0x7a:
|
||||
/* Goldmont Plus. */
|
||||
cpu = "goldmont-plus";
|
||||
break;
|
||||
case 0x86:
|
||||
case 0x96:
|
||||
case 0x9c:
|
||||
/* Tremont. */
|
||||
cpu = "tremont";
|
||||
break;
|
||||
case 0x0f:
|
||||
/* Merom. */
|
||||
case 0x17:
|
||||
case 0x1d:
|
||||
/* Penryn. */
|
||||
cpu = "core2";
|
||||
break;
|
||||
case 0x1a:
|
||||
case 0x1e:
|
||||
case 0x1f:
|
||||
case 0x2e:
|
||||
/* Nehalem. */
|
||||
cpu = "nehalem";
|
||||
break;
|
||||
case 0x25:
|
||||
case 0x2c:
|
||||
case 0x2f:
|
||||
/* Westmere. */
|
||||
cpu = "westmere";
|
||||
break;
|
||||
case 0x2a:
|
||||
case 0x2d:
|
||||
/* Sandy Bridge. */
|
||||
cpu = "sandybridge";
|
||||
break;
|
||||
case 0x3a:
|
||||
case 0x3e:
|
||||
/* Ivy Bridge. */
|
||||
cpu = "ivybridge";
|
||||
break;
|
||||
case 0x3c:
|
||||
case 0x3f:
|
||||
case 0x45:
|
||||
case 0x46:
|
||||
/* Haswell. */
|
||||
cpu = "haswell";
|
||||
break;
|
||||
case 0x3d:
|
||||
case 0x47:
|
||||
case 0x4f:
|
||||
case 0x56:
|
||||
/* Broadwell. */
|
||||
cpu = "broadwell";
|
||||
break;
|
||||
case 0x4e:
|
||||
case 0x5e:
|
||||
/* Skylake. */
|
||||
case 0x8e:
|
||||
case 0x9e:
|
||||
/* Kaby Lake. */
|
||||
case 0xa5:
|
||||
case 0xa6:
|
||||
/* Comet Lake. */
|
||||
cpu = "skylake";
|
||||
break;
|
||||
case 0x55:
|
||||
if (has_avx512vnni)
|
||||
/* Cascade Lake. */
|
||||
cpu = "cascadelake";
|
||||
else
|
||||
/* Skylake with AVX-512. */
|
||||
cpu = "skylake-avx512";
|
||||
break;
|
||||
case 0x6a:
|
||||
case 0x6c:
|
||||
/* Ice Lake server. */
|
||||
cpu = "icelake-server";
|
||||
break;
|
||||
case 0x7e:
|
||||
case 0x7d:
|
||||
case 0x9d:
|
||||
/* Ice Lake client. */
|
||||
cpu = "icelake-client";
|
||||
break;
|
||||
case 0x8c:
|
||||
case 0x8d:
|
||||
/* Tiger Lake. */
|
||||
cpu = "tigerlake";
|
||||
break;
|
||||
case 0x57:
|
||||
/* Knights Landing. */
|
||||
cpu = "knl";
|
||||
break;
|
||||
case 0x66:
|
||||
/* Cannon Lake. */
|
||||
cpu = "cannonlake";
|
||||
break;
|
||||
case 0x85:
|
||||
/* Knights Mill. */
|
||||
cpu = "knm";
|
||||
break;
|
||||
default:
|
||||
if (arch)
|
||||
{
|
||||
/* This is unknown family 0x6 CPU. */
|
||||
if (has_avx)
|
||||
{
|
||||
/* Assume Tiger Lake */
|
||||
if (has_avx512vp2intersect)
|
||||
cpu = "tigerlake";
|
||||
/* Assume Cooper Lake */
|
||||
else if (has_avx512bf16)
|
||||
cpu = "cooperlake";
|
||||
/* Assume Ice Lake Server. */
|
||||
else if (has_wbnoinvd)
|
||||
cpu = "icelake-server";
|
||||
if (has_feature (FEATURE_AVX))
|
||||
{
|
||||
/* Assume Tiger Lake */
|
||||
if (has_feature (FEATURE_AVX512VP2INTERSECT))
|
||||
cpu = "tigerlake";
|
||||
/* Assume Cooper Lake */
|
||||
else if (has_feature (FEATURE_AVX512BF16))
|
||||
cpu = "cooperlake";
|
||||
/* Assume Ice Lake Server. */
|
||||
else if (has_feature (FEATURE_WBNOINVD))
|
||||
cpu = "icelake-server";
|
||||
/* Assume Ice Lake. */
|
||||
else if (has_avx512bitalg)
|
||||
else if (has_feature (FEATURE_AVX512BITALG))
|
||||
cpu = "icelake-client";
|
||||
/* Assume Cannon Lake. */
|
||||
else if (has_avx512vbmi)
|
||||
else if (has_feature (FEATURE_AVX512VBMI))
|
||||
cpu = "cannonlake";
|
||||
/* Assume Knights Mill. */
|
||||
else if (has_avx5124vnniw)
|
||||
else if (has_feature (FEATURE_AVX5124VNNIW))
|
||||
cpu = "knm";
|
||||
/* Assume Knights Landing. */
|
||||
else if (has_avx512er)
|
||||
else if (has_feature (FEATURE_AVX512ER))
|
||||
cpu = "knl";
|
||||
/* Assume Skylake with AVX-512. */
|
||||
else if (has_avx512f)
|
||||
else if (has_feature (FEATURE_AVX512F))
|
||||
cpu = "skylake-avx512";
|
||||
/* Assume Skylake. */
|
||||
else if (has_clflushopt)
|
||||
else if (has_feature (FEATURE_CLFLUSHOPT))
|
||||
cpu = "skylake";
|
||||
/* Assume Broadwell. */
|
||||
else if (has_adx)
|
||||
else if (has_feature (FEATURE_ADX))
|
||||
cpu = "broadwell";
|
||||
else if (has_avx2)
|
||||
else if (has_feature (FEATURE_AVX2))
|
||||
/* Assume Haswell. */
|
||||
cpu = "haswell";
|
||||
else
|
||||
/* Assume Sandy Bridge. */
|
||||
cpu = "sandybridge";
|
||||
}
|
||||
else if (has_sse4_2)
|
||||
else if (has_feature (FEATURE_SSE4_2))
|
||||
{
|
||||
if (has_gfni)
|
||||
if (has_feature (FEATURE_GFNI))
|
||||
/* Assume Tremont. */
|
||||
cpu = "tremont";
|
||||
else if (has_sgx)
|
||||
else if (has_feature (FEATURE_SGX))
|
||||
/* Assume Goldmont Plus. */
|
||||
cpu = "goldmont-plus";
|
||||
else if (has_xsave)
|
||||
else if (has_feature (FEATURE_XSAVE))
|
||||
/* Assume Goldmont. */
|
||||
cpu = "goldmont";
|
||||
else if (has_movbe)
|
||||
else if (has_feature (FEATURE_MOVBE))
|
||||
/* Assume Silvermont. */
|
||||
cpu = "silvermont";
|
||||
else
|
||||
/* Assume Nehalem. */
|
||||
cpu = "nehalem";
|
||||
}
|
||||
else if (has_ssse3)
|
||||
else if (has_feature (FEATURE_SSSE3))
|
||||
{
|
||||
if (has_movbe)
|
||||
if (has_feature (FEATURE_MOVBE))
|
||||
/* Assume Bonnell. */
|
||||
cpu = "bonnell";
|
||||
else
|
||||
/* Assume Core 2. */
|
||||
cpu = "core2";
|
||||
}
|
||||
else if (has_longmode)
|
||||
else if (has_feature (FEATURE_LM))
|
||||
/* Perhaps some emulator? Assume x86-64, otherwise gcc
|
||||
-march=native would be unusable for 64-bit compilations,
|
||||
as all the CPUs below are 32-bit only. */
|
||||
cpu = "x86-64";
|
||||
else if (has_sse3)
|
||||
else if (has_feature (FEATURE_SSE3))
|
||||
{
|
||||
if (vendor == signature_CENTAUR_ebx)
|
||||
if (vendor == VENDOR_CENTAUR)
|
||||
/* C7 / Eden "Esther" */
|
||||
cpu = "c7";
|
||||
else
|
||||
/* It is Core Duo. */
|
||||
cpu = "pentium-m";
|
||||
}
|
||||
else if (has_sse2)
|
||||
else if (has_feature (FEATURE_SSE2))
|
||||
/* It is Pentium M. */
|
||||
cpu = "pentium-m";
|
||||
else if (has_sse)
|
||||
else if (has_feature (FEATURE_SSE))
|
||||
{
|
||||
if (vendor == signature_CENTAUR_ebx)
|
||||
if (vendor == VENDOR_CENTAUR)
|
||||
{
|
||||
if (model >= 9)
|
||||
/* Eden "Nehemiah" */
|
||||
@ -994,7 +658,7 @@ const char *host_detect_local_cpu (int argc, const char **argv)
|
||||
/* It is Pentium III. */
|
||||
cpu = "pentium3";
|
||||
}
|
||||
else if (has_mmx)
|
||||
else if (has_feature (FEATURE_MMX))
|
||||
/* It is Pentium II. */
|
||||
cpu = "pentium2";
|
||||
else
|
||||
@ -1004,13 +668,12 @@ const char *host_detect_local_cpu (int argc, const char **argv)
|
||||
else
|
||||
/* For -mtune, we default to -mtune=generic. */
|
||||
cpu = "generic";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PROCESSOR_PENTIUM4:
|
||||
if (has_sse3)
|
||||
if (has_feature (FEATURE_SSE3))
|
||||
{
|
||||
if (has_longmode)
|
||||
if (has_feature (FEATURE_LM))
|
||||
cpu = "nocona";
|
||||
else
|
||||
cpu = "prescott";
|
||||
@ -1022,13 +685,13 @@ const char *host_detect_local_cpu (int argc, const char **argv)
|
||||
cpu = "geode";
|
||||
break;
|
||||
case PROCESSOR_K6:
|
||||
if (arch && has_3dnow)
|
||||
if (arch && has_feature (FEATURE_3DNOW))
|
||||
cpu = "k6-3";
|
||||
else
|
||||
cpu = "k6";
|
||||
break;
|
||||
case PROCESSOR_ATHLON:
|
||||
if (arch && has_sse)
|
||||
if (arch && has_feature (FEATURE_SSE))
|
||||
cpu = "athlon-4";
|
||||
else
|
||||
cpu = "athlon";
|
||||
@ -1036,22 +699,22 @@ const char *host_detect_local_cpu (int argc, const char **argv)
|
||||
case PROCESSOR_K8:
|
||||
if (arch)
|
||||
{
|
||||
if (vendor == signature_CENTAUR_ebx)
|
||||
if (vendor == VENDOR_CENTAUR)
|
||||
{
|
||||
if (has_sse4_1)
|
||||
if (has_feature (FEATURE_SSE4_1))
|
||||
/* Nano 3000 | Nano dual / quad core | Eden X4 */
|
||||
cpu = "nano-3000";
|
||||
else if (has_ssse3)
|
||||
else if (has_feature (FEATURE_SSSE3))
|
||||
/* Nano 1000 | Nano 2000 */
|
||||
cpu = "nano";
|
||||
else if (has_sse3)
|
||||
else if (has_feature (FEATURE_SSE3))
|
||||
/* Eden X2 */
|
||||
cpu = "eden-x2";
|
||||
else
|
||||
/* Default to k8 */
|
||||
cpu = "k8";
|
||||
}
|
||||
else if (has_sse3)
|
||||
else if (has_feature (FEATURE_SSE3))
|
||||
cpu = "k8-sse3";
|
||||
else
|
||||
cpu = "k8";
|
||||
@ -1092,27 +755,27 @@ const char *host_detect_local_cpu (int argc, const char **argv)
|
||||
/* Use something reasonable. */
|
||||
if (arch)
|
||||
{
|
||||
if (has_ssse3)
|
||||
if (has_feature (FEATURE_SSSE3))
|
||||
cpu = "core2";
|
||||
else if (has_sse3)
|
||||
else if (has_feature (FEATURE_SSE3))
|
||||
{
|
||||
if (has_longmode)
|
||||
if (has_feature (FEATURE_LM))
|
||||
cpu = "nocona";
|
||||
else
|
||||
cpu = "prescott";
|
||||
}
|
||||
else if (has_longmode)
|
||||
else if (has_feature (FEATURE_LM))
|
||||
/* Perhaps some emulator? Assume x86-64, otherwise gcc
|
||||
-march=native would be unusable for 64-bit compilations,
|
||||
as all the CPUs below are 32-bit only. */
|
||||
cpu = "x86-64";
|
||||
else if (has_sse2)
|
||||
else if (has_feature (FEATURE_SSE2))
|
||||
cpu = "pentium4";
|
||||
else if (has_cmov)
|
||||
else if (has_feature (FEATURE_CMOV))
|
||||
cpu = "pentiumpro";
|
||||
else if (has_mmx)
|
||||
else if (has_feature (FEATURE_MMX))
|
||||
cpu = "pentium-mmx";
|
||||
else if (has_cmpxchg8b)
|
||||
else if (has_feature (FEATURE_CMPXCHG8B))
|
||||
cpu = "pentium";
|
||||
}
|
||||
else
|
||||
@ -1121,101 +784,18 @@ const char *host_detect_local_cpu (int argc, const char **argv)
|
||||
|
||||
if (arch)
|
||||
{
|
||||
const char *mmx = has_mmx ? " -mmmx" : " -mno-mmx";
|
||||
const char *mmx3dnow = has_3dnow ? " -m3dnow" : " -mno-3dnow";
|
||||
const char *sse = has_sse ? " -msse" : " -mno-sse";
|
||||
const char *sse2 = has_sse2 ? " -msse2" : " -mno-sse2";
|
||||
const char *sse3 = has_sse3 ? " -msse3" : " -mno-sse3";
|
||||
const char *ssse3 = has_ssse3 ? " -mssse3" : " -mno-ssse3";
|
||||
const char *sse4a = has_sse4a ? " -msse4a" : " -mno-sse4a";
|
||||
const char *cx16 = has_cmpxchg16b ? " -mcx16" : " -mno-cx16";
|
||||
const char *sahf = has_lahf_lm ? " -msahf" : " -mno-sahf";
|
||||
const char *movbe = has_movbe ? " -mmovbe" : " -mno-movbe";
|
||||
const char *aes = has_aes ? " -maes" : " -mno-aes";
|
||||
const char *sha = has_sha ? " -msha" : " -mno-sha";
|
||||
const char *pclmul = has_pclmul ? " -mpclmul" : " -mno-pclmul";
|
||||
const char *popcnt = has_popcnt ? " -mpopcnt" : " -mno-popcnt";
|
||||
const char *abm = has_abm ? " -mabm" : " -mno-abm";
|
||||
const char *lwp = has_lwp ? " -mlwp" : " -mno-lwp";
|
||||
const char *fma = has_fma ? " -mfma" : " -mno-fma";
|
||||
const char *fma4 = has_fma4 ? " -mfma4" : " -mno-fma4";
|
||||
const char *xop = has_xop ? " -mxop" : " -mno-xop";
|
||||
const char *bmi = has_bmi ? " -mbmi" : " -mno-bmi";
|
||||
const char *pconfig = has_pconfig ? " -mpconfig" : " -mno-pconfig";
|
||||
const char *wbnoinvd = has_wbnoinvd ? " -mwbnoinvd" : " -mno-wbnoinvd";
|
||||
const char *sgx = has_sgx ? " -msgx" : " -mno-sgx";
|
||||
const char *bmi2 = has_bmi2 ? " -mbmi2" : " -mno-bmi2";
|
||||
const char *tbm = has_tbm ? " -mtbm" : " -mno-tbm";
|
||||
const char *avx = has_avx ? " -mavx" : " -mno-avx";
|
||||
const char *avx2 = has_avx2 ? " -mavx2" : " -mno-avx2";
|
||||
const char *sse4_2 = has_sse4_2 ? " -msse4.2" : " -mno-sse4.2";
|
||||
const char *sse4_1 = has_sse4_1 ? " -msse4.1" : " -mno-sse4.1";
|
||||
const char *lzcnt = has_lzcnt ? " -mlzcnt" : " -mno-lzcnt";
|
||||
const char *hle = has_hle ? " -mhle" : " -mno-hle";
|
||||
const char *rtm = has_rtm ? " -mrtm" : " -mno-rtm";
|
||||
const char *rdrnd = has_rdrnd ? " -mrdrnd" : " -mno-rdrnd";
|
||||
const char *f16c = has_f16c ? " -mf16c" : " -mno-f16c";
|
||||
const char *fsgsbase = has_fsgsbase ? " -mfsgsbase" : " -mno-fsgsbase";
|
||||
const char *rdseed = has_rdseed ? " -mrdseed" : " -mno-rdseed";
|
||||
const char *prfchw = has_prfchw ? " -mprfchw" : " -mno-prfchw";
|
||||
const char *adx = has_adx ? " -madx" : " -mno-adx";
|
||||
const char *fxsr = has_fxsr ? " -mfxsr" : " -mno-fxsr";
|
||||
const char *xsave = has_xsave ? " -mxsave" : " -mno-xsave";
|
||||
const char *xsaveopt = has_xsaveopt ? " -mxsaveopt" : " -mno-xsaveopt";
|
||||
const char *avx512f = has_avx512f ? " -mavx512f" : " -mno-avx512f";
|
||||
const char *avx512er = has_avx512er ? " -mavx512er" : " -mno-avx512er";
|
||||
const char *avx512cd = has_avx512cd ? " -mavx512cd" : " -mno-avx512cd";
|
||||
const char *avx512pf = has_avx512pf ? " -mavx512pf" : " -mno-avx512pf";
|
||||
const char *prefetchwt1 = has_prefetchwt1 ? " -mprefetchwt1" : " -mno-prefetchwt1";
|
||||
const char *clflushopt = has_clflushopt ? " -mclflushopt" : " -mno-clflushopt";
|
||||
const char *xsavec = has_xsavec ? " -mxsavec" : " -mno-xsavec";
|
||||
const char *xsaves = has_xsaves ? " -mxsaves" : " -mno-xsaves";
|
||||
const char *avx512dq = has_avx512dq ? " -mavx512dq" : " -mno-avx512dq";
|
||||
const char *avx512bw = has_avx512bw ? " -mavx512bw" : " -mno-avx512bw";
|
||||
const char *avx512vl = has_avx512vl ? " -mavx512vl" : " -mno-avx512vl";
|
||||
const char *avx512ifma = has_avx512ifma ? " -mavx512ifma" : " -mno-avx512ifma";
|
||||
const char *avx512vbmi = has_avx512vbmi ? " -mavx512vbmi" : " -mno-avx512vbmi";
|
||||
const char *avx5124vnniw = has_avx5124vnniw ? " -mavx5124vnniw" : " -mno-avx5124vnniw";
|
||||
const char *avx512vbmi2 = has_avx512vbmi2 ? " -mavx512vbmi2" : " -mno-avx512vbmi2";
|
||||
const char *avx512vnni = has_avx512vnni ? " -mavx512vnni" : " -mno-avx512vnni";
|
||||
const char *avx5124fmaps = has_avx5124fmaps ? " -mavx5124fmaps" : " -mno-avx5124fmaps";
|
||||
const char *clwb = has_clwb ? " -mclwb" : " -mno-clwb";
|
||||
const char *mwaitx = has_mwaitx ? " -mmwaitx" : " -mno-mwaitx";
|
||||
const char *clzero = has_clzero ? " -mclzero" : " -mno-clzero";
|
||||
const char *pku = has_pku ? " -mpku" : " -mno-pku";
|
||||
const char *rdpid = has_rdpid ? " -mrdpid" : " -mno-rdpid";
|
||||
const char *gfni = has_gfni ? " -mgfni" : " -mno-gfni";
|
||||
const char *shstk = has_shstk ? " -mshstk" : " -mno-shstk";
|
||||
const char *vaes = has_vaes ? " -mvaes" : " -mno-vaes";
|
||||
const char *vpclmulqdq = has_vpclmulqdq ? " -mvpclmulqdq" : " -mno-vpclmulqdq";
|
||||
const char *avx512vp2intersect = has_avx512vp2intersect ? " -mavx512vp2intersect" : " -mno-avx512vp2intersect";
|
||||
const char *tsxldtrk = has_tsxldtrk ? " -mtsxldtrk " : " -mno-tsxldtrk";
|
||||
const char *avx512bitalg = has_avx512bitalg ? " -mavx512bitalg" : " -mno-avx512bitalg";
|
||||
const char *avx512vpopcntdq = has_avx512vpopcntdq ? " -mavx512vpopcntdq" : " -mno-avx512vpopcntdq";
|
||||
const char *movdiri = has_movdiri ? " -mmovdiri" : " -mno-movdiri";
|
||||
const char *movdir64b = has_movdir64b ? " -mmovdir64b" : " -mno-movdir64b";
|
||||
const char *enqcmd = has_enqcmd ? " -menqcmd" : " -mno-enqcmd";
|
||||
const char *waitpkg = has_waitpkg ? " -mwaitpkg" : " -mno-waitpkg";
|
||||
const char *cldemote = has_cldemote ? " -mcldemote" : " -mno-cldemote";
|
||||
const char *serialize = has_serialize ? " -mserialize" : " -mno-serialize";
|
||||
const char *ptwrite = has_ptwrite ? " -mptwrite" : " -mno-ptwrite";
|
||||
const char *avx512bf16 = has_avx512bf16 ? " -mavx512bf16" : " -mno-avx512bf16";
|
||||
|
||||
options = concat (options, mmx, mmx3dnow, sse, sse2, sse3, ssse3,
|
||||
sse4a, cx16, sahf, movbe, aes, sha, pclmul,
|
||||
popcnt, abm, lwp, fma, fma4, xop, bmi, sgx, bmi2,
|
||||
pconfig, wbnoinvd,
|
||||
tbm, avx, avx2, sse4_2, sse4_1, lzcnt, rtm,
|
||||
hle, rdrnd, f16c, fsgsbase, rdseed, prfchw, adx,
|
||||
fxsr, xsave, xsaveopt, avx512f, avx512er,
|
||||
avx512cd, avx512pf, prefetchwt1, clflushopt,
|
||||
xsavec, xsaves, avx512dq, avx512bw, avx512vl,
|
||||
avx512ifma, avx512vbmi, avx5124fmaps, avx5124vnniw,
|
||||
clwb, mwaitx, clzero, pku, rdpid, gfni, shstk,
|
||||
avx512vbmi2, avx512vnni, vaes, vpclmulqdq,
|
||||
avx512bitalg, avx512vpopcntdq, movdiri, movdir64b,
|
||||
waitpkg, cldemote, ptwrite, avx512bf16, enqcmd,
|
||||
avx512vp2intersect, serialize, tsxldtrk, NULL);
|
||||
unsigned int i;
|
||||
const char *const neg_option = " -mno-";
|
||||
for (i = 0; i < ARRAY_SIZE (isa_names_table); i++)
|
||||
if (isa_names_table[i].option)
|
||||
{
|
||||
if (has_feature (isa_names_table[i].feature))
|
||||
options = concat (options, " ",
|
||||
isa_names_table[i].option, NULL);
|
||||
else
|
||||
options = concat (options, neg_option,
|
||||
isa_names_table[i].option + 2, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
@ -90,6 +90,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "debug.h"
|
||||
#include "dwarf2out.h"
|
||||
#include "i386-builtins.h"
|
||||
#include "common/config/i386/i386-isas.h"
|
||||
|
||||
#undef BDESC
|
||||
#undef BDESC_FIRST
|
||||
@ -1835,57 +1836,6 @@ ix86_builtin_reciprocal (tree fndecl)
|
||||
}
|
||||
}
|
||||
|
||||
/* These are the target attribute strings for which a dispatcher is
|
||||
available, from fold_builtin_cpu. */
|
||||
struct _isa_names_table
|
||||
{
|
||||
const char *const name;
|
||||
const enum processor_features feature;
|
||||
const enum feature_priority priority;
|
||||
};
|
||||
|
||||
static const _isa_names_table isa_names_table[] =
|
||||
{
|
||||
{"cmov", FEATURE_CMOV, P_NONE},
|
||||
{"mmx", FEATURE_MMX, P_MMX},
|
||||
{"popcnt", FEATURE_POPCNT, P_POPCNT},
|
||||
{"sse", FEATURE_SSE, P_SSE},
|
||||
{"sse2", FEATURE_SSE2, P_SSE2},
|
||||
{"sse3", FEATURE_SSE3, P_SSE3},
|
||||
{"ssse3", FEATURE_SSSE3, P_SSSE3},
|
||||
{"sse4a", FEATURE_SSE4_A, P_SSE4_A},
|
||||
{"sse4.1", FEATURE_SSE4_1, P_SSE4_1},
|
||||
{"sse4.2", FEATURE_SSE4_2, P_SSE4_2},
|
||||
{"avx", FEATURE_AVX, P_AVX},
|
||||
{"fma4", FEATURE_FMA4, P_FMA4},
|
||||
{"xop", FEATURE_XOP, P_XOP},
|
||||
{"fma", FEATURE_FMA, P_FMA},
|
||||
{"avx2", FEATURE_AVX2, P_AVX2},
|
||||
{"avx512f", FEATURE_AVX512F, P_AVX512F},
|
||||
{"bmi", FEATURE_BMI, P_BMI},
|
||||
{"bmi2", FEATURE_BMI2, P_BMI2},
|
||||
{"aes", FEATURE_AES, P_AES},
|
||||
{"pclmul", FEATURE_PCLMUL, P_PCLMUL},
|
||||
{"avx512vl",FEATURE_AVX512VL, P_NONE},
|
||||
{"avx512bw",FEATURE_AVX512BW, P_NONE},
|
||||
{"avx512dq",FEATURE_AVX512DQ, P_NONE},
|
||||
{"avx512cd",FEATURE_AVX512CD, P_NONE},
|
||||
{"avx512er",FEATURE_AVX512ER, P_NONE},
|
||||
{"avx512pf",FEATURE_AVX512PF, P_NONE},
|
||||
{"avx512vbmi",FEATURE_AVX512VBMI, P_NONE},
|
||||
{"avx512ifma",FEATURE_AVX512IFMA, P_NONE},
|
||||
{"avx5124vnniw",FEATURE_AVX5124VNNIW, P_NONE},
|
||||
{"avx5124fmaps",FEATURE_AVX5124FMAPS, P_NONE},
|
||||
{"avx512vpopcntdq",FEATURE_AVX512VPOPCNTDQ, P_NONE},
|
||||
{"avx512vbmi2", FEATURE_AVX512VBMI2, P_NONE},
|
||||
{"gfni", FEATURE_GFNI, P_NONE},
|
||||
{"vpclmulqdq", FEATURE_VPCLMULQDQ, P_NONE},
|
||||
{"avx512vnni", FEATURE_AVX512VNNI, P_NONE},
|
||||
{"avx512bitalg", FEATURE_AVX512BITALG, P_NONE},
|
||||
{"avx512bf16", FEATURE_AVX512BF16, P_NONE},
|
||||
{"avx512vp2intersect",FEATURE_AVX512VP2INTERSECT, P_NONE}
|
||||
};
|
||||
|
||||
/* This parses the attribute arguments to target in DECL and determines
|
||||
the right builtin to use to match the platform specification.
|
||||
It returns the priority value for this version decl. If PREDICATE_LIST
|
||||
|
@ -7,348 +7,53 @@
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include "cpuid.h"
|
||||
|
||||
/* Check if the Intel CPU model and sub-model are identified. */
|
||||
static void
|
||||
check_intel_cpu_model (unsigned int family, unsigned int model,
|
||||
unsigned int brand_id)
|
||||
{
|
||||
/* Parse family and model only if brand ID is 0. */
|
||||
if (brand_id == 0)
|
||||
{
|
||||
switch (family)
|
||||
{
|
||||
case 0x5:
|
||||
/* Pentium. */
|
||||
break;
|
||||
case 0x6:
|
||||
switch (model)
|
||||
{
|
||||
case 0x1c:
|
||||
case 0x26:
|
||||
/* Atom. */
|
||||
assert (__builtin_cpu_is ("atom"));
|
||||
break;
|
||||
case 0x37:
|
||||
case 0x4a:
|
||||
case 0x4d:
|
||||
case 0x5a:
|
||||
case 0x5d:
|
||||
/* Silvermont. */
|
||||
assert (__builtin_cpu_is ("silvermont"));
|
||||
break;
|
||||
case 0x5c:
|
||||
case 0x5f:
|
||||
/* Goldmont. */
|
||||
assert (__builtin_cpu_is ("goldmont"));
|
||||
break;
|
||||
case 0x7a:
|
||||
/* Goldmont Plus. */
|
||||
assert (__builtin_cpu_is ("goldmont-plus"));
|
||||
break;
|
||||
case 0x57:
|
||||
/* Knights Landing. */
|
||||
assert (__builtin_cpu_is ("knl"));
|
||||
break;
|
||||
case 0x85:
|
||||
/* Knights Mill */
|
||||
assert (__builtin_cpu_is ("knm"));
|
||||
break;
|
||||
case 0x1a:
|
||||
case 0x1e:
|
||||
case 0x1f:
|
||||
case 0x2e:
|
||||
/* Nehalem. */
|
||||
assert (__builtin_cpu_is ("corei7"));
|
||||
assert (__builtin_cpu_is ("nehalem"));
|
||||
break;
|
||||
case 0x25:
|
||||
case 0x2c:
|
||||
case 0x2f:
|
||||
/* Westmere. */
|
||||
assert (__builtin_cpu_is ("corei7"));
|
||||
assert (__builtin_cpu_is ("westmere"));
|
||||
break;
|
||||
case 0x2a:
|
||||
case 0x2d:
|
||||
/* Sandy Bridge. */
|
||||
assert (__builtin_cpu_is ("corei7"));
|
||||
assert (__builtin_cpu_is ("sandybridge"));
|
||||
break;
|
||||
case 0x3a:
|
||||
case 0x3e:
|
||||
/* Ivy Bridge. */
|
||||
assert (__builtin_cpu_is ("corei7"));
|
||||
assert (__builtin_cpu_is ("ivybridge"));
|
||||
break;
|
||||
case 0x3c:
|
||||
case 0x3f:
|
||||
case 0x45:
|
||||
case 0x46:
|
||||
/* Haswell. */
|
||||
assert (__builtin_cpu_is ("corei7"));
|
||||
assert (__builtin_cpu_is ("haswell"));
|
||||
break;
|
||||
case 0x3d:
|
||||
case 0x47:
|
||||
case 0x4f:
|
||||
case 0x56:
|
||||
/* Broadwell. */
|
||||
assert (__builtin_cpu_is ("corei7"));
|
||||
assert (__builtin_cpu_is ("broadwell"));
|
||||
break;
|
||||
case 0x4e:
|
||||
case 0x5e:
|
||||
/* Skylake. */
|
||||
case 0x8e:
|
||||
case 0x9e:
|
||||
/* Kaby Lake. */
|
||||
assert (__builtin_cpu_is ("corei7"));
|
||||
assert (__builtin_cpu_is ("skylake"));
|
||||
break;
|
||||
case 0x55:
|
||||
{
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
__cpuid_count (7, 0, eax, ebx, ecx, edx);
|
||||
assert (__builtin_cpu_is ("corei7"));
|
||||
if (ecx & bit_AVX512VNNI)
|
||||
/* Cascade Lake. */
|
||||
assert (__builtin_cpu_is ("cascadelake"));
|
||||
else
|
||||
/* Skylake with AVX-512 support. */
|
||||
assert (__builtin_cpu_is ("skylake-avx512"));
|
||||
break;
|
||||
}
|
||||
case 0x66:
|
||||
/* Cannon Lake. */
|
||||
assert (__builtin_cpu_is ("cannonlake"));
|
||||
break;
|
||||
case 0x17:
|
||||
case 0x1d:
|
||||
/* Penryn. */
|
||||
case 0x0f:
|
||||
/* Merom. */
|
||||
assert (__builtin_cpu_is ("core2"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* We have no idea. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the AMD CPU model and sub-model are identified. */
|
||||
static void
|
||||
check_amd_cpu_model (unsigned int family, unsigned int model)
|
||||
{
|
||||
switch (family)
|
||||
{
|
||||
/* AMD Family 10h. */
|
||||
case 0x10:
|
||||
switch (model)
|
||||
{
|
||||
case 0x2:
|
||||
/* Barcelona. */
|
||||
assert (__builtin_cpu_is ("amdfam10h"));
|
||||
assert (__builtin_cpu_is ("barcelona"));
|
||||
break;
|
||||
case 0x4:
|
||||
/* Shanghai. */
|
||||
assert (__builtin_cpu_is ("amdfam10h"));
|
||||
assert (__builtin_cpu_is ("shanghai"));
|
||||
break;
|
||||
case 0x8:
|
||||
/* Istanbul. */
|
||||
assert (__builtin_cpu_is ("amdfam10h"));
|
||||
assert (__builtin_cpu_is ("istanbul"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
/* AMD Family 15h. */
|
||||
case 0x15:
|
||||
assert (__builtin_cpu_is ("amdfam15h"));
|
||||
/* Bulldozer version 1. */
|
||||
if ( model <= 0xf)
|
||||
assert (__builtin_cpu_is ("bdver1"));
|
||||
/* Bulldozer version 2. */
|
||||
if (model >= 0x10 && model <= 0x1f)
|
||||
assert (__builtin_cpu_is ("bdver2"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#define CHECK___builtin_cpu_is(cpu) assert (__builtin_cpu_is (cpu))
|
||||
#define gcc_assert(a) assert (a)
|
||||
#define gcc_unreachable() abort ()
|
||||
#define inline
|
||||
#include "../../../common/config/i386/i386-cpuinfo.h"
|
||||
#include "../../../common/config/i386/cpuinfo.h"
|
||||
|
||||
/* Check if the ISA features are identified. */
|
||||
static void
|
||||
check_features (unsigned int ecx, unsigned int edx,
|
||||
int max_cpuid_level)
|
||||
check_features (struct __processor_model *cpu_model,
|
||||
unsigned int *cpu_features2)
|
||||
{
|
||||
unsigned int eax, ebx;
|
||||
unsigned int ext_level;
|
||||
|
||||
if (edx & bit_CMOV)
|
||||
assert (__builtin_cpu_supports ("cmov"));
|
||||
if (edx & bit_MMX)
|
||||
assert (__builtin_cpu_supports ("mmx"));
|
||||
if (edx & bit_SSE)
|
||||
assert (__builtin_cpu_supports ("sse"));
|
||||
if (edx & bit_SSE2)
|
||||
assert (__builtin_cpu_supports ("sse2"));
|
||||
if (ecx & bit_POPCNT)
|
||||
assert (__builtin_cpu_supports ("popcnt"));
|
||||
if (ecx & bit_AES)
|
||||
assert (__builtin_cpu_supports ("aes"));
|
||||
if (ecx & bit_PCLMUL)
|
||||
assert (__builtin_cpu_supports ("pclmul"));
|
||||
if (ecx & bit_SSE3)
|
||||
assert (__builtin_cpu_supports ("sse3"));
|
||||
if (ecx & bit_SSSE3)
|
||||
assert (__builtin_cpu_supports ("ssse3"));
|
||||
if (ecx & bit_SSE4_1)
|
||||
assert (__builtin_cpu_supports ("sse4.1"));
|
||||
if (ecx & bit_SSE4_2)
|
||||
assert (__builtin_cpu_supports ("sse4.2"));
|
||||
if (ecx & bit_AVX)
|
||||
assert (__builtin_cpu_supports ("avx"));
|
||||
if (ecx & bit_FMA)
|
||||
assert (__builtin_cpu_supports ("fma"));
|
||||
|
||||
/* Get advanced features at level 7 (eax = 7, ecx = 0). */
|
||||
if (max_cpuid_level >= 7)
|
||||
{
|
||||
__cpuid_count (7, 0, eax, ebx, ecx, edx);
|
||||
if (ebx & bit_BMI)
|
||||
assert (__builtin_cpu_supports ("bmi"));
|
||||
if (ebx & bit_AVX2)
|
||||
assert (__builtin_cpu_supports ("avx2"));
|
||||
if (ebx & bit_BMI2)
|
||||
assert (__builtin_cpu_supports ("bmi2"));
|
||||
if (ebx & bit_AVX512F)
|
||||
assert (__builtin_cpu_supports ("avx512f"));
|
||||
if (ebx & bit_AVX512VL)
|
||||
assert (__builtin_cpu_supports ("avx512vl"));
|
||||
if (ebx & bit_AVX512BW)
|
||||
assert (__builtin_cpu_supports ("avx512bw"));
|
||||
if (ebx & bit_AVX512DQ)
|
||||
assert (__builtin_cpu_supports ("avx512dq"));
|
||||
if (ebx & bit_AVX512CD)
|
||||
assert (__builtin_cpu_supports ("avx512cd"));
|
||||
if (ebx & bit_AVX512PF)
|
||||
assert (__builtin_cpu_supports ("avx512pf"));
|
||||
if (ebx & bit_AVX512ER)
|
||||
assert (__builtin_cpu_supports ("avx512er"));
|
||||
if (ebx & bit_AVX512IFMA)
|
||||
assert (__builtin_cpu_supports ("avx512ifma"));
|
||||
if (ecx & bit_AVX512VBMI)
|
||||
assert (__builtin_cpu_supports ("avx512vbmi"));
|
||||
if (ecx & bit_AVX512VBMI2)
|
||||
assert (__builtin_cpu_supports ("avx512vbmi2"));
|
||||
if (ecx & bit_GFNI)
|
||||
assert (__builtin_cpu_supports ("gfni"));
|
||||
if (ecx & bit_VPCLMULQDQ)
|
||||
assert (__builtin_cpu_supports ("vpclmulqdq"));
|
||||
if (ecx & bit_AVX512VNNI)
|
||||
assert (__builtin_cpu_supports ("avx512vnni"));
|
||||
if (ecx & bit_AVX512BITALG)
|
||||
assert (__builtin_cpu_supports ("avx512bitalg"));
|
||||
if (ecx & bit_AVX512VPOPCNTDQ)
|
||||
assert (__builtin_cpu_supports ("avx512vpopcntdq"));
|
||||
if (edx & bit_AVX5124VNNIW)
|
||||
assert (__builtin_cpu_supports ("avx5124vnniw"));
|
||||
if (edx & bit_AVX5124FMAPS)
|
||||
assert (__builtin_cpu_supports ("avx5124fmaps"));
|
||||
|
||||
__cpuid_count (7, 1, eax, ebx, ecx, edx);
|
||||
if (eax & bit_AVX512BF16)
|
||||
assert (__builtin_cpu_supports ("avx512bf16"));
|
||||
}
|
||||
|
||||
/* Check cpuid level of extended features. */
|
||||
__cpuid (0x80000000, ext_level, ebx, ecx, edx);
|
||||
|
||||
if (ext_level >= 0x80000001)
|
||||
{
|
||||
__cpuid (0x80000001, eax, ebx, ecx, edx);
|
||||
|
||||
if (ecx & bit_SSE4a)
|
||||
assert (__builtin_cpu_supports ("sse4a"));
|
||||
if (ecx & bit_FMA4)
|
||||
assert (__builtin_cpu_supports ("fma4"));
|
||||
if (ecx & bit_XOP)
|
||||
assert (__builtin_cpu_supports ("xop"));
|
||||
}
|
||||
}
|
||||
|
||||
static int __attribute__ ((noinline))
|
||||
__get_cpuid_output (unsigned int __level,
|
||||
unsigned int *__eax, unsigned int *__ebx,
|
||||
unsigned int *__ecx, unsigned int *__edx)
|
||||
{
|
||||
return __get_cpuid (__level, __eax, __ebx, __ecx, __edx);
|
||||
#define has_feature(f) \
|
||||
has_cpu_feature (cpu_model, cpu_features2, f)
|
||||
#define ISA_NAMES_TABLE_START
|
||||
#define ISA_NAMES_TABLE_END
|
||||
#define ISA_NAMES_TABLE_ENTRY(name, feature, priority, option) \
|
||||
assert (!!has_feature (feature) == !!__builtin_cpu_supports (name));
|
||||
#include "../../../common/config/i386/i386-isas.h"
|
||||
}
|
||||
|
||||
static int
|
||||
check_detailed ()
|
||||
{
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
struct __processor_model cpu_model = { 0 };
|
||||
struct __processor_model2 cpu_model2 = { 0 };
|
||||
unsigned int cpu_features2[SIZE_OF_CPU_FEATURES] = { 0 };
|
||||
|
||||
int max_level;
|
||||
unsigned int vendor;
|
||||
unsigned int model, family, brand_id;
|
||||
unsigned int extended_model, extended_family;
|
||||
|
||||
/* Assume cpuid insn present. Run in level 0 to get vendor id. */
|
||||
if (!__get_cpuid_output (0, &eax, &ebx, &ecx, &edx))
|
||||
if (cpu_indicator_init (&cpu_model, &cpu_model2, cpu_features2) != 0)
|
||||
return 0;
|
||||
|
||||
vendor = ebx;
|
||||
max_level = eax;
|
||||
check_features (&cpu_model, cpu_features2);
|
||||
|
||||
if (max_level < 1)
|
||||
return 0;
|
||||
|
||||
if (!__get_cpuid_output (1, &eax, &ebx, &ecx, &edx))
|
||||
return 0;
|
||||
|
||||
model = (eax >> 4) & 0x0f;
|
||||
family = (eax >> 8) & 0x0f;
|
||||
brand_id = ebx & 0xff;
|
||||
extended_model = (eax >> 12) & 0xf0;
|
||||
extended_family = (eax >> 20) & 0xff;
|
||||
|
||||
if (vendor == signature_INTEL_ebx)
|
||||
switch (cpu_model.__cpu_vendor)
|
||||
{
|
||||
case VENDOR_INTEL:
|
||||
assert (__builtin_cpu_is ("intel"));
|
||||
/* Adjust family and model for Intel CPUs. */
|
||||
if (family == 0x0f)
|
||||
{
|
||||
family += extended_family;
|
||||
model += extended_model;
|
||||
}
|
||||
else if (family == 0x06)
|
||||
model += extended_model;
|
||||
check_intel_cpu_model (family, model, brand_id);
|
||||
check_features (ecx, edx, max_level);
|
||||
}
|
||||
else if (vendor == signature_AMD_ebx)
|
||||
{
|
||||
get_intel_cpu (&cpu_model, &cpu_model2, cpu_features2, 0);
|
||||
break;
|
||||
case VENDOR_AMD:
|
||||
assert (__builtin_cpu_is ("amd"));
|
||||
/* Adjust model and family for AMD CPUS. */
|
||||
if (family == 0x0f)
|
||||
{
|
||||
family += extended_family;
|
||||
model += (extended_model << 4);
|
||||
}
|
||||
check_amd_cpu_model (family, model);
|
||||
check_features (ecx, edx, max_level);
|
||||
get_amd_cpu (&cpu_model, &cpu_model2, cpu_features2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user