On Tue, Mar 17, 2026 at 4:41 AM Ewanhaioc <[email protected]> wrote:
>
> From: Ewan <[email protected]>
>
> The __get_cpuid() and __get_cpuid_count() functions use
> "__leaf & 0x80000000" to determine the CPUID range base, which only
> distinguishes between Basic (0x0) and Extended (0x80000000) ranges.
> This causes queries to the Centaur/Zhaoxin range (0xC0000000) to be
> incorrectly mapped to the Extended range, and always return 0 (failure)
> on Centaur/Zhaoxin processors that support CPUID 0xC000xxxx
> leaves (e.g. PadLock feature detection via leaf 0xC0000001).
>
> Replace the bitmask with explicit range checks that correctly identify
> all four CPUID ranges: Basic (0x0), Hypervisor (0x40000000), Extended
> (0x80000000), and Centaur/Zhaoxin (0xC0000000).
>
> Additionally, the Hypervisor range (0x40000000) is also handled as an
> extra improvement, since the original bitmask incorrectly mapped it to
> the Basic range (0x0).
>
> Also update the __get_cpuid_max() comment to document the newly
> supported range base values.
>
> Signed-off-by: Ewanhaioc <[email protected]>

Patch itself is OK, but please repost it with the correct ChangeLog entry.

Uros.

> ---
>  gcc/config/i386/cpuid.h | 29 +++++++++++++++++++++++++----
>  1 file changed, 25 insertions(+), 4 deletions(-)
>
> diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h
> index f493360b1e8..083e4f62498 100644
> --- a/gcc/config/i386/cpuid.h
> +++ b/gcc/config/i386/cpuid.h
> @@ -264,8 +264,9 @@
>
>
>  /* Return highest supported input value for cpuid instruction.  ext can
> -   be either 0x0 or 0x80000000 to return highest supported value for
> -   basic or extended cpuid information.  Function returns 0 if cpuid
> +   be either 0x0, 0x40000000, 0x80000000, or 0xC0000000 to return
> +   highest supported value for basic, hypervisor, extended, or
> +   Centaur/Zhaoxin cpuid information.  Function returns 0 if cpuid
>     is not supported or whatever cpuid returns in eax register.  If sig
>     pointer is non-null, then first four bytes of the signature
>     (as found in ebx register) are returned in location pointed by sig.  */
> @@ -330,7 +331,17 @@ __get_cpuid (unsigned int __leaf,
>              unsigned int *__eax, unsigned int *__ebx,
>              unsigned int *__ecx, unsigned int *__edx)
>  {
> -  unsigned int __ext = __leaf & 0x80000000;
> +  unsigned int __ext;
> +
> +  if (__leaf >= 0xC0000000)
> +    __ext = 0xC0000000;
> +  else if (__leaf >= 0x80000000)
> +    __ext = 0x80000000;
> +  else if (__leaf >= 0x40000000)
> +    __ext = 0x40000000;
> +  else
> +    __ext = 0x00000000;
> +
>    unsigned int __maxlevel = __get_cpuid_max (__ext, 0);
>
>    if (__maxlevel == 0 || __maxlevel < __leaf)
> @@ -347,7 +358,17 @@ __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;
> +  unsigned int __ext;
> +
> +  if (__leaf >= 0xC0000000)
> +    __ext = 0xC0000000;
> +  else if (__leaf >= 0x80000000)
> +    __ext = 0x80000000;
> +  else if (__leaf >= 0x40000000)
> +    __ext = 0x40000000;
> +  else
> +    __ext = 0x00000000;
> +
>    unsigned int __maxlevel = __get_cpuid_max (__ext, 0);
>
>    if (__builtin_expect (__maxlevel == 0, 0) || __maxlevel < __leaf)
> --
> 2.34.1
>

Reply via email to