diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h index e32d87fdc4a..0939e9e6696 100644 --- a/gcc/config/i386/cpuid.h +++ b/gcc/config/i386/cpuid.h @@ -47,28 +47,25 @@ #define bit_SSE (1 << 25) #define bit_SSE2 (1 << 26) -/* Extended Features */ +/* Extended Features (%eax == 0x80000001) */ /* %ecx */ #define bit_LAHF_LM (1 << 0) #define bit_ABM (1 << 5) #define bit_SSE4a (1 << 6) #define bit_PRFCHW (1 << 8) #define bit_XOP (1 << 11) -#define bit_AVX512VPOPCNTDQ (1 << 14) #define bit_LWP (1 << 15) #define bit_FMA4 (1 << 16) #define bit_TBM (1 << 21) #define bit_MWAITX (1 << 29) /* %edx */ -#define bit_AVX5124VNNIW (1 << 2) -#define bit_AVX5124FMAPS (1 << 3) #define bit_MMXEXT (1 << 22) #define bit_LM (1 << 29) #define bit_3DNOWP (1 << 30) #define bit_3DNOW (1 << 31) -/* %ebx. */ +/* %ebx */ #define bit_CLZERO (1 << 0) /* Extended Features (%eax == 7) */ @@ -100,6 +97,11 @@ #define bit_AVX512VBMI (1 << 1) #define bit_PKU (1 << 3) #define bit_OSPKE (1 << 4) +#define bit_AVX512VPOPCNTDQ (1 << 14) + +/* %edx */ +#define bit_AVX5124VNNIW (1 << 2) +#define bit_AVX5124FMAPS (1 << 3) /* XFEATURE_ENABLED_MASK register bits (%eax == 13, %ecx == 0) */ #define bit_BNDREGS (1 << 3) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ba357ffb04a..631a8a3d7ca 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-01-12 Uros Bizjak + + * gcc.target/i386/builtin_target.c (check_features): Check all + supported __builtin_cpu_supports options. + 2017-01-12 Kyrylo Tkachov PR tree-optimization/78319 diff --git a/gcc/testsuite/gcc.target/i386/builtin_target.c b/gcc/testsuite/gcc.target/i386/builtin_target.c index e50695c7091..374f0292453 100644 --- a/gcc/testsuite/gcc.target/i386/builtin_target.c +++ b/gcc/testsuite/gcc.target/i386/builtin_target.c @@ -163,6 +163,9 @@ static void check_features (unsigned int ecx, unsigned int edx, int max_cpuid_level) { + unsigned int eax, ebx; + unsigned int ext_level; + if (edx & bit_CMOV) assert (__builtin_cpu_supports ("cmov")); if (edx & bit_MMX) @@ -187,38 +190,58 @@ check_features (unsigned int ecx, unsigned int edx, assert (__builtin_cpu_supports ("sse4.2")); if (ecx & bit_AVX) assert (__builtin_cpu_supports ("avx")); + if (ecx & bit_FMA) + assert (__builtin_cpu_supports ("fma")); /* Get advanced features at level 7 (eax = 7, ecx = 0). */ if (max_cpuid_level >= 7) { - unsigned int eax, ebx, ecx, edx; __cpuid_count (7, 0, eax, ebx, ecx, edx); + if (ebx & bit_BMI) + assert (__builtin_cpu_supports ("bmi")); if (ebx & bit_AVX2) assert (__builtin_cpu_supports ("avx2")); + if (ebx & bit_BMI2) + assert (__builtin_cpu_supports ("bmi2")); if (ebx & bit_AVX512F) assert (__builtin_cpu_supports ("avx512f")); if (ebx & bit_AVX512VL) assert (__builtin_cpu_supports ("avx512vl")); + if (ebx & bit_AVX512BW) + assert (__builtin_cpu_supports ("avx512bw")); + if (ebx & bit_AVX512DQ) + assert (__builtin_cpu_supports ("avx512dq")); if (ebx & bit_AVX512CD) assert (__builtin_cpu_supports ("avx512cd")); if (ebx & bit_AVX512PF) assert (__builtin_cpu_supports ("avx512pf")); if (ebx & bit_AVX512ER) assert (__builtin_cpu_supports ("avx512er")); - if (ebx & bit_AVX512BW) - assert (__builtin_cpu_supports ("avx512bw")); - if (ebx & bit_AVX512DQ) - assert (__builtin_cpu_supports ("avx512dq")); - if (ecx & bit_AVX512IFMA) + if (ebx & bit_AVX512IFMA) assert (__builtin_cpu_supports ("avx512ifma")); if (ecx & bit_AVX512VBMI) assert (__builtin_cpu_supports ("avx512vbmi")); + if (ecx & bit_AVX512VPOPCNTDQ) + assert (__builtin_cpu_supports ("avx512vpopcntdq")); if (edx & bit_AVX5124VNNIW) assert (__builtin_cpu_supports ("avx5124vnniw")); if (edx & bit_AVX5124FMAPS) assert (__builtin_cpu_supports ("avx5124fmaps")); - if (ecx & bit_AVX512VPOPCNTDQ) - assert (__builtin_cpu_supports ("avx512vpopcntdq")); + } + + /* Check cpuid level of extended features. */ + __cpuid (0x80000000, ext_level, ebx, ecx, edx); + + if (ext_level >= 0x80000001) + { + __cpuid (0x80000001, eax, ebx, ecx, edx); + + if (ecx & bit_SSE4a) + assert (__builtin_cpu_supports ("sse4a")); + if (ecx & bit_FMA4) + assert (__builtin_cpu_supports ("fma4")); + if (ecx & bit_XOP) + assert (__builtin_cpu_supports ("xop")); } } diff --git a/libgcc/config/i386/cpuinfo.c b/libgcc/config/i386/cpuinfo.c index 737d1aa14bd..a1dc011525f 100644 --- a/libgcc/config/i386/cpuinfo.c +++ b/libgcc/config/i386/cpuinfo.c @@ -215,6 +215,9 @@ 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; if (edx & bit_CMOV) @@ -247,7 +250,6 @@ get_available_features (unsigned int ecx, unsigned int edx, /* 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_BMI) features |= (1 << FEATURE_BMI); @@ -273,20 +275,18 @@ get_available_features (unsigned int ecx, unsigned int edx, features |= (1 << FEATURE_AVX512IFMA); if (ecx & bit_AVX512VBMI) features |= (1 << FEATURE_AVX512VBMI); + if (ecx & bit_AVX512VPOPCNTDQ) + features |= (1 << FEATURE_AVX512VPOPCNTDQ); if (edx & bit_AVX5124VNNIW) features |= (1 << FEATURE_AVX5124VNNIW); if (edx & bit_AVX5124FMAPS) features |= (1 << FEATURE_AVX5124FMAPS); - if (ecx & bit_AVX512VPOPCNTDQ) - features |= (1 << FEATURE_AVX512VPOPCNTDQ); } - unsigned int ext_level; - unsigned int eax, ebx; /* Check cpuid level of extended features. */ __cpuid (0x80000000, ext_level, ebx, ecx, edx); - if (ext_level > 0x80000000) + if (ext_level >= 0x80000001) { __cpuid (0x80000001, eax, ebx, ecx, edx);