Message ID | 20151006133653.GF56984@msticlxl57.ims.intel.com |
---|---|
State | New |
Headers | show |
On Tue, Oct 6, 2015 at 3:36 PM, Kirill Yukhin <kirill.yukhin@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.yukhin@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;
On Tue, Oct 6, 2015 at 5:15 PM, Uros Bizjak <ubizjak@gmail.com> wrote: > On Tue, Oct 6, 2015 at 3:36 PM, Kirill Yukhin <kirill.yukhin@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. The discussion was at: https://gcc.gnu.org/ml/gcc-patches/2014-12/msg01987.html AES (+ PCLMUL) was later added to multiversioning with the reasoning at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66954 > So, from the list below, I'd take only SHA. Plus fixes/additions in > the documentation and testsuite, of course. Uros.
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;