Detecting x86 Floating Point Coprocessor in Win32

Last reviewed: July 19, 1996
Article ID: Q124207
The information in this article applies to:
  • Microsoft Win32 Application Programming Interface (API) included with:

        - Microsoft Windows NT versions 3.1, 3.5, and 3.51
        - Microsoft Windows 95 version 4.0
    

SUMMARY

In Windows NT (x86) and Windows 95, floating point is emulated by the operating system, in the event that a numeric coprocessor is not present. This allows Win32-based applications to be compiled with floating point instructions present, which will be trapped by the operating system at runtime in the event that a coprocessor is not present. This behavior is transparent to the application, so it is difficult to detect.

In some cases, it is useful to execute code based on the presence of a numeric coprocessor, so this article explains how to do it.

MORE INFORMATION

One approach you can use to detect whether a coprocessor is present is to read the CR0 (System Control Register). This is not possible from Ring 3 application code under Windows NT, so a different approach is outlined below.

To determine whether a coprocessor is present on a computer using the x86 platform running Windows NT, you need to determine if the registry entry HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\FloatingPointProcessor is present. If this key is present, a numeric coprocessor is present.

On the MIPS and Alpha platforms, this registry key is not present because floating point support is built-in. The following function indicates whether a numeric coprocessor is present on Windows NT. If the function returns TRUE, a coprocessor is present. If the function returns FALSE, and GetLastError() indicates ERROR_RESOURCE_DATA_NOT_FOUND, a coprocessor is not present. Otherwise, an error occured while attempting to detect for a coprocessor. Some error checking is omitted, for brevity.

BOOL IsCoProcessorPresent(void) {

    #define MY_ERROR_WRONG_OS 0x20000000
    HKEY hKey;
    SYSTEM_INFO SystemInfo;

    // return FALSE if we are not running under Windows NT
    // this should be expanded to cover alternative Win32 platforms

    if(!(GetVersion() & 0x7FFFFFFF))
    {
        SetLastError(MY_ERROR_WRONG_OS);
        return(FALSE);
    }

    // we return TRUE if we're not running on x86
    // other CPUs have built in floating-point, with no registry entry

    GetSystemInfo(&SystemInfo);

    if((SystemInfo.dwProcessorType != PROCESSOR_INTEL_386) &&
       (SystemInfo.dwProcessorType != PROCESSOR_INTEL_486) &&
       (SystemInfo.dwProcessorType != PROCESSOR_INTEL_PENTIUM))
    {
        return(TRUE);
    }

    if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,

"HARDWARE\\DESCRIPTION\\System\\FloatingPointProcessor",

                    0,
                    KEY_EXECUTE,
                    &hKey) != ERROR_SUCCESS)
    {
        // GetLastError() will indicate ERROR_RESOURCE_DATA_NOT_FOUND
        // if we can't find the key.  This indicates no coprocessor present
        return(FALSE);
    }

    RegCloseKey(hKey);
    return(TRUE);
}


Additional reference words: 3.10 3.50 4.00 x87 math co-processor
coprocessor
KBCategory: kbprg kbcode
KBSubcategory: BseFltpt


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: July 19, 1996
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.