[PATCH, i386]: Fix PR 77756, _-get_cpuid() returns wrong values for level 7 (extended features)
Uros Bizjak
ubizjak@gmail.com
Thu Sep 29 18:58:00 GMT 2016
On Wed, Sep 28, 2016 at 11:32 PM, Uros Bizjak <ubizjak@gmail.com> wrote:
> 2016-09-28 Uros Bizjak <ubizjak@gmail.com>
I have reverted my previous patch and committed the following:
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:
2016-09-29 Uros Bizjak <ubizjak@gmail.com>
PR target/77756
* gcc.target/i386/pr77756.c: New test.
Patch was bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.
Committed to mainline, will be backported to release branches.
Uros.
-------------- next part --------------
Index: config/i386/cpuid.h
===================================================================
--- config/i386/cpuid.h (revision 240626)
+++ config/i386/cpuid.h (working copy)
@@ -229,31 +229,37 @@
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;
+}
Index: testsuite/gcc.target/i386/pr77756.c
===================================================================
--- testsuite/gcc.target/i386/pr77756.c (revision 240626)
+++ testsuite/gcc.target/i386/pr77756.c (working copy)
@@ -11,7 +11,7 @@
{
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))
More information about the Gcc-patches
mailing list