Uros,

On Mon, May 20, 2019 at 3:29 AM Uros Bizjak <ubiz...@gmail.com> wrote:
> The CPUID documentation from Intel Architectures Developer's manual is
> crystal clear on the implementation:
>
> --quote--
> CPUID—CPU Identification
>
> Returns processor identification and feature
> information to the EAX, EBX, ECX, and EDX
> registers, as determined by input entered in
> EAX (in some cases, ECX as well).
> --quote--

That is for the current versions of the documentation. Earlier versions are
different (see below).

> So, I dont see why we should implement the workaround for an
> implementation bug in a widely used header for a relatively obscure
> target. Please also note that there are other places in the compiler
> that assume that the instruction returns values as specified above,
> not to mention other applications that assumes the same.
>
> I think proposed target specific bugfix should be implemented
> elsewhere, not in the cpuid.h header that assumes the specified
> functionality.

I did some research and found the Intel CPUID document that existed when
the WinChip was manufactured (dated December 1996):

http://bitsavers.trailing-edge.com/components/intel/appNotes/AP-485_Intel_Processor_Identification_and_the_CPUID_Instruction_Dec96.pdf

It is ALSO silent about the contents of %ebx and %ecx after a cpuid() with
%eax = 1. The Winchip met the Intel _published_ standard that existed at
the time. Intel changed the standard a long time afterwards.

This means that all the following processor manufacturers (and example
cpus) of that era might demonstrate this behavior:

AMD (Am486 DX2/DX4, Am5x86, K5)
Centaur (WinChip C6, Winchip 2)
NexGen (Nx586)
Cyrix (Cx486DX2/DX4, 5x86, 6x86, 6x86MX)

That is a lot of processors. Admittedly they are old, but they are still
officially supported by GNU/Linux.

Since the patch only introduces four (4) more opcodes, it is not
computationally expensive. Here is the diff:

  test   $0x200000,%eax
  je     0xb7e214c0 <rdrand+128>
- xor    %eax,%eax
+ xor    %edi,%edi
+ mov    %edi,%eax
  cpuid
  test   %eax,%eax
  je     0xb7e214c0 <rdrand+128>
+ mov    %edi,%ebx
+ mov    %edi,%ecx
+ mov    %edi,%edx
  mov    $0x1,%eax
  cpuid

Lastly, this is just an example of "initialized your variables before you
use them".

- Matthew

Reply via email to