On Wed, Jun 24, 2020 at 2:27 PM H.J. Lu <hjl.to...@gmail.com> wrote: > > On Mon, Jun 22, 2020 at 04:25:46PM -0700, H.J. Lu wrote: > > On Sun, Jun 21, 2020 at 10:22 AM H.J. Lu <hjl.to...@gmail.com> wrote: > > > > > > On Sun, Jun 21, 2020 at 10:18 AM Uros Bizjak <ubiz...@gmail.com> wrote: > > > > > > > > On Sat, Jun 20, 2020 at 3:40 PM H.J. Lu <hjl.to...@gmail.com> wrote: > > > > > > > > > > > > >> 2) can we automatically deduce option name: > > > > > > > > >> > > > > > > > > >>> + ISA_NAMES_TABLE_ENTRY("rdpid", FEATURE_RDPID, P_ZERO, > > > > > > > > >>> "-mrdpid") > > > > > > > > >>> + ISA_NAMES_TABLE_ENTRY("rdrnd", FEATURE_RDRND, P_ZERO, > > > > > > > > >>> "-mrdrnd") > > > > > > > > >> > > > > > > > > >> I mean "-m" + "rdrnd" == "-mrdrnd" ? > > > > > > > > > > > > > > > > > > The new option field serves 2 purposes: > > > > > > > > > > > > > > > > > > 1. Not all features have a corresponding command-line option > > > > > > > > > > > > > > > > > > ISA_NAMES_TABLE_ENTRY("cmov", FEATURE_CMOV, P_ZERO, NULL) > > > > > > > > > > > > > > > > > > for (i = 0; i < ARRAY_SIZE (isa_names_table); i++) > > > > > > > > > if (isa_names_table[i].option) > > > > > > > > > > > > > > > > > > 2. Some feature has a different name in the command-line > > > > > > > > > option. > > > > > > > > > > > > > > > > > > ISA_NAMES_TABLE_ENTRY("fxsave", FEATURE_FXSAVE, P_ZERO, > > > > > > > > > "-mfxsr") > > > > > > > > > > > > > > > > I noticed that, one can theoretically use "" for an option that > > > > > > > > does not > > > > > > > > have a flag. And NULL for these which have option equal to "-m" > > > > > > > > + name. > > > > > > > > Anyway, that's a nit. > > > > > > > > > > > > > > > > I support the patch! > > > > > > > > Martin > > > > > > > > > > > > > > > > > > > > > > > > > > Here is the updated patch. OK for master? > > > > > > > > > > > > > > > > > > Thanks. > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > PING: > > > > > > > > > > > > > > https://gcc.gnu.org/pipermail/gcc-patches/2020-May/546522.html > > > > > > > > > > > > > > > > > > > PING. > > > > > > > > > > Hi, > > > > > > > > > > We have patches like > > > > > > > > > > https://gcc.gnu.org/pipermail/gcc-bugs/2020-June/705851.html > > > > > > > > > > queued up because of this prerequisite patch. Are there any > > > > > objections > > > > > to this patch? > > > > > > > > Yes, there are my objections. > > > > > > > > As explained before, I support unifying libgcc and core gcc handling, > > > > but _NOT_ unifying with driver-i386.c. Unifying libgcc and core gcc > > > > handling would have benefit to avoid desynchronisation between the two > > > > (which happened multiple times in the past, resulting in various API > > > > issues). OTOH, unifying with driver-i386.c would result in quite messy > > > > approach, because driver-i386 handles more targets beside relatively > > > > recent 64bit Intel and AMD targets, not to mention heuristics to > > > > determine the most appropriate target when standard detection fails > > > > (e.g. emulators). > > > > > > Only the duplicated parts of driver-i386.c should be unified. The only > > > impact > > > should be removing code duplications. If it isn't the case, it is a bug > > > in my > > > implementation. > > > > Here is the updated patch to remove FEATURE_OSPKE and use bit_OSPKE > > for FEATURE_PKU. It uses the same get_amd_cpu and get_intel_cpu in > > libgcc and driver-i386.c: > > a. Detect the processor name for newer Intel and AMD processors. > > Since the older processor names are only supported by driver-i386.c, > > not by libgcc, detection for the older processors remains in > > driver-i386.c. > > b. Detect available ISAs for all Intel and AMD processors. > > > > Here is the updated patch for x86 backend and libgcc. driver-i386.c > is unchanged.
Thanks. We should change driver-i386.c very carefully and in an independent way from this patch. It is a complex and interwoven web of name, model and features check. I propose that we first convert various has_xxx checks to a new interface, in as trivial way as possible. > OK for master? Yes, this part looks OK to me. Thanks, Uros. > > Thannks. > > H.J. > --- > Both x86 backend and libgcc define enum processor_features. libgcc sets > enum processor_feature and x86 backend checks enum processor_feature. > They are very easy out of sync and it has happened multiple times in the > past. > > 1. Move cpuinfo.h from libgcc to common/config/i386 so that we can share > the same enum processor_features in x86 backend and libgcc. > 2. Change __cpu_features2 to an array to support more processor features. > 3. Add more processor features to enum processor_features. > > gcc/ > > PR target/95259 > * common/config/i386/cpuinfo.h: New file. > (__processor_model): Moved from libgcc/config/i386/cpuinfo.h. > (__processor_model2): New. > (CHECK___builtin_cpu_is): New. Defined as empty if not defined. > (has_cpu_feature): New function. > (set_cpu_feature): Likewise. > (get_amd_cpu): Moved from libgcc/config/i386/cpuinfo.c. Use > CHECK___builtin_cpu_is. Return AMD CPU name. > (get_intel_cpu): Moved from libgcc/config/i386/cpuinfo.c. Use > Use CHECK___builtin_cpu_is. Return Intel CPU name. > (get_available_features): Moved from libgcc/config/i386/cpuinfo.c. > Also check FEATURE_3DNOW, FEATURE_3DNOWP, FEATURE_ADX, > FEATURE_ABM, FEATURE_CLDEMOTE, FEATURE_CLFLUSHOPT, FEATURE_CLWB, > FEATURE_CLZERO, FEATURE_CMPXCHG16B, FEATURE_CMPXCHG8B, > FEATURE_ENQCMD, FEATURE_F16C, FEATURE_FSGSBASE, FEATURE_FXSAVE, > FEATURE_HLE, FEATURE_IBT, FEATURE_LAHF_LM, FEATURE_LM, > FEATURE_LWP, FEATURE_LZCNT, FEATURE_MOVBE, FEATURE_MOVDIR64B, > FEATURE_MOVDIRI, FEATURE_MWAITX, FEATURE_OSXSAVE, > FEATURE_PCONFIG, FEATURE_PKU, FEATURE_PREFETCHWT1, FEATURE_PRFCHW, > FEATURE_PTWRITE, FEATURE_RDPID, FEATURE_RDRND, FEATURE_RDSEED, > FEATURE_RTM, FEATURE_SERIALIZE, FEATURE_SGX, FEATURE_SHA, > FEATURE_SHSTK, FEATURE_TBM, FEATURE_TSXLDTRK, FEATURE_VAES, > FEATURE_WAITPKG, FEATURE_WBNOINVD, FEATURE_XSAVE, FEATURE_XSAVEC, > FEATURE_XSAVEOPT and FEATURE_XSAVES > (cpu_indicator_init): Moved from libgcc/config/i386/cpuinfo.c. > Also update cpu_model2. > * common/config/i386/i386-cpuinfo.h (processor_vendor): Add > Add VENDOR_CENTAUR, VENDOR_CYRIX and VENDOR_NSC. > (processor_features): Moved from gcc/config/i386/i386-builtins.c. > Renamed F_XXX to FEATURE_XXX. Add FEATURE_3DNOW, FEATURE_3DNOWP, > FEATURE_ADX, FEATURE_ABM, FEATURE_CLDEMOTE, FEATURE_CLFLUSHOPT, > FEATURE_CLWB, FEATURE_CLZERO, FEATURE_CMPXCHG16B, > FEATURE_CMPXCHG8B, FEATURE_ENQCMD, FEATURE_F16C, > FEATURE_FSGSBASE, FEATURE_FXSAVE, FEATURE_HLE, FEATURE_IBT, > FEATURE_LAHF_LM, FEATURE_LM, FEATURE_LWP, FEATURE_LZCNT, > FEATURE_MOVBE, FEATURE_MOVDIR64B, FEATURE_MOVDIRI, > FEATURE_MWAITX, FEATURE_OSXSAVE, FEATURE_PCONFIG, > FEATURE_PKU, FEATURE_PREFETCHWT1, FEATURE_PRFCHW, > FEATURE_PTWRITE, FEATURE_RDPID, FEATURE_RDRND, FEATURE_RDSEED, > FEATURE_RTM, FEATURE_SERIALIZE, FEATURE_SGX, FEATURE_SHA, > FEATURE_SHSTK, FEATURE_TBM, FEATURE_TSXLDTRK, FEATURE_VAES, > FEATURE_WAITPKG, FEATURE_WBNOINVD, FEATURE_XSAVE, FEATURE_XSAVEC, > FEATURE_XSAVEOPT, FEATURE_XSAVES and CPU_FEATURE_MAX. > (SIZE_OF_CPU_FEATURES): New. > * config/i386/i386-builtins.c (processor_features): Removed. > (isa_names_table): Replace F_XXX with FEATURE_XXX. > (fold_builtin_cpu): Change __cpu_features2 to an array. > > libgcc/ > > PR target/95259 > * config/i386/cpuinfo.c: Don't include "cpuinfo.h". Include > "common/config/i386/i386-cpuinfo.h" and > "common/config/i386/cpuinfo.h". > (__cpu_features2): Changed to array. > (get_amd_cpu): Removed. > (get_intel_cpu): Likewise. > (get_available_features): Likewise. > (__cpu_indicator_init): Call cpu_indicator_init. > * config/i386/cpuinfo.h: Removed. > --- > gcc/common/config/i386/cpuinfo.h | 844 ++++++++++++++++++++++++++ > gcc/common/config/i386/i386-cpuinfo.h | 98 +++ > gcc/config/i386/i386-builtins.c | 147 ++--- > libgcc/config/i386/cpuinfo.c | 465 +------------- > libgcc/config/i386/cpuinfo.h | 136 ----- > 5 files changed, 1009 insertions(+), 681 deletions(-) > create mode 100644 gcc/common/config/i386/cpuinfo.h > delete mode 100644 libgcc/config/i386/cpuinfo.h > > diff --git a/gcc/common/config/i386/cpuinfo.h > b/gcc/common/config/i386/cpuinfo.h > new file mode 100644 > index 00000000000..2d72b3b60fd > --- /dev/null > +++ b/gcc/common/config/i386/cpuinfo.h > @@ -0,0 +1,844 @@ > +/* Get CPU type and Features for x86 processors. > + Copyright (C) 2012-2020 Free Software Foundation, Inc. > + Contributed by Sriraman Tallam (tmsri...@google.com) > + > +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. > + > +Under Section 7 of GPL version 3, you are granted additional > +permissions described in the GCC Runtime Library Exception, version > +3.1, as published by the Free Software Foundation. > + > +You should have received a copy of the GNU General Public License and > +a copy of the GCC Runtime Library Exception along with this program; > +see the files COPYING3 and COPYING.RUNTIME respectively. If not, see > +<http://www.gnu.org/licenses/>. */ > + > +struct __processor_model > +{ > + unsigned int __cpu_vendor; > + unsigned int __cpu_type; > + unsigned int __cpu_subtype; > + /* The first 32 features are stored as bitmasks in __cpu_features. > + The rest of features are stored as bitmasks in a separate array > + of unsigned int. */ > + unsigned int __cpu_features[1]; > +}; > + > +struct __processor_model2 > +{ > + unsigned int __cpu_family; > + unsigned int __cpu_model; > + unsigned int __cpu_max_level; > + unsigned int __cpu_ext_level; > +}; > + > +#ifndef CHECK___builtin_cpu_is > +# define CHECK___builtin_cpu_is(cpu) > +#endif > + > +/* Return non-zero if the processor has feature F. */ > + > +static inline int > +has_cpu_feature (struct __processor_model *cpu_model, > + unsigned int *cpu_features2, > + enum processor_features f) > +{ > + unsigned int i; > + if (f < 32) > + { > + /* The first 32 features. */ > + return cpu_model->__cpu_features[0] & (1U << (f & 31)); > + } > + /* The rest of features. cpu_features2[i] contains features from > + (32 + i * 32) to (31 + 32 + i * 32), inclusively. */ > + for (i = 0; i < SIZE_OF_CPU_FEATURES; i++) > + if (f < (32 + 32 + i * 32)) > + return cpu_features2[i] & (1U << ((f - (32 + i * 32)) & 31)); > + gcc_unreachable (); > +} > + > +static inline void > +set_cpu_feature (struct __processor_model *cpu_model, > + unsigned int *cpu_features2, > + enum processor_features f) > +{ > + unsigned int i; > + if (f < 32) > + { > + /* The first 32 features. */ > + cpu_model->__cpu_features[0] |= (1U << (f & 31)); > + return; > + } > + /* The rest of features. cpu_features2[i] contains features from > + (32 + i * 32) to (31 + 32 + i * 32), inclusively. */ > + for (i = 0; i < SIZE_OF_CPU_FEATURES; i++) > + if (f < (32 + 32 + i * 32)) > + { > + cpu_features2[i] |= (1U << ((f - (32 + i * 32)) & 31)); > + return; > + } > + gcc_unreachable (); > +} > + > +/* Get the specific type of AMD CPU and return AMD CPU name. Return > + NULL for unknown AMD CPU. */ > + > +static inline const char * > +get_amd_cpu (struct __processor_model *cpu_model, > + struct __processor_model2 *cpu_model2, > + unsigned int *cpu_features2) > +{ > + const char *cpu = NULL; > + unsigned int family = cpu_model2->__cpu_family; > + unsigned int model = cpu_model2->__cpu_model; > + > + switch (family) > + { > + case 0x10: > + /* AMD Family 10h. */ > + cpu = "amdfam10"; > + cpu_model->__cpu_type = AMDFAM10H; > + switch (model) > + { > + case 0x2: > + /* Barcelona. */ > + CHECK___builtin_cpu_is ("amdfam10h"); > + CHECK___builtin_cpu_is ("barcelona"); > + cpu_model->__cpu_subtype = AMDFAM10H_BARCELONA; > + break; > + case 0x4: > + /* Shanghai. */ > + CHECK___builtin_cpu_is ("amdfam10h"); > + CHECK___builtin_cpu_is ("shanghai"); > + cpu_model->__cpu_subtype = AMDFAM10H_SHANGHAI; > + break; > + case 0x8: > + /* Istanbul. */ > + CHECK___builtin_cpu_is ("amdfam10h"); > + CHECK___builtin_cpu_is ("istanbul"); > + cpu_model->__cpu_subtype = AMDFAM10H_ISTANBUL; > + break; > + default: > + break; > + } > + break; > + case 0x14: > + /* AMD Family 14h "btver1". */ > + cpu = "btver1"; > + CHECK___builtin_cpu_is ("btver1"); > + cpu_model->__cpu_type = AMD_BTVER1; > + break; > + case 0x15: > + /* AMD Family 15h "Bulldozer". */ > + cpu_model->__cpu_type = AMDFAM15H; > + if (model == 0x2) > + { > + /* Bulldozer version 2 "Piledriver" */ > + cpu = "bdver2"; > + CHECK___builtin_cpu_is ("bdver2"); > + cpu_model->__cpu_subtype = AMDFAM15H_BDVER2; > + } > + else if (model <= 0xf) > + { > + /* Bulldozer version 1. */ > + cpu = "bdver1"; > + CHECK___builtin_cpu_is ("bdver1"); > + cpu_model->__cpu_subtype = AMDFAM15H_BDVER1; > + } > + else if (model <= 0x2f) > + { > + /* Bulldozer version 2 "Piledriver" */ > + cpu = "bdver2"; > + CHECK___builtin_cpu_is ("bdver2"); > + cpu_model->__cpu_subtype = AMDFAM15H_BDVER2; > + } > + else if (model <= 0x4f) > + { > + /* Bulldozer version 3 "Steamroller" */ > + cpu = "bdver3"; > + CHECK___builtin_cpu_is ("bdver3"); > + cpu_model->__cpu_subtype = AMDFAM15H_BDVER3; > + } > + else if (model <= 0x7f) > + { > + /* Bulldozer version 4 "Excavator" */ > + cpu = "bdver4"; > + CHECK___builtin_cpu_is ("bdver4"); > + cpu_model->__cpu_subtype = AMDFAM15H_BDVER4; > + } > + else if (has_cpu_feature (cpu_model, cpu_features2, > + FEATURE_AVX2)) > + { > + cpu = "bdver4"; > + CHECK___builtin_cpu_is ("bdver4"); > + cpu_model->__cpu_subtype = AMDFAM15H_BDVER4; > + } > + else if (has_cpu_feature (cpu_model, cpu_features2, > + FEATURE_XSAVEOPT)) > + { > + cpu = "bdver3"; > + CHECK___builtin_cpu_is ("bdver3"); > + cpu_model->__cpu_subtype = AMDFAM15H_BDVER3; > + } > + else if (has_cpu_feature (cpu_model, cpu_features2, > + FEATURE_BMI)) > + { > + cpu = "bdver2"; > + CHECK___builtin_cpu_is ("bdver2"); > + cpu_model->__cpu_subtype = AMDFAM15H_BDVER2; > + } > + else if (has_cpu_feature (cpu_model, cpu_features2, > + FEATURE_XOP)) > + { > + cpu = "bdver1"; > + CHECK___builtin_cpu_is ("bdver1"); > + cpu_model->__cpu_subtype = AMDFAM15H_BDVER1; > + } > + break; > + case 0x16: > + /* AMD Family 16h "btver2" */ > + cpu = "btver2"; > + CHECK___builtin_cpu_is ("btver2"); > + cpu_model->__cpu_type = AMD_BTVER2; > + break; > + case 0x17: > + cpu_model->__cpu_type = AMDFAM17H; > + if (model <= 0x1f) > + { > + /* AMD family 17h version 1. */ > + cpu = "znver1"; > + CHECK___builtin_cpu_is ("znver1"); > + cpu_model->__cpu_subtype = AMDFAM17H_ZNVER1; > + } > + else if (model >= 0x30) > + { > + cpu = "znver2"; > + CHECK___builtin_cpu_is ("znver2"); > + cpu_model->__cpu_subtype = AMDFAM17H_ZNVER2; > + } > + else if (has_cpu_feature (cpu_model, cpu_features2, > + FEATURE_CLWB)) > + { > + cpu = "znver2"; > + CHECK___builtin_cpu_is ("znver2"); > + cpu_model->__cpu_subtype = AMDFAM17H_ZNVER2; > + } > + else if (has_cpu_feature (cpu_model, cpu_features2, > + FEATURE_CLZERO)) > + { > + cpu = "znver1"; > + CHECK___builtin_cpu_is ("znver1"); > + cpu_model->__cpu_subtype = AMDFAM17H_ZNVER1; > + } > + break; > + default: > + break; > + } > + > + return cpu; > +} > + > +/* Get the specific type of Intel CPU and return Intel CPU name. Return > + NULL for unknown Intel CPU. */ > + > +static inline const char * > +get_intel_cpu (struct __processor_model *cpu_model, > + struct __processor_model2 *cpu_model2, > + unsigned int *cpu_features2, > + unsigned int brand_id) > +{ > + const char *cpu = NULL; > + > + /* Parse family and model only for brand ID 0 and model 6. */ > + if (brand_id != 0 || cpu_model2->__cpu_family != 0x6) > + return cpu; > + > + switch (cpu_model2->__cpu_model) > + { > + case 0x1c: > + case 0x26: > + /* Bonnell. */ > + cpu = "bonnell"; > + CHECK___builtin_cpu_is ("atom"); > + cpu_model->__cpu_type = INTEL_BONNELL; > + break; > + case 0x37: > + case 0x4a: > + case 0x4d: > + case 0x5d: > + /* Silvermont. */ > + case 0x4c: > + case 0x5a: > + case 0x75: > + /* Airmont. */ > + cpu = "silvermont"; > + CHECK___builtin_cpu_is ("silvermont"); > + cpu_model->__cpu_type = INTEL_SILVERMONT; > + break; > + case 0x5c: > + case 0x5f: > + /* Goldmont. */ > + cpu = "goldmont"; > + CHECK___builtin_cpu_is ("goldmont"); > + cpu_model->__cpu_type = INTEL_GOLDMONT; > + break; > + case 0x7a: > + /* Goldmont Plus. */ > + cpu = "goldmont-plus"; > + CHECK___builtin_cpu_is ("goldmont-plus"); > + cpu_model->__cpu_type = INTEL_GOLDMONT_PLUS; > + break; > + case 0x86: > + case 0x96: > + case 0x9c: > + /* Tremont. */ > + cpu = "tremont"; > + CHECK___builtin_cpu_is ("tremont"); > + cpu_model->__cpu_type = INTEL_TREMONT; > + break; > + case 0x57: > + /* Knights Landing. */ > + cpu = "knl"; > + CHECK___builtin_cpu_is ("knl"); > + cpu_model->__cpu_type = INTEL_KNL; > + break; > + case 0x85: > + /* Knights Mill. */ > + cpu = "knm"; > + CHECK___builtin_cpu_is ("knm"); > + cpu_model->__cpu_type = INTEL_KNM; > + break; > + case 0x1a: > + case 0x1e: > + case 0x1f: > + case 0x2e: > + /* Nehalem. */ > + cpu = "nehalem"; > + CHECK___builtin_cpu_is ("corei7"); > + CHECK___builtin_cpu_is ("nehalem"); > + cpu_model->__cpu_type = INTEL_COREI7; > + cpu_model->__cpu_subtype = INTEL_COREI7_NEHALEM; > + break; > + case 0x25: > + case 0x2c: > + case 0x2f: > + /* Westmere. */ > + cpu = "westmere"; > + CHECK___builtin_cpu_is ("corei7"); > + CHECK___builtin_cpu_is ("westmere"); > + cpu_model->__cpu_type = INTEL_COREI7; > + cpu_model->__cpu_subtype = INTEL_COREI7_WESTMERE; > + break; > + case 0x2a: > + case 0x2d: > + /* Sandy Bridge. */ > + cpu = "sandybridge"; > + CHECK___builtin_cpu_is ("corei7"); > + CHECK___builtin_cpu_is ("sandybridge"); > + cpu_model->__cpu_type = INTEL_COREI7; > + cpu_model->__cpu_subtype = INTEL_COREI7_SANDYBRIDGE; > + break; > + case 0x3a: > + case 0x3e: > + /* Ivy Bridge. */ > + cpu = "ivybridge"; > + CHECK___builtin_cpu_is ("corei7"); > + CHECK___builtin_cpu_is ("ivybridge"); > + cpu_model->__cpu_type = INTEL_COREI7; > + cpu_model->__cpu_subtype = INTEL_COREI7_IVYBRIDGE; > + break; > + case 0x3c: > + case 0x3f: > + case 0x45: > + case 0x46: > + /* Haswell. */ > + cpu = "haswell"; > + CHECK___builtin_cpu_is ("corei7"); > + CHECK___builtin_cpu_is ("haswell"); > + cpu_model->__cpu_type = INTEL_COREI7; > + cpu_model->__cpu_subtype = INTEL_COREI7_HASWELL; > + break; > + case 0x3d: > + case 0x47: > + case 0x4f: > + case 0x56: > + /* Broadwell. */ > + cpu = "broadwell"; > + CHECK___builtin_cpu_is ("corei7"); > + CHECK___builtin_cpu_is ("broadwell"); > + cpu_model->__cpu_type = INTEL_COREI7; > + cpu_model->__cpu_subtype = INTEL_COREI7_BROADWELL; > + break; > + case 0x4e: > + case 0x5e: > + /* Skylake. */ > + case 0x8e: > + case 0x9e: > + /* Kaby Lake. */ > + case 0xa5: > + case 0xa6: > + /* Comet Lake. */ > + cpu = "skylake"; > + CHECK___builtin_cpu_is ("corei7"); > + CHECK___builtin_cpu_is ("skylake"); > + cpu_model->__cpu_type = INTEL_COREI7; > + cpu_model->__cpu_subtype = INTEL_COREI7_SKYLAKE; > + break; > + case 0x55: > + CHECK___builtin_cpu_is ("corei7"); > + cpu_model->__cpu_type = INTEL_COREI7; > + if (has_cpu_feature (cpu_model, cpu_features2, > + FEATURE_AVX512VNNI)) > + { > + /* Cascade Lake. */ > + cpu = "cascadelake"; > + CHECK___builtin_cpu_is ("cascadelake"); > + cpu_model->__cpu_subtype = INTEL_COREI7_CASCADELAKE; > + } > + else > + { > + /* Skylake with AVX-512 support. */ > + cpu = "skylake-avx512"; > + CHECK___builtin_cpu_is ("skylake-avx512"); > + cpu_model->__cpu_subtype = INTEL_COREI7_SKYLAKE_AVX512; > + } > + break; > + case 0x66: > + /* Cannon Lake. */ > + cpu = "cannonlake"; > + CHECK___builtin_cpu_is ("corei7"); > + CHECK___builtin_cpu_is ("cannonlake"); > + cpu_model->__cpu_type = INTEL_COREI7; > + cpu_model->__cpu_subtype = INTEL_COREI7_CANNONLAKE; > + break; > + case 0x6a: > + case 0x6c: > + /* Ice Lake server. */ > + cpu = "icelake-server"; > + CHECK___builtin_cpu_is ("corei7"); > + CHECK___builtin_cpu_is ("icelake-server"); > + cpu_model->__cpu_type = INTEL_COREI7; > + cpu_model->__cpu_subtype = INTEL_COREI7_ICELAKE_SERVER; > + break; > + case 0x7e: > + case 0x7d: > + case 0x9d: > + /* Ice Lake client. */ > + cpu = "icelake-client"; > + CHECK___builtin_cpu_is ("corei7"); > + CHECK___builtin_cpu_is ("icelake-client"); > + cpu_model->__cpu_type = INTEL_COREI7; > + cpu_model->__cpu_subtype = INTEL_COREI7_ICELAKE_CLIENT; > + break; > + case 0x8c: > + case 0x8d: > + /* Tiger Lake. */ > + cpu = "tigerlake"; > + CHECK___builtin_cpu_is ("corei7"); > + CHECK___builtin_cpu_is ("tigerlake"); > + cpu_model->__cpu_type = INTEL_COREI7; > + cpu_model->__cpu_subtype = INTEL_COREI7_TIGERLAKE; > + break; > + case 0x17: > + case 0x1d: > + /* Penryn. */ > + case 0x0f: > + /* Merom. */ > + cpu = "core2"; > + CHECK___builtin_cpu_is ("core2"); > + cpu_model->__cpu_type = INTEL_CORE2; > + break; > + default: > + break; > + } > + > + return cpu; > +} > + > +/* ECX and EDX are output of CPUID at level one. */ > +static inline void > +get_available_features (struct __processor_model *cpu_model, > + struct __processor_model2 *cpu_model2, > + unsigned int *cpu_features2, > + unsigned int ecx, unsigned int edx) > +{ > + unsigned int max_cpuid_level = cpu_model2->__cpu_max_level; > + unsigned int eax, ebx; > + unsigned int ext_level; > + > + /* 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) > + > + /* Check if AVX and AVX512 are usable. */ > + int avx_usable = 0; > + int avx512_usable = 0; > + if ((ecx & bit_OSXSAVE)) > + { > + /* Check if XMM, YMM, OPMASK, upper 256 bits of ZMM0-ZMM15 and > + ZMM16-ZMM31 states are supported by OSXSAVE. */ > + unsigned int xcrlow; > + unsigned int xcrhigh; > + __asm__ (".byte 0x0f, 0x01, 0xd0" > + : "=a" (xcrlow), "=d" (xcrhigh) > + : "c" (XCR_XFEATURE_ENABLED_MASK)); > + if ((xcrlow & XCR_AVX_ENABLED_MASK) == XCR_AVX_ENABLED_MASK) > + { > + avx_usable = 1; > + avx512_usable = ((xcrlow & XCR_AVX512F_ENABLED_MASK) > + == XCR_AVX512F_ENABLED_MASK); > + } > + } > + > +#define set_feature(f) \ > + set_cpu_feature (cpu_model, cpu_features2, f) > + > + if (edx & bit_CMOV) > + set_feature (FEATURE_CMOV); > + if (edx & bit_MMX) > + set_feature (FEATURE_MMX); > + if (edx & bit_SSE) > + set_feature (FEATURE_SSE); > + if (edx & bit_SSE2) > + set_feature (FEATURE_SSE2); > + if (edx & bit_CMPXCHG8B) > + set_feature (FEATURE_CMPXCHG8B); > + if (edx & bit_FXSAVE) > + set_feature (FEATURE_FXSAVE); > + > + if (ecx & bit_POPCNT) > + set_feature (FEATURE_POPCNT); > + if (ecx & bit_AES) > + set_feature (FEATURE_AES); > + if (ecx & bit_PCLMUL) > + set_feature (FEATURE_PCLMUL); > + if (ecx & bit_SSE3) > + set_feature (FEATURE_SSE3); > + if (ecx & bit_SSSE3) > + set_feature (FEATURE_SSSE3); > + if (ecx & bit_SSE4_1) > + set_feature (FEATURE_SSE4_1); > + if (ecx & bit_SSE4_2) > + set_feature (FEATURE_SSE4_2); > + if (ecx & bit_OSXSAVE) > + set_feature (FEATURE_OSXSAVE); > + if (ecx & bit_CMPXCHG16B) > + set_feature (FEATURE_CMPXCHG16B); > + if (ecx & bit_MOVBE) > + set_feature (FEATURE_MOVBE); > + if (ecx & bit_AES) > + set_feature (FEATURE_AES); > + if (ecx & bit_F16C) > + set_feature (FEATURE_F16C); > + if (ecx & bit_RDRND) > + set_feature (FEATURE_RDRND); > + if (ecx & bit_XSAVE) > + set_feature (FEATURE_XSAVE); > + if (avx_usable) > + { > + if (ecx & bit_AVX) > + set_feature (FEATURE_AVX); > + if (ecx & bit_FMA) > + set_feature (FEATURE_FMA); > + } > + > + /* Get Advanced Features at level 7 (eax = 7, ecx = 0/1). */ > + if (max_cpuid_level >= 7) > + { > + __cpuid_count (7, 0, eax, ebx, ecx, edx); > + if (ebx & bit_BMI) > + set_feature (FEATURE_BMI); > + if (ebx & bit_SGX) > + set_feature (FEATURE_SGX); > + if (ebx & bit_HLE) > + set_feature (FEATURE_HLE); > + if (ebx & bit_RTM) > + set_feature (FEATURE_RTM); > + if (avx_usable) > + { > + if (ebx & bit_AVX2) > + set_feature (FEATURE_AVX2); > + if (ecx & bit_VPCLMULQDQ) > + set_feature (FEATURE_VPCLMULQDQ); > + } > + if (ebx & bit_BMI2) > + set_feature (FEATURE_BMI2); > + if (ebx & bit_FSGSBASE) > + set_feature (FEATURE_FSGSBASE); > + if (ebx & bit_RDSEED) > + set_feature (FEATURE_RDSEED); > + if (ebx & bit_ADX) > + set_feature (FEATURE_ADX); > + if (ebx & bit_SHA) > + set_feature (FEATURE_SHA); > + if (ebx & bit_CLFLUSHOPT) > + set_feature (FEATURE_CLFLUSHOPT); > + if (ebx & bit_CLWB) > + set_feature (FEATURE_CLWB); > + if (ecx & bit_PREFETCHWT1) > + set_feature (FEATURE_PREFETCHWT1); > + /* NB: bit_OSPKE indicates that OS supports PKU. */ > + if (ecx & bit_OSPKE) > + set_feature (FEATURE_PKU); > + if (ecx & bit_RDPID) > + set_feature (FEATURE_RDPID); > + if (ecx & bit_VAES) > + set_feature (FEATURE_VAES); > + if (ecx & bit_GFNI) > + set_feature (FEATURE_GFNI); > + if (ecx & bit_MOVDIRI) > + set_feature (FEATURE_MOVDIRI); > + if (ecx & bit_MOVDIR64B) > + set_feature (FEATURE_MOVDIR64B); > + if (ecx & bit_ENQCMD) > + set_feature (FEATURE_ENQCMD); > + if (ecx & bit_CLDEMOTE) > + set_feature (FEATURE_CLDEMOTE); > + if (ecx & bit_WAITPKG) > + set_feature (FEATURE_WAITPKG); > + if (ecx & bit_SHSTK) > + set_feature (FEATURE_SHSTK); > + if (edx & bit_SERIALIZE) > + set_feature (FEATURE_SERIALIZE); > + if (edx & bit_TSXLDTRK) > + set_feature (FEATURE_TSXLDTRK); > + if (edx & bit_PCONFIG) > + set_feature (FEATURE_PCONFIG); > + if (edx & bit_IBT) > + set_feature (FEATURE_IBT); > + if (avx512_usable) > + { > + if (ebx & bit_AVX512F) > + set_feature (FEATURE_AVX512F); > + if (ebx & bit_AVX512VL) > + set_feature (FEATURE_AVX512VL); > + if (ebx & bit_AVX512BW) > + set_feature (FEATURE_AVX512BW); > + if (ebx & bit_AVX512DQ) > + set_feature (FEATURE_AVX512DQ); > + if (ebx & bit_AVX512CD) > + set_feature (FEATURE_AVX512CD); > + if (ebx & bit_AVX512PF) > + set_feature (FEATURE_AVX512PF); > + if (ebx & bit_AVX512ER) > + set_feature (FEATURE_AVX512ER); > + if (ebx & bit_AVX512IFMA) > + set_feature (FEATURE_AVX512IFMA); > + if (ecx & bit_AVX512VBMI) > + set_feature (FEATURE_AVX512VBMI); > + if (ecx & bit_AVX512VBMI2) > + set_feature (FEATURE_AVX512VBMI2); > + if (ecx & bit_AVX512VNNI) > + set_feature (FEATURE_AVX512VNNI); > + if (ecx & bit_AVX512BITALG) > + set_feature (FEATURE_AVX512BITALG); > + if (ecx & bit_AVX512VPOPCNTDQ) > + set_feature (FEATURE_AVX512VPOPCNTDQ); > + if (edx & bit_AVX5124VNNIW) > + set_feature (FEATURE_AVX5124VNNIW); > + if (edx & bit_AVX5124FMAPS) > + set_feature (FEATURE_AVX5124FMAPS); > + if (edx & bit_AVX512VP2INTERSECT) > + set_feature (FEATURE_AVX512VP2INTERSECT); > + > + __cpuid_count (7, 1, eax, ebx, ecx, edx); > + if (eax & bit_AVX512BF16) > + set_feature (FEATURE_AVX512BF16); > + } > + } > + > + /* Get Advanced Features at level 0xd (eax = 0xd, ecx = 1). */ > + if (max_cpuid_level >= 0xd) > + { > + __cpuid_count (0xd, 1, eax, ebx, ecx, edx); > + if (eax & bit_XSAVEOPT) > + set_feature (FEATURE_XSAVEOPT); > + if (eax & bit_XSAVEC) > + set_feature (FEATURE_XSAVEC); > + if (eax & bit_XSAVES) > + set_feature (FEATURE_XSAVES); > + } > + > + /* Get Advanced Features at level 0x14 (eax = 0x14, ecx = 0). */ > + if (max_cpuid_level >= 0x14) > + { > + __cpuid_count (0x14, 0, eax, ebx, ecx, edx); > + if (ebx & bit_PTWRITE) > + set_feature (FEATURE_PTWRITE); > + } > + > + /* Check cpuid level of extended features. */ > + __cpuid (0x80000000, ext_level, ebx, ecx, edx); > + > + cpu_model2->__cpu_ext_level = ext_level; > + > + if (ext_level >= 0x80000001) > + { > + __cpuid (0x80000001, eax, ebx, ecx, edx); > + > + if (ecx & bit_SSE4a) > + set_feature (FEATURE_SSE4_A); > + if (ecx & bit_LAHF_LM) > + set_feature (FEATURE_LAHF_LM); > + if (ecx & bit_ABM) > + set_feature (FEATURE_ABM); > + if (ecx & bit_LWP) > + set_feature (FEATURE_LWP); > + if (ecx & bit_TBM) > + set_feature (FEATURE_TBM); > + if (ecx & bit_LZCNT) > + set_feature (FEATURE_LZCNT); > + if (ecx & bit_PRFCHW) > + set_feature (FEATURE_PRFCHW); > + if (ecx & bit_MWAITX) > + set_feature (FEATURE_MWAITX); > + > + if (edx & bit_LM) > + set_feature (FEATURE_LM); > + if (edx & bit_3DNOWP) > + set_feature (FEATURE_3DNOWP); > + if (edx & bit_3DNOW) > + set_feature (FEATURE_3DNOW); > + > + if (avx_usable) > + { > + if (ecx & bit_FMA4) > + set_feature (FEATURE_FMA4); > + if (ecx & bit_XOP) > + set_feature (FEATURE_XOP); > + } > + } > + > + if (ext_level >= 0x80000008) > + { > + __cpuid (0x80000008, eax, ebx, ecx, edx); > + if (ebx & bit_CLZERO) > + set_feature (FEATURE_CLZERO); > + if (ebx & bit_WBNOINVD) > + set_feature (FEATURE_WBNOINVD); > + } > + > +#undef set_feature > +} > + > +static inline int > +cpu_indicator_init (struct __processor_model *cpu_model, > + struct __processor_model2 *cpu_model2, > + unsigned int *cpu_features2) > +{ > + unsigned int eax, ebx, ecx, edx; > + > + int max_level; > + unsigned int vendor; > + unsigned int model, family, brand_id; > + unsigned int extended_model, extended_family; > + > + /* This function needs to run just once. */ > + if (cpu_model->__cpu_vendor) > + return 0; > + > + /* Assume cpuid insn present. Run in level 0 to get vendor id. */ > + if (!__get_cpuid (0, &eax, &ebx, &ecx, &edx)) > + { > + cpu_model->__cpu_vendor = VENDOR_OTHER; > + return -1; > + } > + > + vendor = ebx; > + max_level = eax; > + > + if (max_level < 1) > + { > + cpu_model->__cpu_vendor = VENDOR_OTHER; > + return -1; > + } > + > + if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) > + { > + cpu_model->__cpu_vendor = VENDOR_OTHER; > + return -1; > + } > + > + cpu_model2->__cpu_max_level = max_level; > + > + 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) > + { > + /* Adjust model and family for Intel CPUS. */ > + if (family == 0x0f) > + { > + family += extended_family; > + model += extended_model; > + } > + else if (family == 0x06) > + model += extended_model; > + > + cpu_model2->__cpu_family = family; > + cpu_model2->__cpu_model = model; > + > + /* Find available features. */ > + get_available_features (cpu_model, cpu_model2, cpu_features2, > + ecx, edx); > + /* Get CPU type. */ > + get_intel_cpu (cpu_model, cpu_model2, cpu_features2, brand_id); > + cpu_model->__cpu_vendor = VENDOR_INTEL; > + } > + else if (vendor == signature_AMD_ebx) > + { > + /* Adjust model and family for AMD CPUS. */ > + if (family == 0x0f) > + { > + family += extended_family; > + model += extended_model; > + } > + > + cpu_model2->__cpu_family = family; > + cpu_model2->__cpu_model = model; > + > + /* Find available features. */ > + get_available_features (cpu_model, cpu_model2, cpu_features2, > + ecx, edx); > + /* Get CPU type. */ > + get_amd_cpu (cpu_model, cpu_model2, cpu_features2); > + cpu_model->__cpu_vendor = VENDOR_AMD; > + } > + else if (vendor == signature_CENTAUR_ebx) > + cpu_model->__cpu_vendor = VENDOR_CENTAUR; > + else if (vendor == signature_CYRIX_ebx) > + cpu_model->__cpu_vendor = VENDOR_CYRIX; > + else if (vendor == signature_NSC_ebx) > + cpu_model->__cpu_vendor = VENDOR_NSC; > + else > + cpu_model->__cpu_vendor = VENDOR_OTHER; > + > + gcc_assert (cpu_model->__cpu_vendor < VENDOR_MAX); > + gcc_assert (cpu_model->__cpu_type < CPU_TYPE_MAX); > + gcc_assert (cpu_model->__cpu_subtype < CPU_SUBTYPE_MAX); > + > + return 0; > +} > diff --git a/gcc/common/config/i386/i386-cpuinfo.h > b/gcc/common/config/i386/i386-cpuinfo.h > index e11c68f46dd..96cf0eaea47 100644 > --- a/gcc/common/config/i386/i386-cpuinfo.h > +++ b/gcc/common/config/i386/i386-cpuinfo.h > @@ -30,6 +30,9 @@ enum processor_vendor > VENDOR_INTEL = 1, > VENDOR_AMD, > VENDOR_OTHER, > + VENDOR_CENTAUR, > + VENDOR_CYRIX, > + VENDOR_NSC, > BUILTIN_VENDOR_MAX = VENDOR_OTHER, > VENDOR_MAX > }; > @@ -122,6 +125,101 @@ enum feature_priority > P_PROC_DYNAMIC > }; > > +/* ISA Features supported. New features have to be inserted at the end. */ > + > +enum processor_features > +{ > + FEATURE_CMOV = 0, > + FEATURE_MMX, > + FEATURE_POPCNT, > + FEATURE_SSE, > + FEATURE_SSE2, > + FEATURE_SSE3, > + FEATURE_SSSE3, > + FEATURE_SSE4_1, > + FEATURE_SSE4_2, > + FEATURE_AVX, > + FEATURE_AVX2, > + FEATURE_SSE4_A, > + FEATURE_FMA4, > + FEATURE_XOP, > + FEATURE_FMA, > + FEATURE_AVX512F, > + FEATURE_BMI, > + FEATURE_BMI2, > + FEATURE_AES, > + FEATURE_PCLMUL, > + FEATURE_AVX512VL, > + FEATURE_AVX512BW, > + FEATURE_AVX512DQ, > + FEATURE_AVX512CD, > + FEATURE_AVX512ER, > + FEATURE_AVX512PF, > + FEATURE_AVX512VBMI, > + FEATURE_AVX512IFMA, > + FEATURE_AVX5124VNNIW, > + FEATURE_AVX5124FMAPS, > + FEATURE_AVX512VPOPCNTDQ, > + FEATURE_AVX512VBMI2, > + FEATURE_GFNI, > + FEATURE_VPCLMULQDQ, > + FEATURE_AVX512VNNI, > + FEATURE_AVX512BITALG, > + FEATURE_AVX512BF16, > + FEATURE_AVX512VP2INTERSECT, > + FEATURE_3DNOW, > + FEATURE_3DNOWP, > + FEATURE_ADX, > + FEATURE_ABM, > + FEATURE_CLDEMOTE, > + FEATURE_CLFLUSHOPT, > + FEATURE_CLWB, > + FEATURE_CLZERO, > + FEATURE_CMPXCHG16B, > + FEATURE_CMPXCHG8B, > + FEATURE_ENQCMD, > + FEATURE_F16C, > + FEATURE_FSGSBASE, > + FEATURE_FXSAVE, > + FEATURE_HLE, > + FEATURE_IBT, > + FEATURE_LAHF_LM, > + FEATURE_LM, > + FEATURE_LWP, > + FEATURE_LZCNT, > + FEATURE_MOVBE, > + FEATURE_MOVDIR64B, > + FEATURE_MOVDIRI, > + FEATURE_MWAITX, > + FEATURE_OSXSAVE, > + FEATURE_PCONFIG, > + FEATURE_PKU, > + FEATURE_PREFETCHWT1, > + FEATURE_PRFCHW, > + FEATURE_PTWRITE, > + FEATURE_RDPID, > + FEATURE_RDRND, > + FEATURE_RDSEED, > + FEATURE_RTM, > + FEATURE_SERIALIZE, > + FEATURE_SGX, > + FEATURE_SHA, > + FEATURE_SHSTK, > + FEATURE_TBM, > + FEATURE_TSXLDTRK, > + FEATURE_VAES, > + FEATURE_WAITPKG, > + FEATURE_WBNOINVD, > + FEATURE_XSAVE, > + FEATURE_XSAVEC, > + FEATURE_XSAVEOPT, > + FEATURE_XSAVES, > + CPU_FEATURE_MAX > +}; > + > +/* Size of __cpu_features2 array in libgcc/config/i386/cpuinfo.c. */ > +#define SIZE_OF_CPU_FEATURES ((CPU_FEATURE_MAX - 1) / 32) > + > /* These are the values for vendor types, cpu types and subtypes. Cpu > types and subtypes should be subtracted by the corresponding start > value. */ > diff --git a/gcc/config/i386/i386-builtins.c b/gcc/config/i386/i386-builtins.c > index 6f6a8328ef1..57e709d6c43 100644 > --- a/gcc/config/i386/i386-builtins.c > +++ b/gcc/config/i386/i386-builtins.c > @@ -1835,50 +1835,6 @@ ix86_builtin_reciprocal (tree fndecl) > } > } > > -/* This is the order of bit-fields in __processor_features in cpuinfo.c */ > -enum processor_features > -{ > - F_CMOV = 0, > - F_MMX, > - F_POPCNT, > - F_SSE, > - F_SSE2, > - F_SSE3, > - F_SSSE3, > - F_SSE4_1, > - F_SSE4_2, > - F_AVX, > - F_AVX2, > - F_SSE4_A, > - F_FMA4, > - F_XOP, > - F_FMA, > - F_AVX512F, > - F_BMI, > - F_BMI2, > - F_AES, > - F_PCLMUL, > - F_AVX512VL, > - F_AVX512BW, > - F_AVX512DQ, > - F_AVX512CD, > - F_AVX512ER, > - F_AVX512PF, > - F_AVX512VBMI, > - F_AVX512IFMA, > - F_AVX5124VNNIW, > - F_AVX5124FMAPS, > - F_AVX512VPOPCNTDQ, > - F_AVX512VBMI2, > - F_GFNI, > - F_VPCLMULQDQ, > - F_AVX512VNNI, > - F_AVX512BITALG, > - F_AVX512BF16, > - F_AVX512VP2INTERSECT, > - F_MAX > -}; > - > /* These are the target attribute strings for which a dispatcher is > available, from fold_builtin_cpu. */ > struct _isa_names_table > @@ -1890,44 +1846,44 @@ struct _isa_names_table > > static const _isa_names_table isa_names_table[] = > { > - {"cmov", F_CMOV, P_NONE}, > - {"mmx", F_MMX, P_MMX}, > - {"popcnt", F_POPCNT, P_POPCNT}, > - {"sse", F_SSE, P_SSE}, > - {"sse2", F_SSE2, P_SSE2}, > - {"sse3", F_SSE3, P_SSE3}, > - {"ssse3", F_SSSE3, P_SSSE3}, > - {"sse4a", F_SSE4_A, P_SSE4_A}, > - {"sse4.1", F_SSE4_1, P_SSE4_1}, > - {"sse4.2", F_SSE4_2, P_SSE4_2}, > - {"avx", F_AVX, P_AVX}, > - {"fma4", F_FMA4, P_FMA4}, > - {"xop", F_XOP, P_XOP}, > - {"fma", F_FMA, P_FMA}, > - {"avx2", F_AVX2, P_AVX2}, > - {"avx512f", F_AVX512F, P_AVX512F}, > - {"bmi", F_BMI, P_BMI}, > - {"bmi2", F_BMI2, P_BMI2}, > - {"aes", F_AES, P_AES}, > - {"pclmul", F_PCLMUL, P_PCLMUL}, > - {"avx512vl",F_AVX512VL, P_NONE}, > - {"avx512bw",F_AVX512BW, P_NONE}, > - {"avx512dq",F_AVX512DQ, P_NONE}, > - {"avx512cd",F_AVX512CD, P_NONE}, > - {"avx512er",F_AVX512ER, P_NONE}, > - {"avx512pf",F_AVX512PF, P_NONE}, > - {"avx512vbmi",F_AVX512VBMI, P_NONE}, > - {"avx512ifma",F_AVX512IFMA, P_NONE}, > - {"avx5124vnniw",F_AVX5124VNNIW, P_NONE}, > - {"avx5124fmaps",F_AVX5124FMAPS, P_NONE}, > - {"avx512vpopcntdq",F_AVX512VPOPCNTDQ, P_NONE}, > - {"avx512vbmi2", F_AVX512VBMI2, P_NONE}, > - {"gfni", F_GFNI, P_NONE}, > - {"vpclmulqdq", F_VPCLMULQDQ, P_NONE}, > - {"avx512vnni", F_AVX512VNNI, P_NONE}, > - {"avx512bitalg", F_AVX512BITALG, P_NONE}, > - {"avx512bf16", F_AVX512BF16, P_NONE}, > - {"avx512vp2intersect",F_AVX512VP2INTERSECT, P_NONE} > + {"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 > @@ -2294,16 +2250,29 @@ fold_builtin_cpu (tree fndecl, tree *args) > > if (isa_names_table[i].feature >= 32) > { > - tree __cpu_features2_var = make_var_decl (unsigned_type_node, > + tree index_type > + = build_index_type (size_int (SIZE_OF_CPU_FEATURES)); > + tree type = build_array_type (unsigned_type_node, index_type); > + tree __cpu_features2_var = make_var_decl (type, > "__cpu_features2"); > > varpool_node::add (__cpu_features2_var); > - field_val = (1U << (isa_names_table[i].feature - 32)); > - /* Return __cpu_features2 & field_val */ > - final = build2 (BIT_AND_EXPR, unsigned_type_node, > - __cpu_features2_var, > - build_int_cstu (unsigned_type_node, field_val)); > - return build1 (CONVERT_EXPR, integer_type_node, final); > + for (unsigned int j = 0; j < SIZE_OF_CPU_FEATURES; j++) > + if (isa_names_table[i].feature < (32 + 32 + j * 32)) > + { > + field_val = (1U << (isa_names_table[i].feature > + - (32 + j * 32))); > + tree index = size_int (j); > + array_elt = build4 (ARRAY_REF, unsigned_type_node, > + __cpu_features2_var, > + index, NULL_TREE, NULL_TREE); > + /* Return __cpu_features2[index] & field_val */ > + final = build2 (BIT_AND_EXPR, unsigned_type_node, > + array_elt, > + build_int_cstu (unsigned_type_node, > + field_val)); > + return build1 (CONVERT_EXPR, integer_type_node, final); > + } > } > > field = TYPE_FIELDS (__processor_model_type); > diff --git a/libgcc/config/i386/cpuinfo.c b/libgcc/config/i386/cpuinfo.c > index cf5f0884bb4..7218952f32a 100644 > --- a/libgcc/config/i386/cpuinfo.c > +++ b/libgcc/config/i386/cpuinfo.c > @@ -26,7 +26,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. > If not, see > #include "cpuid.h" > #include "tsystem.h" > #include "auto-target.h" > -#include "cpuinfo.h" > +#include "common/config/i386/i386-cpuinfo.h" > +#include "common/config/i386/cpuinfo.h" > > #ifdef HAVE_INIT_PRIORITY > #define CONSTRUCTOR_PRIORITY (101) > @@ -39,386 +40,14 @@ int __cpu_indicator_init (void) > > > struct __processor_model __cpu_model = { }; > -#ifndef SHARED > /* We want to move away from __cpu_model in libgcc_s.so.1 and the > size of __cpu_model is part of ABI. So, new features that don't > fit into __cpu_model.__cpu_features[0] go into extra variables > - in libgcc.a only, preferrably hidden. */ > -unsigned int __cpu_features2; > -#endif > - > - > -/* Get the specific type of AMD CPU. */ > - > -static void > -get_amd_cpu (unsigned int family, unsigned int model) > -{ > - switch (family) > - { > - /* AMD Family 10h. */ > - case 0x10: > - __cpu_model.__cpu_type = AMDFAM10H; > - switch (model) > - { > - case 0x2: > - /* Barcelona. */ > - __cpu_model.__cpu_subtype = AMDFAM10H_BARCELONA; > - break; > - case 0x4: > - /* Shanghai. */ > - __cpu_model.__cpu_subtype = AMDFAM10H_SHANGHAI; > - break; > - case 0x8: > - /* Istanbul. */ > - __cpu_model.__cpu_subtype = AMDFAM10H_ISTANBUL; > - break; > - default: > - break; > - } > - break; > - /* AMD Family 14h "btver1". */ > - case 0x14: > - __cpu_model.__cpu_type = AMD_BTVER1; > - break; > - /* AMD Family 15h "Bulldozer". */ > - case 0x15: > - __cpu_model.__cpu_type = AMDFAM15H; > - > - if (model == 0x2) > - __cpu_model.__cpu_subtype = AMDFAM15H_BDVER2; > - /* Bulldozer version 1. */ > - else if (model <= 0xf) > - __cpu_model.__cpu_subtype = AMDFAM15H_BDVER1; > - /* Bulldozer version 2 "Piledriver" */ > - else if (model <= 0x2f) > - __cpu_model.__cpu_subtype = AMDFAM15H_BDVER2; > - /* Bulldozer version 3 "Steamroller" */ > - else if (model <= 0x4f) > - __cpu_model.__cpu_subtype = AMDFAM15H_BDVER3; > - /* Bulldozer version 4 "Excavator" */ > - else if (model <= 0x7f) > - __cpu_model.__cpu_subtype = AMDFAM15H_BDVER4; > - break; > - /* AMD Family 16h "btver2" */ > - case 0x16: > - __cpu_model.__cpu_type = AMD_BTVER2; > - break; > - case 0x17: > - __cpu_model.__cpu_type = AMDFAM17H; > - /* AMD family 17h version 1. */ > - if (model <= 0x1f) > - __cpu_model.__cpu_subtype = AMDFAM17H_ZNVER1; > - if (model >= 0x30) > - __cpu_model.__cpu_subtype = AMDFAM17H_ZNVER2; > - break; > - default: > - break; > - } > -} > - > -/* Get the specific type of Intel CPU. */ > - > -static void > -get_intel_cpu (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: > - /* Bonnell. */ > - __cpu_model.__cpu_type = INTEL_BONNELL; > - break; > - case 0x37: > - case 0x4a: > - case 0x4d: > - case 0x5a: > - case 0x5d: > - /* Silvermont. */ > - __cpu_model.__cpu_type = INTEL_SILVERMONT; > - break; > - case 0x5c: > - case 0x5f: > - /* Goldmont. */ > - __cpu_model.__cpu_type = INTEL_GOLDMONT; > - break; > - case 0x7a: > - /* Goldmont Plus. */ > - __cpu_model.__cpu_type = INTEL_GOLDMONT_PLUS; > - break; > - case 0x57: > - /* Knights Landing. */ > - __cpu_model.__cpu_type = INTEL_KNL; > - break; > - case 0x85: > - /* Knights Mill. */ > - __cpu_model.__cpu_type = INTEL_KNM; > - break; > - case 0x1a: > - case 0x1e: > - case 0x1f: > - case 0x2e: > - /* Nehalem. */ > - __cpu_model.__cpu_type = INTEL_COREI7; > - __cpu_model.__cpu_subtype = INTEL_COREI7_NEHALEM; > - break; > - case 0x25: > - case 0x2c: > - case 0x2f: > - /* Westmere. */ > - __cpu_model.__cpu_type = INTEL_COREI7; > - __cpu_model.__cpu_subtype = INTEL_COREI7_WESTMERE; > - break; > - case 0x2a: > - case 0x2d: > - /* Sandy Bridge. */ > - __cpu_model.__cpu_type = INTEL_COREI7; > - __cpu_model.__cpu_subtype = INTEL_COREI7_SANDYBRIDGE; > - break; > - case 0x3a: > - case 0x3e: > - /* Ivy Bridge. */ > - __cpu_model.__cpu_type = INTEL_COREI7; > - __cpu_model.__cpu_subtype = INTEL_COREI7_IVYBRIDGE; > - break; > - case 0x3c: > - case 0x3f: > - case 0x45: > - case 0x46: > - /* Haswell. */ > - __cpu_model.__cpu_type = INTEL_COREI7; > - __cpu_model.__cpu_subtype = INTEL_COREI7_HASWELL; > - break; > - case 0x3d: > - case 0x47: > - case 0x4f: > - case 0x56: > - /* Broadwell. */ > - __cpu_model.__cpu_type = INTEL_COREI7; > - __cpu_model.__cpu_subtype = INTEL_COREI7_BROADWELL; > - break; > - case 0x4e: > - case 0x5e: > - /* Skylake. */ > - case 0x8e: > - case 0x9e: > - /* Kaby Lake. */ > - __cpu_model.__cpu_type = INTEL_COREI7; > - __cpu_model.__cpu_subtype = INTEL_COREI7_SKYLAKE; > - break; > - case 0x55: > - { > - unsigned int eax, ebx, ecx, edx; > - __cpu_model.__cpu_type = INTEL_COREI7; > - __cpuid_count (7, 0, eax, ebx, ecx, edx); > - if (ecx & bit_AVX512VNNI) > - /* Cascade Lake. */ > - __cpu_model.__cpu_subtype = INTEL_COREI7_CASCADELAKE; > - else > - /* Skylake with AVX-512 support. */ > - __cpu_model.__cpu_subtype = INTEL_COREI7_SKYLAKE_AVX512; > - } > - break; > - case 0x66: > - /* Cannon Lake. */ > - __cpu_model.__cpu_type = INTEL_COREI7; > - __cpu_model.__cpu_subtype = INTEL_COREI7_CANNONLAKE; > - break; > - case 0x17: > - case 0x1d: > - /* Penryn. */ > - case 0x0f: > - /* Merom. */ > - __cpu_model.__cpu_type = INTEL_CORE2; > - break; > - default: > - break; > - } > - break; > - default: > - /* We have no idea. */ > - break; > - } > - } > -} > - > -/* ECX and EDX are output of CPUID at level one. MAX_CPUID_LEVEL is > - the max possible level of CPUID insn. */ > -static void > -get_available_features (unsigned int ecx, unsigned int edx, > - int max_cpuid_level) > -{ > - unsigned int eax, ebx; > - unsigned int ext_level; > - > - unsigned int features = 0; > - unsigned int features2 = 0; > - > - /* 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) > - > - /* Check if AVX and AVX512 are usable. */ > - int avx_usable = 0; > - int avx512_usable = 0; > - if ((ecx & bit_OSXSAVE)) > - { > - /* Check if XMM, YMM, OPMASK, upper 256 bits of ZMM0-ZMM15 and > - ZMM16-ZMM31 states are supported by OSXSAVE. */ > - unsigned int xcrlow; > - unsigned int xcrhigh; > - asm (".byte 0x0f, 0x01, 0xd0" > - : "=a" (xcrlow), "=d" (xcrhigh) > - : "c" (XCR_XFEATURE_ENABLED_MASK)); > - if ((xcrlow & XCR_AVX_ENABLED_MASK) == XCR_AVX_ENABLED_MASK) > - { > - avx_usable = 1; > - avx512_usable = ((xcrlow & XCR_AVX512F_ENABLED_MASK) > - == XCR_AVX512F_ENABLED_MASK); > - } > - } > - > -#define set_feature(f) \ > - do \ > - { \ > - if (f < 32) \ > - features |= (1U << (f & 31)); \ > - else \ > - features2 |= (1U << ((f - 32) & 31)); \ > - } \ > - while (0) > - > - if (edx & bit_CMOV) > - set_feature (FEATURE_CMOV); > - if (edx & bit_MMX) > - set_feature (FEATURE_MMX); > - if (edx & bit_SSE) > - set_feature (FEATURE_SSE); > - if (edx & bit_SSE2) > - set_feature (FEATURE_SSE2); > - if (ecx & bit_POPCNT) > - set_feature (FEATURE_POPCNT); > - if (ecx & bit_AES) > - set_feature (FEATURE_AES); > - if (ecx & bit_PCLMUL) > - set_feature (FEATURE_PCLMUL); > - if (ecx & bit_SSE3) > - set_feature (FEATURE_SSE3); > - if (ecx & bit_SSSE3) > - set_feature (FEATURE_SSSE3); > - if (ecx & bit_SSE4_1) > - set_feature (FEATURE_SSE4_1); > - if (ecx & bit_SSE4_2) > - set_feature (FEATURE_SSE4_2); > - if (avx_usable) > - { > - if (ecx & bit_AVX) > - set_feature (FEATURE_AVX); > - if (ecx & bit_FMA) > - set_feature (FEATURE_FMA); > - } > - > - /* Get Advanced Features at level 7 (eax = 7, ecx = 0/1). */ > - if (max_cpuid_level >= 7) > - { > - __cpuid_count (7, 0, eax, ebx, ecx, edx); > - if (ebx & bit_BMI) > - set_feature (FEATURE_BMI); > - if (avx_usable) > - { > - if (ebx & bit_AVX2) > - set_feature (FEATURE_AVX2); > - if (ecx & bit_VPCLMULQDQ) > - set_feature (FEATURE_VPCLMULQDQ); > - } > - if (ebx & bit_BMI2) > - set_feature (FEATURE_BMI2); > - if (ecx & bit_GFNI) > - set_feature (FEATURE_GFNI); > - if (avx512_usable) > - { > - if (ebx & bit_AVX512F) > - set_feature (FEATURE_AVX512F); > - if (ebx & bit_AVX512VL) > - set_feature (FEATURE_AVX512VL); > - if (ebx & bit_AVX512BW) > - set_feature (FEATURE_AVX512BW); > - if (ebx & bit_AVX512DQ) > - set_feature (FEATURE_AVX512DQ); > - if (ebx & bit_AVX512CD) > - set_feature (FEATURE_AVX512CD); > - if (ebx & bit_AVX512PF) > - set_feature (FEATURE_AVX512PF); > - if (ebx & bit_AVX512ER) > - set_feature (FEATURE_AVX512ER); > - if (ebx & bit_AVX512IFMA) > - set_feature (FEATURE_AVX512IFMA); > - if (ecx & bit_AVX512VBMI) > - set_feature (FEATURE_AVX512VBMI); > - if (ecx & bit_AVX512VBMI2) > - set_feature (FEATURE_AVX512VBMI2); > - if (ecx & bit_AVX512VNNI) > - set_feature (FEATURE_AVX512VNNI); > - if (ecx & bit_AVX512BITALG) > - set_feature (FEATURE_AVX512BITALG); > - if (ecx & bit_AVX512VPOPCNTDQ) > - set_feature (FEATURE_AVX512VPOPCNTDQ); > - if (edx & bit_AVX5124VNNIW) > - set_feature (FEATURE_AVX5124VNNIW); > - if (edx & bit_AVX5124FMAPS) > - set_feature (FEATURE_AVX5124FMAPS); > - if (edx & bit_AVX512VP2INTERSECT) > - set_feature (FEATURE_AVX512VP2INTERSECT); > + in libgcc.a only, preferably hidden. > > - __cpuid_count (7, 1, eax, ebx, ecx, edx); > - if (eax & bit_AVX512BF16) > - set_feature (FEATURE_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) > - set_feature (FEATURE_SSE4_A); > - if (avx_usable) > - { > - if (ecx & bit_FMA4) > - set_feature (FEATURE_FMA4); > - if (ecx & bit_XOP) > - set_feature (FEATURE_XOP); > - } > - } > - > - __cpu_model.__cpu_features[0] = features; > -#ifndef SHARED > - __cpu_features2 = features2; > -#else > - (void) features2; > -#endif > -} > + NB: Since older 386-builtins.c accesses __cpu_features2 as scalar or > + smaller array, it can only access the first few elements. */ > +unsigned int __cpu_features2[SIZE_OF_CPU_FEATURES]; > > /* A constructor function that is sets __cpu_model and __cpu_features with > the right values. This needs to run only once. This constructor is > @@ -429,85 +58,9 @@ get_available_features (unsigned int ecx, unsigned int > edx, > int __attribute__ ((constructor CONSTRUCTOR_PRIORITY)) > __cpu_indicator_init (void) > { > - unsigned int eax, ebx, ecx, edx; > - > - int max_level; > - unsigned int vendor; > - unsigned int model, family, brand_id; > - unsigned int extended_model, extended_family; > - > - /* This function needs to run just once. */ > - if (__cpu_model.__cpu_vendor) > - return 0; > - > - /* Assume cpuid insn present. Run in level 0 to get vendor id. */ > - if (!__get_cpuid (0, &eax, &ebx, &ecx, &edx)) > - { > - __cpu_model.__cpu_vendor = VENDOR_OTHER; > - return -1; > - } > - > - vendor = ebx; > - max_level = eax; > - > - if (max_level < 1) > - { > - __cpu_model.__cpu_vendor = VENDOR_OTHER; > - return -1; > - } > - > - if (!__get_cpuid (1, &eax, &ebx, &ecx, &edx)) > - { > - __cpu_model.__cpu_vendor = VENDOR_OTHER; > - return -1; > - } > - > - 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) > - { > - /* Adjust model and family for Intel CPUS. */ > - if (family == 0x0f) > - { > - family += extended_family; > - model += extended_model; > - } > - else if (family == 0x06) > - model += extended_model; > - > - /* Get CPU type. */ > - get_intel_cpu (family, model, brand_id); > - /* Find available features. */ > - get_available_features (ecx, edx, max_level); > - __cpu_model.__cpu_vendor = VENDOR_INTEL; > - } > - else if (vendor == signature_AMD_ebx) > - { > - /* Adjust model and family for AMD CPUS. */ > - if (family == 0x0f) > - { > - family += extended_family; > - model += extended_model; > - } > - > - /* Get CPU type. */ > - get_amd_cpu (family, model); > - /* Find available features. */ > - get_available_features (ecx, edx, max_level); > - __cpu_model.__cpu_vendor = VENDOR_AMD; > - } > - else > - __cpu_model.__cpu_vendor = VENDOR_OTHER; > - > - gcc_assert (__cpu_model.__cpu_vendor < VENDOR_MAX); > - gcc_assert (__cpu_model.__cpu_type < CPU_TYPE_MAX); > - gcc_assert (__cpu_model.__cpu_subtype < CPU_SUBTYPE_MAX); > - > - return 0; > + struct __processor_model2 cpu_model2; > + return cpu_indicator_init (&__cpu_model, &cpu_model2, > + __cpu_features2); > } > > #if defined SHARED && defined USE_ELF_SYMVER > diff --git a/libgcc/config/i386/cpuinfo.h b/libgcc/config/i386/cpuinfo.h > deleted file mode 100644 > index 0f97510cde1..00000000000 > --- a/libgcc/config/i386/cpuinfo.h > +++ /dev/null > @@ -1,136 +0,0 @@ > -/* Get CPU type and Features for x86 processors. > - Copyright (C) 2012-2020 Free Software Foundation, Inc. > - Contributed by Sriraman Tallam (tmsri...@google.com) > - > -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. > - > -Under Section 7 of GPL version 3, you are granted additional > -permissions described in the GCC Runtime Library Exception, version > -3.1, as published by the Free Software Foundation. > - > -You should have received a copy of the GNU General Public License and > -a copy of the GCC Runtime Library Exception along with this program; > -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see > -<http://www.gnu.org/licenses/>. */ > - > -/* Processor Vendor and Models. */ > - > -enum processor_vendor > -{ > - VENDOR_INTEL = 1, > - VENDOR_AMD, > - VENDOR_OTHER, > - VENDOR_MAX > -}; > - > -/* Any new types or subtypes have to be inserted at the end. */ > - > -enum processor_types > -{ > - INTEL_BONNELL = 1, > - INTEL_CORE2, > - INTEL_COREI7, > - AMDFAM10H, > - AMDFAM15H, > - INTEL_SILVERMONT, > - INTEL_KNL, > - AMD_BTVER1, > - AMD_BTVER2, > - AMDFAM17H, > - INTEL_KNM, > - INTEL_GOLDMONT, > - INTEL_GOLDMONT_PLUS, > - INTEL_TREMONT, > - CPU_TYPE_MAX > -}; > - > -enum processor_subtypes > -{ > - INTEL_COREI7_NEHALEM = 1, > - INTEL_COREI7_WESTMERE, > - INTEL_COREI7_SANDYBRIDGE, > - AMDFAM10H_BARCELONA, > - AMDFAM10H_SHANGHAI, > - AMDFAM10H_ISTANBUL, > - AMDFAM15H_BDVER1, > - AMDFAM15H_BDVER2, > - AMDFAM15H_BDVER3, > - AMDFAM15H_BDVER4, > - AMDFAM17H_ZNVER1, > - INTEL_COREI7_IVYBRIDGE, > - INTEL_COREI7_HASWELL, > - INTEL_COREI7_BROADWELL, > - INTEL_COREI7_SKYLAKE, > - INTEL_COREI7_SKYLAKE_AVX512, > - INTEL_COREI7_CANNONLAKE, > - INTEL_COREI7_ICELAKE_CLIENT, > - INTEL_COREI7_ICELAKE_SERVER, > - AMDFAM17H_ZNVER2, > - INTEL_COREI7_CASCADELAKE, > - INTEL_COREI7_TIGERLAKE, > - INTEL_COREI7_COOPERLAKE, > - CPU_SUBTYPE_MAX > -}; > - > -/* ISA Features supported. New features have to be inserted at the end. */ > - > -enum processor_features > -{ > - FEATURE_CMOV = 0, > - FEATURE_MMX, > - FEATURE_POPCNT, > - FEATURE_SSE, > - FEATURE_SSE2, > - FEATURE_SSE3, > - FEATURE_SSSE3, > - FEATURE_SSE4_1, > - FEATURE_SSE4_2, > - FEATURE_AVX, > - FEATURE_AVX2, > - FEATURE_SSE4_A, > - FEATURE_FMA4, > - FEATURE_XOP, > - FEATURE_FMA, > - FEATURE_AVX512F, > - FEATURE_BMI, > - FEATURE_BMI2, > - FEATURE_AES, > - FEATURE_PCLMUL, > - FEATURE_AVX512VL, > - FEATURE_AVX512BW, > - FEATURE_AVX512DQ, > - FEATURE_AVX512CD, > - FEATURE_AVX512ER, > - FEATURE_AVX512PF, > - FEATURE_AVX512VBMI, > - FEATURE_AVX512IFMA, > - FEATURE_AVX5124VNNIW, > - FEATURE_AVX5124FMAPS, > - FEATURE_AVX512VPOPCNTDQ, > - FEATURE_AVX512VBMI2, > - FEATURE_GFNI, > - FEATURE_VPCLMULQDQ, > - FEATURE_AVX512VNNI, > - FEATURE_AVX512BITALG, > - FEATURE_AVX512BF16, > - FEATURE_AVX512VP2INTERSECT > -}; > - > -extern struct __processor_model > -{ > - unsigned int __cpu_vendor; > - unsigned int __cpu_type; > - unsigned int __cpu_subtype; > - unsigned int __cpu_features[1]; > -} __cpu_model; > -extern unsigned int __cpu_features2; > -- > 2.26.2 >