From 2488ebe5ef1788616c2fbc61e05af09f0749ebbe Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Thu, 29 Sep 2016 20:44:32 +0200 Subject: [PATCH] re PR target/77756 (__get_cpuid() returns wrong values for level 7 (extended features)) PR target/77756 * config/i386/cpuid.h (__get_cpuid_count): New. (__get_cpuid): Rename __level to __leaf. testsuite/ChangeLog: PR target/77756 * gcc.target/i386/pr77756.c: New test. From-SVN: r240629 --- gcc/ChangeLog | 11 +++---- gcc/config/i386/cpuid.h | 38 ++++++++++++++----------- gcc/testsuite/ChangeLog | 10 +++---- gcc/testsuite/gcc.target/i386/pr77756.c | 2 +- 4 files changed, 34 insertions(+), 27 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b3731d2de97..d9f7844c971 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2016-09-29 Uros Bizjak + + PR target/77756 + * config/i386/cpuid.h (__get_cpuid_count): New. + (__get_cpuid): Rename __level to __leaf. + 2016-09-29 Marek Polacek * genattrtab.c (write_attr_case): Also emit FALLTHRU marker. @@ -100,11 +106,6 @@ get_destination_size, pass_sprintf_length::handle_gimple_call): Likewise. -2016-09-28 Uros Bizjak - - PR target/77756 - * config/i386/cpuid.h (__get_cpuid): Handle CPUID level >= 7. - 2016-09-28 Jakub Jelinek * gimple-ssa-sprintf.c: Fix comment formatting. diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h index a4f658af797..4ea3f74fecd 100644 --- a/gcc/config/i386/cpuid.h +++ b/gcc/config/i386/cpuid.h @@ -229,31 +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; - if (__ext) - __cpuid (__level, *__eax, *__ebx, *__ecx, *__edx); - else - { - if (__level >= 13) - __cpuid_count (__level, 1, *__eax, *__ebx, *__ecx, *__edx); - else if (__level >= 7) - __cpuid_count (__level, 0, *__eax, *__ebx, *__ecx, *__edx); - else - __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/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1a92e7899bb..af688477248 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-09-29 Uros Bizjak + + PR target/77756 + * gcc.target/i386/pr77756.c: New test. + 2016-09-29 Marek Polacek * g++.dg/cpp0x/fallthrough2.C: Use the c++14_down target. @@ -32,11 +37,6 @@ * gcc.dg/profile-update-warning.c: Restrict to ia32. (dg-options): Remove -m32. -2016-09-28 Uros Bizjak - - PR target/77756 - * gcc.target/i386/pr77756.c: New test. - 2016-09-28 Martin Sebor PR middle-end/77721 diff --git a/gcc/testsuite/gcc.target/i386/pr77756.c b/gcc/testsuite/gcc.target/i386/pr77756.c index cd880381006..1eee7cd5a00 100644 --- a/gcc/testsuite/gcc.target/i386/pr77756.c +++ b/gcc/testsuite/gcc.target/i386/pr77756.c @@ -11,7 +11,7 @@ main () { unsigned int eax, ebx, ecx, edx; - if (!__get_cpuid (7, &eax, &ebx, &ecx, &edx)) + if (!__get_cpuid_count (7, 0, &eax, &ebx, &ecx, &edx)) __builtin_abort (); if (!(ebx & bit_AVX2)) -- 2.30.2