aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2016-09-29 22:49:58 +0200
committerUros Bizjak <uros@gcc.gnu.org>2016-09-29 22:49:58 +0200
commit0a2d7bc05a7de689cb3fde82109e74a0b72e535c (patch)
tree64ef9bbd62abd3d0d71dc9edd66a008d9e621480
parentdd4b238a77c34f2ef1109623da2200793fa45d45 (diff)
downloadgcc-0a2d7bc05a7de689cb3fde82109e74a0b72e535c.zip
gcc-0a2d7bc05a7de689cb3fde82109e74a0b72e535c.tar.gz
gcc-0a2d7bc05a7de689cb3fde82109e74a0b72e535c.tar.bz2
driver-i386.c (host_detect_local_cpu): Check maximum ext_level before calling CPUID with 0x80000008.
* config/i386/driver-i386.c (host_detect_local_cpu): Check maximum ext_level before calling CPUID with 0x80000008. Simplify xgetbv checks. From-SVN: r240637
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/i386/driver-i386.c26
2 files changed, 23 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7264cff..1658dcb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2016-09-29 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/driver-i386.c (host_detect_local_cpu): Check maximum
+ ext_level before calling CPUID with 0x80000008.
+ Simplify xgetbv checks.
+
2016-09-29 David Malcolm <dmalcolm@redhat.com>
* Makefile.in (OBJS): Add print-rtl-function.o.
diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c
index 6d4390f..7460b59 100644
--- a/gcc/config/i386/driver-i386.c
+++ b/gcc/config/i386/driver-i386.c
@@ -517,7 +517,7 @@ const char *host_detect_local_cpu (int argc, const char **argv)
/* 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);
@@ -535,7 +535,10 @@ const char *host_detect_local_cpu (int argc, const char **argv)
has_3dnowp = edx & bit_3DNOWP;
has_3dnow = edx & bit_3DNOW;
has_mwaitx = ecx & bit_MWAITX;
+ }
+ if (ext_level >= 0x80000008)
+ {
__cpuid (0x80000008, eax, ebx, ecx, edx);
has_clzero = ebx & bit_CLZERO;
}
@@ -548,14 +551,21 @@ const char *host_detect_local_cpu (int argc, const char **argv)
#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)
+
if (has_osxsave)
asm (".byte 0x0f; .byte 0x01; .byte 0xd0"
: "=a" (eax), "=d" (edx)
: "c" (XCR_XFEATURE_ENABLED_MASK));
+ else
+ eax = 0;
- /* Check if SSE and YMM states are supported. */
- if (!has_osxsave
- || (eax & (XSTATE_SSE | XSTATE_YMM)) != (XSTATE_SSE | XSTATE_YMM))
+ /* Check if AVX registers are supported. */
+ if ((eax & XCR_AVX_ENABLED_MASK) != XCR_AVX_ENABLED_MASK)
{
has_avx = 0;
has_avx2 = 0;
@@ -569,10 +579,8 @@ const char *host_detect_local_cpu (int argc, const char **argv)
has_xsavec = 0;
}
- if (!has_osxsave
- || (eax &
- (XSTATE_SSE | XSTATE_YMM | XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM))
- != (XSTATE_SSE | XSTATE_YMM | XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM))
+ /* Check if AVX512F registers are supported. */
+ if ((eax & XCR_AVX512F_ENABLED_MASK) != XCR_AVX512F_ENABLED_MASK)
{
has_avx512f = 0;
has_avx512er = 0;
@@ -603,7 +611,7 @@ const char *host_detect_local_cpu (int argc, const char **argv)
unsigned int name;
/* Detect geode processor by its processor signature. */
- if (ext_level > 0x80000001)
+ if (ext_level >= 0x80000002)
__cpuid (0x80000002, name, ebx, ecx, edx);
else
name = 0;