background image

Vol. 1 D-7

GUIDELINES FOR WRITING X87 FPU EXCEPTION HANDLERS

If a no-wait instruction is used outside of the x87 FPU exception handler, it may malfunction as explained above, 
depending on the details of the hardware interface implementation and which particular processor is involved. The 
actual interrupt inside the window in the no-wait instruction may be blocked by surrounding it with the instruc-
tions: PUSHFD, CLI, no-wait, then POPFD. (CLI blocks interrupts, and the push and pop of flags preserves and 
restores the original value of the interrupt flag.) However, if FERR# was triggered by the no-wait, its latched value 
and the PIC response will still be in effect. Further code can be used to check for and correct such a condition, if 
needed. Section D.3.6, “Considerations When x87 FPU Shared Between Tasks,” discusses an important example of 
this type of problem and gives a solution.

D.2.2  

MS-DOS* Compatibility Sub-mode in the P6 Family 

and Pentium® 4 Processors

When bit NE = 0 in CR0, the MS-DOS compatibility mode of the P6 family and Pentium 4 processors provides 
FERR# and IGNNE# functionality that is almost identical to the Intel486 and Pentium processors. The same 
external hardware described in Section D.2.1.2, “Recommended External Hardware to Support the MS-DOS* 
Compatibility Sub-mode,” is recommende
d for the P6 family and Pentium 4 processors as well as the two previous 
generations. The only change to MS-DOS compatibility x87 FPU exception handling with the P6 family and Pentium 
4 processors is that all exceptions for all x87 FPU instructions cause immediate error reporting. That is, FERR# is 
asserted as soon as the x87 FPU detects an unmasked exception; there are no cases in which error reporting is 
deferred to the next x87 FPU or WAIT instruction. 
(As is discussed in Section D.2.1.1, “Basic Rules: When FERR# Is Generated,” most exception cases in the Intel486 
and Pentium processors are of the deferred type.)
Although FERR# is asserted immediately upon detection of an unmasked x87 FPU error, this certainly does not 
mean that the requested interrupt will always be serviced before the next instruction in the code sequence is 
executed. To begin with, the P6 family and Pentium 4 processors execute several instructions simultaneously. 
There also will be a delay, which depends on the external hardware implementation, between the FERR# assertion 
from the processor and the responding INTR assertion to the processor. Further, the interrupt request to the PICs 
(IRQ13) may be temporarily blocked by the operating system, or delayed by higher priority interrupts, and 
processor response to INTR itself is blocked if the operating system has cleared the IF bit in EFLAGS. Note that 
Streaming SIMD Extensions numeric exceptions will not cause assertion of FERR# (independent of the value of 
CR0.NE). In addition, they ignore the assertion/deassertion of IGNNE#).
However, just as with the Intel486 and Pentium processors, if the IGNNE# input is inactive, a floating-point excep-
tion which occurred in the previous x87 FPU instruction and is unmasked causes the processor to freeze immedi-
ately when encountering the next WAIT or x87 FPU instruction (except for no-wait instructions). This means that if 
the x87 FPU exception handler has not already been invoked due to the earlier exception (and therefore, the 
handler not has cleared that exception state from the x87 FPU), the processor is forced to wait for the handler to 
be invoked and handle the exception, before the processor can execute another WAIT or x87 FPU instruction. 
As explained in Section D.2.1.3, “No-Wait x87 FPU Instructions Can Get x87 FPU Interrupt in Window,” if a no-wait 
instruction is used outside of the x87 FPU exception handler, in the Intel486 and Pentium processors, it may accept 
an unmasked exception from a previous x87 FPU instruction which happens to fall within the external interrupt 
sampling window that is opened near the beginning of execution of all x87 FPU instructions. This will not happen in 
the P6 family and Pentium 4 processors, because this sampling window has been removed from the no-wait group 
of x87 FPU instructions.

D.3 RECOMMENDED 

PROTOCOL 

FOR 

MS-DOS* COMPATIBILITY HANDLERS

The activities of numeric programs can be split into two major areas: program control and arithmetic. The program 
control part performs activities such as deciding what functions to perform, calculating addresses of numeric oper-
ands, and loop control. The arithmetic part simply adds, subtracts, multiplies, and performs other operations on 
the numeric operands. The processor is designed to handle these two parts separately and efficiently. An x87 FPU 
exception handler, if a system chooses to implement one, is often one of the most complicated parts of the program 
control code.