Intel 64 and IA-32 Architectures Software Developers Manual Volume 1, Basic Architecture
D-10 Vol. 1
GUIDELINES FOR WRITING X87 FPU EXCEPTION HANDLERS
There are two other ways, in addition to Case 1 above, in which a no-wait floating-
point instruction can service a numeric exception inside its interrupt window. First,
the first floating-point error condition could be of the “immediate” category (as
defined in Section D.2.1.1, “Basic Rules: When FERR# Is Generated”) that asserts
FERR# immediately. If the system delay before asserting INTR is long enough, rela-
tive to the time elapsed before the no-wait floating-point instruction, INTR can be
asserted inside the interrupt window for the latter. Second, consider two no-wait x87
FPU instructions in close sequence, and assume that a previous x87 FPU instruction
has caused an unmasked numeric exception. Then if the INTR timing is too long for
an FERR# signal triggered by the first no-wait instruction to hit the first instruction’s
interrupt window, it could catch the interrupt window of the second.
The possible malfunction of a no-wait x87 FPU instruction explained above cannot
happen if the instruction is being used in the manner for which Intel originally
designed it. The no-wait instructions were intended to be used inside the x87 FPU
exception handler, to allow manipulation of the x87 FPU before the error condition is
cleared, without hanging the processor because of the x87 FPU error condition, and
without the need to assert IGNNE#. They will perform this function correctly, since
before the error condition is cleared, the assertion of FERR# that caused the x87 FPU
error handler to be invoked is still active. Thus the logic that would assert FERR#
briefly at a no-wait instruction causes no change since FERR# is already asserted.
The no-wait instructions may also be used without problem in the handler after the
error condition is cleared, since now they will not cause FERR# to be asserted at all.
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 instructions: 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 iden-
tical 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 recommended for the P6 family and Pentium 4 proces-
sors as well as the two previous generations. The only change to MS-DOS compati-
bility 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,