background image

Vol. 1 8-9

PROGRAMMING WITH THE X87 FPU

The x87 FPU uses the tag values to detect stack overflow and underflow conditions (see Section 8.5.1.1, “Stack 
Overflow or Underflow Exception (#IS)”).
Application programs and exception handlers can use this tag information to check the contents of an x87 FPU data 
register without performing complex decoding of the actual data in the register. To read the tag register, it must be 
stored in memory using either the FSTENV/FNSTENV or FSAVE/FNSAVE instructions. The location of the tag word 
in memory after being saved with one of these instructions is shown in Figures 8-9 through 8-12.
Software cannot directly load or modify the tags in the tag register. The FLDENV and FRSTOR instructions load an 
image of the tag register into the x87 FPU; however, the x87 FPU uses those tag values only to determine if the 
data registers are empty (11B) or non-empty (00B, 01B, or 10B). 
If the tag register image indicates that a data register is empty, the tag in the tag register for that data register is 
marked empty (11B); if the tag register image indicates that the data register is non-empty, the x87 FPU reads the 
actual value in the data register and sets the tag for the register accordingly. This action prevents a program from 
setting the values in the tag register to incorrectly represent the actual contents of non-empty data registers.

8.1.8 

x87 FPU Instruction and Data (Operand) Pointers

The x87 FPU stores pointers to the instruction and data (operand) for the last non-control instruction executed. 
These are the x87 FPU instruction pointer and x87 FPU data (operand) pointers; software can save these pointers 
to provide state information for exception handlers. The pointers are illustrated in Figure 8-1 (the figure illustrates 
the pointers as used outside 64-bit mode; see below).
Note that the value in the x87 FPU data pointer is always a pointer to a memory operand. If the last non-control 
instruction that was executed did not have a memory operand, the value in the data pointer is undefined 
(reserved). If CPUID.(EAX=07H,ECX=0H):EBX[bit 6] = 1, the data pointer is updated only for x87 non-control 
instructions that incur unmasked x87 exceptions.
The contents of the x87 FPU instruction and data pointers remain unchanged when any of the following instructions 
are executed: FCLEX/FNCLEX, FLDCW, FSTCW/FNSTCW, FSTSW/FNSTSW, FSTENV/FNSTENV, FLDENV, and 
WAIT/FWAIT.
For all the x87 FPUs and NPXs except the 8087, the x87 FPU instruction pointer points to any prefixes that preceded 
the instruction. For the 8087, the x87 FPU instruction pointer points only to the actual opcode.
The x87 FPU instruction and data pointers each consists of an offset and a segment selector:

•

The x87 FPU Instruction Pointer Offset (FIP) comprises 64 bits on processors that support IA-32e mode; on 
other processors, it offset comprises 32 bits.

•

The x87 FPU Instruction Pointer Selector (FCS) comprises 16 bits.

•

The x87 FPU Data Pointer Offset (FDP) comprises 64 bits on processors that support IA-32e mode; on other 
processors, it offset comprises 32 bits.

•

The x87 FPU Data Pointer Selector (FDS) comprises 16 bits.

The pointers are accessed by the FINIT/FNINIT, FLDENV, FRSTOR, FSAVE/FNSAVE, FSTENV/FNSTENV, FXRSTOR, 
FXSAVE, XRSTOR, XSAVE, and XSAVEOPT instructions as follows:

•

FINIT/FNINIT. Each instruction clears FIP, FCS, FDP, and FDS.

•

FLDENV, FRSTOR. These instructions use the memory formats given in Figures 8-9 through 8-12:
— For each of FIP and FDP, each instruction loads the lower 32 bits from memory and clears the upper 32 bits.
— If CR0.PE = 1, each instruction loads FCS and FDS from memory; otherwise, it clears them.

•

FSAVE/FNSAVE, FSTENV/FNSTENV. These instructions use the memory formats given in Figures 8-9 through 
8-12.
— Each instruction saves the lower 32 bits of each FIP and FDP into memory. the upper 32 bits are not saved.
— If CR0.PE = 1, each instruction saves FCS and FDS into memory. If 

CPUID.(EAX=07H,ECX=0H):EBX[bit 13] = 1, the processor deprecates FCS and FDS; it saves each as 
0000H.

— After saving these data into memory, FSAVE/FNSAVE clears FIP, FCS, FDP, and FDS.