Better cpuid support

Robert Lunnon bobl at
Wed Jan 14 23:11:46 CST 2004

On Thursday 15 January 2004 10:45, Alexandre Julliard wrote:
> Robert Lunnon <bobl at> writes:
> > Improves CPUID instruction support in cpu.c by reorganising the existing
> > FREEBSD code. Added more robust cpuid detection with built in 386
> > detection. Code should work for all i386 platforms and has been tested
> > under solaris. Created subroutines for detecting number of CPUs and OS
> > SSE support as this can't be done in a uniform way across different OSes.
> > Extracted relevant code from each section to perform these OS specific
> > operations (Mostly untested).
> It's hard to tell exactly what has changed, since you basically
> rewrote the whole thing, for no good reason IMO. Could you please
> try to merge your changes with the existing code instead?

 I see no reason to, the code functions perfectly well as it is, I 
restructured it for a couple of reasons.

1. Firstly I had the code available tested and working. Increasing the 
distribution of the code through cpu.c risked breaking it.

2. The code as it stood was hard to understand particularly in seeing what was 
being detected from the cpuid instruction due to hardcoded shifts and masks. 
I think this code is much easier to read ( Especially without the CPUID 
instruction documentation in front of you )

3. Merging was difficult due to the specific calls to OS functions for number 
of cpus and the hardcoded numbers. 

4. The code as it stands is more modular and more extensible/maintainable. For 
example Cyrix or Winchip support should be trivial to add as would support 
for other cpuid extensions (IA64 perhaps)  Only CPUID_GetId should need to be 
changed to support future cpuid extensions assuming the chip manufactures 
follow the same calling conventions.

To assist I will explain the scope of the changes

1. The original cpuid and i386 detect are merged into a single assembly call 
for convenience.

2. The data is then interpreted into a structure for use. Understanding CPUID 
means knowing the cpuid_t structure and CPUID_IsFeatureAvailable call. All 
the specifics are isolated into GetId for maintainablity. 

3. The OS Specifics for testing OS support of multiple CPUs and SSE were moved 
into their own subroutines. This abstracts these functions to permit the code 
in the FREEBSD section to be OS independent. Note that I copied/added code to 
each of these subroutines to support all the platforms that were already 
supported for that feature. Much of this code is currently redundant unless 
someone wants to change the existing linux or NETBSD sections (Which 
currently use other methods). The redundant code was added to allow this to 

3. The information collection and feature tests in the FREEBSD code were 
changed to use cpuid_t and IsFeatureAvailable in a way exactly equivalent to 
the original adding support for detection of PAE and SSE in the process 
(Though OS_SSESupported will need a test for SSE for FREEBSD to work)  There 
is no test for Solaris SSE test since SSE isn't supported at all there (Yet). 
So there isn't a documented way to query it.

5. Finally #elif defined (__FREEBSD__) was changed to #elif defined (__i386__)  
since the code within now works for all i386 platforms. (Ultimately this was 
the objective of the patch)

The #ifdef sections for linux and NETBSD remain unchanged for the moment in 
order to minimise the possibility of me breaking anything.


More information about the wine-devel mailing list