diff options
author | uros <uros@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-10-04 14:44:16 +0000 |
---|---|---|
committer | uros <uros@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-10-04 14:44:16 +0000 |
commit | c9a5144ff5cba8a9ae311d83f73cdec2c5a25f36 (patch) | |
tree | de2c836591f9d6707aa65ac9374de7b5b20e0dc3 /gcc/config/i386 | |
parent | 38d1d51eca6793e583c91e305c418ec3ed2fc359 (diff) | |
download | gcc-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.h | 28 | ||||
-rw-r--r-- | gcc/config/i386/driver-i386.c | 7 |
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; |