Detecting x86 Floating Point Coprocessor in Win32

ID: Q124207

3.10 3.50 3.51 | 4.00

WINDOWS NT     | WINDOWS

The information in this article applies to:

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: KBSubcategory: BseFltpt

Keywords          : kbcode kbFloatPoint kbKernBase kbGrpKernBase 
Version           : 3.10 3.50 3.51 | 4.00
Platform          : NT WINDOWS

Last Reviewed: May 23, 1998