On Tue, Oct 6, 2015 at 3:36 PM, Kirill Yukhin <kirill.yuk...@gmail.com> wrote: > Hello, > Patch in the bottom adds missing options to libgcc/config/i386/cpuinfo.c > It also updates documentation. > As far as number of entries exceeded 32, I've extended > type of features array to INT64 (most suspicious part of the patch). > > Bootstrapped and regtested. `make pdf' seems to be working properly. > > Comments?
Er, this is on purpose. Multiversioning is intended to depend on ISA extensions such as SSE, AVX, AES to some degree, and similar extensions that do make a difference when used in compilation. This was discussed some years ago, but I can't find the URL of the discussion. So, from the list below, I'd take only SHA. Plus fixes/additions in the documentation and testsuite, of course. Uros. > gcc/ > * config/i386/i386.c (build_processor_model_struct): Replace > array type to intDI. > (old_builtin_cpu): Handle SHA, PREFETCHWT1, FSGSBASE, HLE, > RTM, RDSEED, ADX, MPX, CLFLUSHOPT, PCOMMIT, CLWB, XSAVEOPT, > XSAVEC, and XSAVES features. Update built-in expansion. > * doc/extend.texi (ivybridge): New. > (haswell): Ditto. > (broadwell): Ditto. > (skylake): Ditto. > (skylake-avx512): Ditto. > (aes): Ditto. > (pclmul): Ditto. > (fma): Ditto. > (bmi): Ditto. > (bmi2): Ditto. > (avx512bw): Ditto. > (avx512dq): Ditto. > (avx512pf): Ditto. > (avx512er): Ditto. > (avx512ifma): Ditto. > (avx512vbmi): Ditto. > (sha): Ditto. > (prefetchwt1): Ditto. > > gcc/testsuite/ > * gcc.target/i386/builtin_target.c: Check SHA, PREFETCHWT1, > FSGSBASE, HLE, RTM, RDSEED, ADX, MPX, CLFLUSHOPT, PCOMMIT, > CLWB, XSAVEOPT, XSAVEC, and XSAVES features. > > libgcc/ > * config/i386/cpuinfo.c (processor_features): Add SHA, PREFETCHWT1, > FSGSBASE, HLE, RTM, RDSEED, ADX, MPX, CLFLUSHOPT, PCOMMIT, CLWB, > XSAVEOPT, XSAVEC, and XSAVES features. > (struct __processor_model): Set type of __cpu_features array to > uint64_t. > (get_available_features): Add new features. Reorder according > to bit number. > > -- > Thanks, K > > commit 839916b8d017fac166f76c317bdf5c38d5d15ea4 > Author: Kirill Yukhin <kirill.yuk...@intel.com> > Date: Tue Oct 6 16:20:09 2015 +0300 > > Add missing entries to libgcc/config/i386/cpuinfo.c. > > diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c > index d59b59b..13241f2 100644 > --- a/gcc/config/i386/i386.c > +++ b/gcc/config/i386/i386.c > @@ -36507,10 +36507,10 @@ build_processor_model_struct (void) > field_chain = field; > } > > - /* The last field is an array of unsigned integers of size one. */ > + /* The last field is an array of unsigned long long integers of size one. > */ > field = build_decl (UNKNOWN_LOCATION, FIELD_DECL, > get_identifier (field_name[3]), > - build_array_type (unsigned_type_node, > + build_array_type (unsigned_intDI_type_node, > build_index_type (size_one_node))); > if (field_chain != NULL_TREE) > DECL_CHAIN (field) = field_chain; > @@ -36587,6 +36587,20 @@ fold_builtin_cpu (tree fndecl, tree *args) > F_AVX512PF, > F_AVX512VBMI, > F_AVX512IFMA, > + F_SHA, > + F_PREFETCHWT1, > + F_FSGSBASE, > + F_HLE, > + F_RTM, > + F_RDSEED, > + F_ADX, > + F_MPX, > + F_CLFLUSHOPT, > + F_PCOMMIT, > + F_CLWB, > + F_XSAVEOPT, > + F_XSAVEC, > + F_XSAVES, > F_MAX > }; > > @@ -36697,6 +36711,20 @@ fold_builtin_cpu (tree fndecl, tree *args) > {"avx512pf",F_AVX512PF}, > {"avx512vbmi",F_AVX512VBMI}, > {"avx512ifma",F_AVX512IFMA}, > + {"prefetchwt1", F_PREFETCHWT1}, > + {"sha", F_SHA}, > + {"fsgsbase",F_FSGSBASE}, > + {"hle", F_HLE}, > + {"rtm", F_RTM}, > + {"rdseed", F_RDSEED}, > + {"adx", F_ADX}, > + {"mpx", F_MPX}, > + {"clflushopt",F_CLFLUSHOPT}, > + {"pcommit", F_PCOMMIT}, > + {"clwb", F_CLWB}, > + {"xsaveopt",F_XSAVEOPT}, > + {"xsavec", F_XSAVEC}, > + {"xsaves", F_XSAVES}, > }; > > tree __processor_model_type = build_processor_model_struct (); > @@ -36780,7 +36808,7 @@ fold_builtin_cpu (tree fndecl, tree *args) > tree field; > tree final; > > - unsigned int field_val = 0; > + unsigned HOST_WIDE_INT field_val = 0; > unsigned int NUM_ISA_NAMES > = sizeof (isa_names_table) / sizeof (struct _isa_names_table); > > @@ -36806,13 +36834,13 @@ fold_builtin_cpu (tree fndecl, tree *args) > field, NULL_TREE); > > /* Access the 0th element of __cpu_features array. */ > - array_elt = build4 (ARRAY_REF, unsigned_type_node, ref, > + array_elt = build4 (ARRAY_REF, unsigned_intDI_type_node, ref, > integer_zero_node, NULL_TREE, NULL_TREE); > > field_val = (1 << isa_names_table[i].feature); > /* Return __cpu_model.__cpu_features[0] & field_val */ > - final = build2 (BIT_AND_EXPR, unsigned_type_node, array_elt, > - build_int_cstu (unsigned_type_node, field_val)); > + final = build2 (BIT_AND_EXPR, unsigned_intDI_type_node, array_elt, > + build_int_cstu (unsigned_intDI_type_node, field_val)); > return build1 (CONVERT_EXPR, integer_type_node, final); > } > gcc_unreachable (); > diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi > index 2db7bb2..72ccdad 100644 > --- a/gcc/doc/extend.texi > +++ b/gcc/doc/extend.texi > @@ -16894,6 +16894,21 @@ Intel Core i7 Westmere CPU. > @item sandybridge > Intel Core i7 Sandy Bridge CPU. > > +@item ivybridge > +Intel Core i7 Ivy Bridge CPU. > + > +@item haswell > +Intel Core i7 Haswell CPU. > + > +@item broadwell > +Intel Core i7 Broadwell CPU. > + > +@item skylake > +Intel Core i7 Skylake CPU. > + > +@item skylake-avx512 > +Intel Core i7 Skylake CPU with AVX-512 extensions. > + > @item amd > AMD CPU. > > @@ -16968,12 +16983,40 @@ SSSE3 instructions. > SSE4.1 instructions. > @item sse4.2 > SSE4.2 instructions. > +@item aes > +AES instructions. > +@item pclmul > +PCLMUL instructions. > @item avx > AVX instructions. > +@item fma > +FMA instructions. > @item avx2 > AVX2 instructions. > +@item bmi > +BMI instructions. > +@item bmi2 > +BMI2 instructions. > @item avx512f > AVX512F instructions. > +@item avx512bw > +AVX512BW instructions. > +@item avx512dq > +AVX512DQ instructions. > +@item avx512cd > +AVX512CD instructions. > +@item avx512pf > +AVX512PF instructions. > +@item avx512er > +AVX512ER instructions. > +@item avx512ifma > +AVX512IFMA instructions. > +@item avx512vbmi > +AVX512VBMI instructions. > +@item sha > +SHA instructions. > +@item prefetchwt1 > +PREFETCHWT1 instructions. > @end table > > Here is an example: > diff --git a/gcc/testsuite/gcc.target/i386/builtin_target.c > b/gcc/testsuite/gcc.target/i386/builtin_target.c > index dd31108..235c7b5 100644 > --- a/gcc/testsuite/gcc.target/i386/builtin_target.c > +++ b/gcc/testsuite/gcc.target/i386/builtin_target.c > @@ -173,10 +173,6 @@ check_features (unsigned int ecx, unsigned int edx, > 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) > @@ -193,26 +189,61 @@ check_features (unsigned int ecx, unsigned int edx, > { > unsigned int eax, ebx, ecx, edx; > __cpuid_count (7, 0, eax, ebx, ecx, edx); > + if (ebx & bit_FSGSBASE) > + assert (__builtin_cpu_supports ("fsgsbase")); > + if (ebx & bit_BMI) > + assert (__builtin_cpu_supports ("bmi")); > + if (ebx & bit_HLE) > + assert (__builtin_cpu_supports ("hle")); > if (ebx & bit_AVX2) > assert (__builtin_cpu_supports ("avx2")); > + if (ebx & bit_BMI2) > + assert (__builtin_cpu_supports ("bmi2")); > + if (ebx & bit_RTM) > + assert (__builtin_cpu_supports ("rtm")); > + if (ebx & bit_MPX) > + assert (__builtin_cpu_supports ("mpx")); > if (ebx & bit_AVX512F) > assert (__builtin_cpu_supports ("avx512f")); > - if (ebx & bit_AVX512VL) > - assert (__builtin_cpu_supports ("avx512vl")); > - if (ebx & bit_AVX512CD) > - assert (__builtin_cpu_supports ("avx512cd")); > + if (ebx & bit_AVX512DQ) > + assert (__builtin_cpu_supports ("avx512dq")); > + if (ebx & bit_RDSEED) > + assert (__builtin_cpu_supports ("rdseed")); > + if (ebx & bit_ADX) > + assert (__builtin_cpu_supports ("adx")); > + if (ebx & bit_AVX512IFMA) > + assert (__builtin_cpu_supports ("avx512ifma")); > + if (ebx & bit_PCOMMIT) > + assert (__builtin_cpu_supports ("pcommit")); > + if (ebx & bit_CLFLUSHOPT) > + assert (__builtin_cpu_supports ("clflushopt")); > + if (ebx & bit_CLWB) > + assert (__builtin_cpu_supports ("clwb")); > if (ebx & bit_AVX512PF) > assert (__builtin_cpu_supports ("avx512pf")); > if (ebx & bit_AVX512ER) > assert (__builtin_cpu_supports ("avx512er")); > + if (ebx & bit_AVX512CD) > + assert (__builtin_cpu_supports ("avx512cd")); > + if (ebx & bit_SHA) > + assert (__builtin_cpu_supports ("sha")); > if (ebx & bit_AVX512BW) > assert (__builtin_cpu_supports ("avx512bw")); > - if (ebx & bit_AVX512DQ) > - assert (__builtin_cpu_supports ("avx512dq")); > - if (ebx & bit_AVX512IFMA) > - assert (__builtin_cpu_supports ("avx512ifma")); > + if (ebx & bit_AVX512VL) > + assert (__builtin_cpu_supports ("avx512vl")); > + > if (ecx & bit_AVX512VBMI) > assert (__builtin_cpu_supports ("avx512vbmi")); > + if (ecx & bit_PREFETCHWT1) > + assert (__builtin_cpu_supports ("prefetchwt1")); > + > + __cpuid_count (7, 1, eax, ebx, ecx, edx); > + if (eax & bit_XSAVEOPT) > + assert (__builtin_cpu_supports ("xsaveopt")); > + if (eax & bit_XSAVEC) > + assert (__builtin_cpu_supports ("xsavec")); > + if (eax & bit_XSAVES) > + assert (__builtin_cpu_supports ("xsaves")); > } > } > > diff --git a/libgcc/config/i386/cpuinfo.c b/libgcc/config/i386/cpuinfo.c > index 0cbbc85..e928411 100644 > --- a/libgcc/config/i386/cpuinfo.c > +++ b/libgcc/config/i386/cpuinfo.c > @@ -23,6 +23,7 @@ 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/>. */ > > +#include <stdint.h> > #include "cpuid.h" > #include "tsystem.h" > #include "auto-target.h" > @@ -113,7 +114,21 @@ enum processor_features > FEATURE_AVX512ER, > FEATURE_AVX512PF, > FEATURE_AVX512VBMI, > - FEATURE_AVX512IFMA > + FEATURE_AVX512IFMA, > + FEATURE_SHA, > + FEATURE_PREFETCHWT1, > + FEATURE_FSGSBASE, /* 31 */ > + FEATURE_HLE, > + FEATURE_RTM, > + FEATURE_RDSEED, > + FEATURE_ADX, > + FEATURE_MPX, > + FEATURE_CLFLUSHOPT, > + FEATURE_PCOMMIT, > + FEATURE_CLWB, > + FEATURE_XSAVEOPT, > + FEATURE_XSAVEC, > + FEATURE_XSAVES > }; > > struct __processor_model > @@ -121,7 +136,7 @@ struct __processor_model > unsigned int __cpu_vendor; > unsigned int __cpu_type; > unsigned int __cpu_subtype; > - unsigned int __cpu_features[1]; > + uint64_t __cpu_features[1]; > } __cpu_model = { }; > > > @@ -290,64 +305,95 @@ static void > get_available_features (unsigned int ecx, unsigned int edx, > int max_cpuid_level) > { > - unsigned int features = 0; > + uint64_t features = 0; > > if (edx & bit_CMOV) > - features |= (1 << FEATURE_CMOV); > + features |= (1ULL << FEATURE_CMOV); > if (edx & bit_MMX) > - features |= (1 << FEATURE_MMX); > + features |= (1ULL << FEATURE_MMX); > if (edx & bit_SSE) > - features |= (1 << FEATURE_SSE); > + features |= (1ULL << FEATURE_SSE); > if (edx & bit_SSE2) > - features |= (1 << FEATURE_SSE2); > + features |= (1ULL << FEATURE_SSE2); > if (ecx & bit_POPCNT) > - features |= (1 << FEATURE_POPCNT); > + features |= (1ULL << FEATURE_POPCNT); > if (ecx & bit_AES) > - features |= (1 << FEATURE_AES); > + features |= (1ULL << FEATURE_AES); > if (ecx & bit_PCLMUL) > - features |= (1 << FEATURE_PCLMUL); > + features |= (1ULL << FEATURE_PCLMUL); > if (ecx & bit_SSE3) > - features |= (1 << FEATURE_SSE3); > + features |= (1ULL << FEATURE_SSE3); > if (ecx & bit_SSSE3) > - features |= (1 << FEATURE_SSSE3); > + features |= (1ULL << FEATURE_SSSE3); > if (ecx & bit_SSE4_1) > - features |= (1 << FEATURE_SSE4_1); > + features |= (1ULL << FEATURE_SSE4_1); > if (ecx & bit_SSE4_2) > - features |= (1 << FEATURE_SSE4_2); > + features |= (1ULL << FEATURE_SSE4_2); > if (ecx & bit_AVX) > - features |= (1 << FEATURE_AVX); > + features |= (1ULL << FEATURE_AVX); > if (ecx & bit_FMA) > - features |= (1 << FEATURE_FMA); > + features |= (1ULL << FEATURE_FMA); > > /* Get Advanced Features at level 7 (eax = 7, ecx = 0). */ > if (max_cpuid_level >= 7) > { > unsigned int eax, ebx, ecx, edx; > __cpuid_count (7, 0, eax, ebx, ecx, edx); > + if (ebx & bit_FSGSBASE) > + features |= (1ULL << FEATURE_FSGSBASE); > if (ebx & bit_BMI) > - features |= (1 << FEATURE_BMI); > + features |= (1ULL << FEATURE_BMI); > + if (ebx & bit_HLE) > + features |= (1ULL << FEATURE_HLE); > if (ebx & bit_AVX2) > - features |= (1 << FEATURE_AVX2); > + features |= (1ULL << FEATURE_AVX2); > if (ebx & bit_BMI2) > - features |= (1 << FEATURE_BMI2); > + features |= (1ULL << FEATURE_BMI2); > + if (ebx & bit_RTM) > + features |= (1ULL << FEATURE_RTM); > + if (ebx & bit_MPX) > + features |= (1ULL << FEATURE_MPX); > if (ebx & bit_AVX512F) > - features |= (1 << FEATURE_AVX512F); > - if (ebx & bit_AVX512VL) > - features |= (1 << FEATURE_AVX512VL); > - if (ebx & bit_AVX512BW) > - features |= (1 << FEATURE_AVX512BW); > + features |= (1ULL << FEATURE_AVX512F); > if (ebx & bit_AVX512DQ) > - features |= (1 << FEATURE_AVX512DQ); > - if (ebx & bit_AVX512CD) > - features |= (1 << FEATURE_AVX512CD); > + features |= (1ULL << FEATURE_AVX512DQ); > + if (ebx & bit_RDSEED) > + features |= (1ULL << FEATURE_RDSEED); > + if (ebx & bit_ADX) > + features |= (1ULL << FEATURE_ADX); > + if (ebx & bit_AVX512IFMA) > + features |= (1ULL << FEATURE_AVX512IFMA); > + if (ebx & bit_PCOMMIT) > + features |= (1ULL << FEATURE_PCOMMIT); > + if (ebx & bit_CLFLUSHOPT) > + features |= (1ULL << FEATURE_CLFLUSHOPT); > + if (ebx & bit_CLWB) > + features |= (1ULL << FEATURE_CLWB); > if (ebx & bit_AVX512PF) > - features |= (1 << FEATURE_AVX512PF); > + features |= (1ULL << FEATURE_AVX512PF); > if (ebx & bit_AVX512ER) > - features |= (1 << FEATURE_AVX512ER); > - if (ebx & bit_AVX512IFMA) > - features |= (1 << FEATURE_AVX512IFMA); > + features |= (1ULL << FEATURE_AVX512ER); > + if (ebx & bit_AVX512CD) > + features |= (1ULL << FEATURE_AVX512CD); > + if (ebx & bit_SHA) > + features |= (1ULL << FEATURE_SHA); > + if (ebx & bit_AVX512BW) > + features |= (1ULL << FEATURE_AVX512BW); > + if (ebx & bit_AVX512VL) > + features |= (1ULL << FEATURE_AVX512VL); > + > if (ecx & bit_AVX512VBMI) > - features |= (1 << FEATURE_AVX512VBMI); > + features |= (1ULL << FEATURE_AVX512VBMI); > + if (ecx & bit_PREFETCHWT1) > + features |= (1ULL << FEATURE_PREFETCHWT1); > + > + __cpuid_count (7, 1, eax, ebx, ecx, edx); > + if (eax & bit_XSAVEOPT) > + features |= (1ULL << FEATURE_XSAVEOPT); > + if (eax & bit_XSAVEC) > + features |= (1ULL << FEATURE_XSAVEC); > + if (eax & bit_XSAVES) > + features |= (1ULL << FEATURE_XSAVES); > } > > unsigned int ext_level; > @@ -360,11 +406,11 @@ get_available_features (unsigned int ecx, unsigned int > edx, > __cpuid (0x80000001, eax, ebx, ecx, edx); > > if (ecx & bit_SSE4a) > - features |= (1 << FEATURE_SSE4_A); > + features |= (1ULL << FEATURE_SSE4_A); > if (ecx & bit_FMA4) > - features |= (1 << FEATURE_FMA4); > + features |= (1ULL << FEATURE_FMA4); > if (ecx & bit_XOP) > - features |= (1 << FEATURE_XOP); > + features |= (1ULL << FEATURE_XOP); > } > > __cpu_model.__cpu_features[0] = features;