summaryrefslogtreecommitdiff
path: root/gcc/config/i386
diff options
context:
space:
mode:
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>2016-10-04 14:44:16 +0000
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>2016-10-04 14:44:16 +0000
commitc9a5144ff5cba8a9ae311d83f73cdec2c5a25f36 (patch)
treede2c836591f9d6707aa65ac9374de7b5b20e0dc3 /gcc/config/i386
parent38d1d51eca6793e583c91e305c418ec3ed2fc359 (diff)
downloadgcc-c9a5144ff5cba8a9ae311d83f73cdec2c5a25f36.tar.gz
Backport from mainline
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. 2016-09-29 Uros Bizjak <ubizjak@gmail.com> PR target/77756 * config/i386/cpuid.h (__get_cpuid_count): New. (__get_cpuid): Rename __level to __leaf. testsuite/ChangeLog: Backport from mainline 2016-09-29 Uros Bizjak <ubizjak@gmail.com> PR target/77756 * gcc.target/i386/pr77756.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-6-branch@240747 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/i386')
-rw-r--r--gcc/config/i386/cpuid.h28
-rw-r--r--gcc/config/i386/driver-i386.c7
2 files changed, 27 insertions, 8 deletions
diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h
index 8760e60d382..4ea3f74fecd 100644
--- a/gcc/config/i386/cpuid.h
+++ b/gcc/config/i386/cpuid.h
@@ -229,21 +229,37 @@ __get_cpuid_max (unsigned int __ext, unsigned int *__sig)
return __eax;
}
-/* Return cpuid data for requested cpuid level, as found in returned
+/* Return cpuid data for requested cpuid leaf, as found in returned
eax, ebx, ecx and edx registers. The function checks if cpuid is
supported and returns 1 for valid cpuid information or 0 for
- unsupported cpuid level. All pointers are required to be non-null. */
+ unsupported cpuid leaf. All pointers are required to be non-null. */
static __inline int
-__get_cpuid (unsigned int __level,
+__get_cpuid (unsigned int __leaf,
unsigned int *__eax, unsigned int *__ebx,
unsigned int *__ecx, unsigned int *__edx)
{
- unsigned int __ext = __level & 0x80000000;
+ unsigned int __ext = __leaf & 0x80000000;
- if (__get_cpuid_max (__ext, 0) < __level)
+ if (__get_cpuid_max (__ext, 0) < __leaf)
return 0;
- __cpuid (__level, *__eax, *__ebx, *__ecx, *__edx);
+ __cpuid (__leaf, *__eax, *__ebx, *__ecx, *__edx);
+ return 1;
+}
+
+/* Same as above, but sub-leaf can be specified. */
+
+static __inline int
+__get_cpuid_count (unsigned int __leaf, unsigned int __subleaf,
+ unsigned int *__eax, unsigned int *__ebx,
+ unsigned int *__ecx, unsigned int *__edx)
+{
+ unsigned int __ext = __leaf & 0x80000000;
+
+ if (__get_cpuid_max (__ext, 0) < __leaf)
+ return 0;
+
+ __cpuid_count (__leaf, __subleaf, *__eax, *__ebx, *__ecx, *__edx);
return 1;
}
diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c
index a9d5135f678..cb59b0c5754 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;
}
@@ -603,7 +606,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;