diff mbox

[i386] Add missing entries to cpuinfo.

Message ID 20151006133653.GF56984@msticlxl57.ims.intel.com
State New
Headers show

Commit Message

Kirill Yukhin Oct. 6, 2015, 1:36 p.m. UTC
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?

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.

Comments

Uros Bizjak Oct. 6, 2015, 3:15 p.m. UTC | #1
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;
Uros Bizjak Oct. 7, 2015, 9:37 a.m. UTC | #2
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 mbox

Patch

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;