# instructions

platform: x86_64
mnem: FFREE
description:
FFREE-Free Floating-Point Register
Opcode             Instruction              64-Bit    Compat/       Description
                                            Mode      Leg Mode
DD C0+i            FFREE ST(i)              Valid     Valid         Sets tag for ST(i) to empty.



Description
Sets the tag in the FPU tag register associated with register ST(i) to empty (11B). The contents of ST(i) and the FPU
stack-top pointer (TOP) are not affected.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
TAG(i) <- 11B;

FPU Flags Affected
C0, C1, C2, C3 undefined.

Floating-Point Exceptions
None

Protected Mode Exceptions
#NM                  CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                  If there is a pending x87 FPU exception.
#UD                  If the LOCK prefix is used.

Real-Address Mode Exceptions
Same exceptions as in protected mode.

Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: FICOM
description:
FICOM/FICOMP-Compare Integer
 Opcode                Instruction              64-Bit   Compat/    Description
                                                Mode     Leg Mode
 DE /2                 FICOM m16int             Valid    Valid      Compare ST(0) with m16int.
 DA /2                 FICOM m32int             Valid    Valid      Compare ST(0) with m32int.
 DE /3                 FICOMP m16int            Valid    Valid      Compare ST(0) with m16int and pop stack register.
 DA /3                 FICOMP m32int            Valid    Valid      Compare ST(0) with m32int and pop stack register.



Description
Compares the value in ST(0) with an integer source operand and sets the condition code flags C0, C2, and C3 in
the FPU status word according to the results (see table below). The integer value is converted to double extended-
precision floating-point format before the comparison is made.
                                          Table 3-26. FICOM/FICOMP Results
                      Condition                          C3                       C2                      C0
                      ST(0) > SRC                         0                       0                        0
                     ST(0) < SRC                          0                       0                        1
                     ST(0) = SRC                          1                       0                        0
                      Unordered                           1                       1                        1

These instructions perform an "unordered comparison." An unordered comparison also checks the class of the
numbers being compared (see "FXAM-Examine Floating-Point" in this chapter). If either operand is a NaN or is in
an undefined format, the condition flags are set to "unordered."
The sign of zero is ignored, so that -0.0 <- +0.0.
The FICOMP instructions pop the register stack following the comparison. To pop the register stack, the processor
marks the ST(0) register empty and increments the stack pointer (TOP) by 1.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
CASE (relation of operands) OF
   ST(0) > SRC:       C3, C2, C0 <- 000;
   ST(0) < SRC:       C3, C2, C0 <- 001;
   ST(0) = SRC:       C3, C2, C0 <- 100;
   Unordered:         C3, C2, C0 <- 111;
ESAC;

IF Instruction = FICOMP
     THEN
         PopRegisterStack;
FI;

FPU Flags Affected
C1                     Set to 0.
C0, C2, C3             See table on previous page.

Floating-Point Exceptions
#IS                    Stack underflow occurred.
#IA                    One or both operands are NaN values or have unsupported formats.
#D                     One or both operands are denormal values.



Protected Mode Exceptions
#GP(0)              If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                    If the DS, ES, FS, or GS register contains a NULL segment selector.
#SS(0)              If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                 If the LOCK prefix is used.

Real-Address Mode Exceptions
#GP                 If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS                 If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#UD                 If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
#GP(0)              If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)              If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made.
#UD                 If the LOCK prefix is used.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#SS(0)              If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)              If the memory address is in a non-canonical form.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                 If there is a pending x87 FPU exception.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                 If the LOCK prefix is used.






platform: x86_64
mnem: FILD
description:
FILD-Load Integer
 Opcode               Instruction          64-Bit    Compat/      Description
                                           Mode      Leg Mode
 DF /0                FILD m16int          Valid     Valid        Push m16int onto the FPU register stack.
 DB /0                FILD m32int          Valid     Valid        Push m32int onto the FPU register stack.
 DF /5                FILD m64int          Valid     Valid        Push m64int onto the FPU register stack.



Description
Converts the signed-integer source operand into double extended-precision floating-point format and pushes the
value onto the FPU register stack. The source operand can be a word, doubleword, or quadword integer. It is loaded
without rounding errors. The sign of the source operand is preserved.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
TOP <- TOP - 1;
ST(0) <- ConvertToDoubleExtendedPrecisionFP(SRC);

FPU Flags Affected
C1                   Set to 1 if stack overflow occurred; set to 0 otherwise.
C0, C2, C3           Undefined.

Floating-Point Exceptions
#IS                  Stack overflow occurred.

Protected Mode Exceptions
#GP(0)               If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                     If the DS, ES, FS, or GS register contains a NULL segment selector.
#SS(0)               If a memory operand effective address is outside the SS segment limit.
#NM                  CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)      If a page fault occurs.
#AC(0)               If alignment checking is enabled and an unaligned memory reference is made while the
                     current privilege level is 3.
#UD                  If the LOCK prefix is used.

Real-Address Mode Exceptions
#GP                  If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS                  If a memory operand effective address is outside the SS segment limit.
#NM                  CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#UD                  If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
#GP(0)               If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)               If a memory operand effective address is outside the SS segment limit.
#NM                  CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)      If a page fault occurs.
#AC(0)               If alignment checking is enabled and an unaligned memory reference is made.
#UD                  If the LOCK prefix is used.




Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#SS(0)              If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)              If the memory address is in a non-canonical form.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                 If there is a pending x87 FPU exception.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                 If the LOCK prefix is used.






platform: x86_64
mnem: FINCSTP
description:
FINCSTP-Increment Stack-Top Pointer
 Opcode                 Instruction        64-Bit     Compat/      Description
                                           Mode       Leg Mode
 D9 F7                  FINCSTP            Valid      Valid        Increment the TOP field in the FPU status register.



Description
Adds one to the TOP field of the FPU status word (increments the top-of-stack pointer). If the TOP field contains a
7, it is set to 0. The effect of this instruction is to rotate the stack by one position. The contents of the FPU data
registers and tag register are not affected. This operation is not equivalent to popping the stack, because the tag
for the previous top-of-stack register is not marked empty.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
IF TOP = 7
    THEN TOP <- 0;
    ELSE TOP <- TOP + 1;
FI;

FPU Flags Affected
The C1 flag is set to 0. The C0, C2, and C3 flags are undefined.

Floating-Point Exceptions
None

Protected Mode Exceptions
#NM                     CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                     If there is a pending x87 FPU exception.
#UD                     If the LOCK prefix is used.

Real-Address Mode Exceptions
Same exceptions as in protected mode.

Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: FINIT
description:
FINIT/FNINIT-Initialize Floating-Point Unit
Opcode               Instruction              64-Bit    Compat/    Description
                                              Mode      Leg Mode
9B DB E3             FINIT                    Valid     Valid      Initialize FPU after checking for pending unmasked
                                                                   floating-point exceptions.
DB E3                FNINIT*                  Valid     Valid      Initialize FPU without checking for pending unmasked
                                                                   floating-point exceptions.
NOTES:
* See IA-32 Architecture Compatibility section below.



Description
Sets the FPU control, status, tag, instruction pointer, and data pointer registers to their default states. The FPU
control word is set to 037FH (round to nearest, all exceptions masked, 64-bit precision). The status word is cleared
(no exception flags set, TOP is set to 0). The data registers in the register stack are left unchanged, but they are all
tagged as empty (11B). Both the instruction and data pointers are cleared.
The FINIT instruction checks for and handles any pending unmasked floating-point exceptions before performing
the initialization; the FNINIT instruction does not.
The assembler issues two instructions for the FINIT instruction (an FWAIT instruction followed by an FNINIT
instruction), and the processor executes each of these instructions in separately. If an exception is generated for
either of these instructions, the save EIP points to the instruction that caused the exception.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

IA-32 Architecture Compatibility
When operating a Pentium or Intel486 processor in MS-DOS compatibility mode, it is possible (under unusual
circumstances) for an FNINIT instruction to be interrupted prior to being executed to handle a pending FPU excep-
tion. See the section titled "No-Wait FPU Instructions Can Get FPU Interrupt in Window" in Appendix D of the Intel
64 and IA-32 Architectures Software Developer's Manual, Volume 1, for a description of these circumstances. An
FNINIT instruction cannot be interrupted in this way on later Intel processors, except for the Intel QuarkTM X1000
processor.
In the Intel387 math coprocessor, the FINIT/FNINIT instruction does not clear the instruction and data pointers.
This instruction affects only the x87 FPU. It does not affect the XMM and MXCSR registers.

Operation
FPUControlWord <- 037FH;
FPUStatusWord <- 0;
FPUTagWord <- FFFFH;
FPUDataPointer <- 0;
FPUInstructionPointer <- 0;
FPULastInstructionOpcode <- 0;

FPU Flags Affected
C0, C1, C2, C3 set to 0.

Floating-Point Exceptions
None





Protected Mode Exceptions
#NM                        CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                        If there is a pending x87 FPU exception.
#UD                        If the LOCK prefix is used.

Real-Address Mode Exceptions
Same exceptions as in protected mode.

Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: FIST
description:
FIST/FISTP-Store Integer
Opcode                     Instruction                64-Bit    Compat/       Description
                                                      Mode      Leg Mode
DF /2                      FIST m16int                Valid     Valid         Store ST(0) in m16int.
DB /2                      FIST m32int                Valid     Valid         Store ST(0) in m32int.
DF /3                      FISTP m16int               Valid     Valid         Store ST(0) in m16int and pop register stack.
DB /3                      FISTP m32int               Valid     Valid         Store ST(0) in m32int and pop register stack.
DF /7                      FISTP m64int               Valid     Valid         Store ST(0) in m64int and pop register stack.



Description
The FIST instruction converts the value in the ST(0) register to a signed integer and stores the result in the desti-
nation operand. Values can be stored in word or doubleword integer format. The destination operand specifies the
address where the first byte of the destination value is to be stored.
The FISTP instruction performs the same operation as the FIST instruction and then pops the register stack. To pop
the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1.
The FISTP instruction also stores values in quadword integer format.
The following table shows the results obtained when storing various classes of numbers in integer format.
                                                 Table 3-27. FIST/FISTP Results
                             ST(0)                                                          DEST
           - inf or Value Too Large for DEST Format                                            *
                             F <= -1                                                          -I
                          -1 < F < -0                                                        **
                              -0                                                             0
                              +0                                                             0
                         +0<F<+1                                                             **
                            F>=+1                                                             +I
           + inf or Value Too Large for DEST Format                                            *
                              NaN                                                            *
NOTES:
F Means finite floating-point value.
I Means integer.
* Indicates floating-point invalid-operation (#IA) exception.
** 0 or +-1, depending on the rounding mode.


If the source value is a non-integral value, it is rounded to an integer value, according to the rounding mode spec-
ified by the RC field of the FPU control word.
If the converted value is too large for the destination format, or if the source operand is an inf, SNaN, QNAN, or is in
an unsupported format, an invalid-arithmetic-operand condition is signaled. If the invalid-operation exception is
not masked, an invalid-arithmetic-operand exception (#IA) is generated and no value is stored in the destination
operand. If the invalid-operation exception is masked, the integer indefinite value is stored in memory.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.





Operation
DEST <- Integer(ST(0));

IF Instruction = FISTP
     THEN
         PopRegisterStack;
FI;

FPU Flags Affected
C1                         Set to 0 if stack underflow occurred.
                           Indicates rounding direction of if the inexact exception (#P) is generated: 0 <- not roundup; 1
                           <- roundup.
                           Set to 0 otherwise.
C0, C2, C3                 Undefined.

Floating-Point Exceptions
#IS                        Stack underflow occurred.
#IA                        Converted value is too large for the destination format.
                           Source operand is an SNaN, QNaN, +-inf, or unsupported format.
#P                         Value cannot be represented exactly in destination format.

Protected Mode Exceptions
#GP(0)                     If the destination is located in a non-writable segment.
                           If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                           If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment
                           selector.
#SS(0)                     If a memory operand effective address is outside the SS segment limit.
#NM                        CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)            If a page fault occurs.
#AC(0)                     If alignment checking is enabled and an unaligned memory reference is made while the
                           current privilege level is 3.
#UD                        If the LOCK prefix is used.

Real-Address Mode Exceptions
#GP                        If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS                        If a memory operand effective address is outside the SS segment limit.
#NM                        CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#UD                        If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
#GP(0)                     If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)                     If a memory operand effective address is outside the SS segment limit.
#NM                        CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)            If a page fault occurs.
#AC(0)                     If alignment checking is enabled and an unaligned memory reference is made.
#UD                        If the LOCK prefix is used.

Compatibility Mode Exceptions
Same exceptions as in protected mode.




64-Bit Mode Exceptions
#SS(0)              If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)              If the memory address is in a non-canonical form.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                 If there is a pending x87 FPU exception.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                 If the LOCK prefix is used.






platform: x86_64
mnem: FISTTP
description:
FISTTP-Store Integer with Truncation
 Opcode                 Instruction                  64-Bit Mode Compat/         Description
                                                                 Leg Mode
 DF /1                  FISTTP m16int                Valid      Valid            Store ST(0) in m16int with truncation.
 DB /1                  FISTTP m32int                Valid      Valid            Store ST(0) in m32int with truncation.
 DD /1                  FISTTP m64int                Valid      Valid            Store ST(0) in m64int with truncation.



Description
FISTTP converts the value in ST into a signed integer using truncation (chop) as rounding mode, transfers the
result to the destination, and pop ST. FISTTP accepts word, short integer, and long integer destinations.
The following table shows the results obtained when storing various classes of numbers in integer format.
                                                    Table 3-28. FISTTP Results
                               ST(0)                                                           DEST
- inf or Value Too Large for DEST Format                                                          *
F<= -1                                                                                           -I
-1<F<+1                                                                                         0
FS+1                                                                                            +I
+ inf or Value Too Large for DEST Format                                                          *
NaN                                                                                             *
NOTES:
F Means finite floating-point value.
I Means integer.
* Indicates floating-point invalid-operation (#IA) exception.

This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
DEST <- ST;
pop ST;

Flags Affected
C1 is cleared; C0, C2, C3 undefined.

Numeric Exceptions
Invalid, Stack Invalid (stack underflow), Precision.

Protected Mode Exceptions
#GP(0)                   If the destination is in a nonwritable segment.
                         For an illegal memory operand effective address in the CS, DS, ES, FS or GS segments.
#SS(0)                   For an illegal address in the SS segment.
#PF(fault-code)          For a page fault.
#AC(0)                   If alignment checking is enabled and an unaligned memory reference is made while the
                         current privilege level is 3.
#NM                      If CR0.EM[bit 2] = 1.
                         If CR0.TS[bit 3] = 1.
#UD                      If CPUID.01H:ECX.SSE3[bit 0] = 0.
                         If the LOCK prefix is used.



Real Address Mode Exceptions
GP(0)               If any part of the operand would lie outside of the effective address space from 0 to 0FFFFH.
#NM                 If CR0.EM[bit 2] = 1.
                    If CR0.TS[bit 3] = 1.
#UD                 If CPUID.01H:ECX.SSE3[bit 0] = 0.
                    If the LOCK prefix is used.

Virtual 8086 Mode Exceptions
GP(0)               If any part of the operand would lie outside of the effective address space from 0 to 0FFFFH.
#NM                 If CR0.EM[bit 2] = 1.
                    If CR0.TS[bit 3] = 1.
#UD                 If CPUID.01H:ECX.SSE3[bit 0] = 0.
                    If the LOCK prefix is used.
#PF(fault-code)     For a page fault.
#AC(0)              For unaligned memory reference if the current privilege is 3.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#SS(0)              If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)              If the memory address is in a non-canonical form.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                 If there is a pending x87 FPU exception.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
                    If the LOCK prefix is used.






platform: x86_64
mnem: FLD
description:
FLD-Load Floating Point Value
 Opcode                   Instruction        64-Bit   Compat/     Description
                                             Mode     Leg Mode
 D9 /0                    FLD m32fp          Valid    Valid       Push m32fp onto the FPU register stack.
 DD /0                    FLD m64fp          Valid    Valid       Push m64fp onto the FPU register stack.
 DB /5                    FLD m80fp          Valid    Valid       Push m80fp onto the FPU register stack.
 D9 C0+i                  FLD ST(i)          Valid    Valid       Push ST(i) onto the FPU register stack.



Description
Pushes the source operand onto the FPU register stack. The source operand can be in single-precision, double-
precision, or double extended-precision floating-point format. If the source operand is in single-precision or
double-precision floating-point format, it is automatically converted to the double extended-precision floating-
point format before being pushed on the stack.
The FLD instruction can also push the value in a selected FPU register [ST(i)] onto the stack. Here, pushing register
ST(0) duplicates the stack top.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
IF SRC is ST(i)
    THEN
         temp <- ST(i);
FI;

TOP <- TOP    - 1;
IF SRC is memory-operand
    THEN
         ST(0) <- ConvertToDoubleExtendedPrecisionFP(SRC);
    ELSE (* SRC is ST(i) *)
         ST(0) <- temp;
FI;

FPU Flags Affected
C1                       Set to 1 if stack overflow occurred; otherwise, set to 0.
C0, C2, C3               Undefined.

Floating-Point Exceptions
#IS                      Stack underflow or overflow occurred.
#IA                      Source operand is an SNaN. Does not occur if the source operand is in double extended-preci-
                         sion floating-point format (FLD m80fp or FLD ST(i)).
#D                       Source operand is a denormal value. Does not occur if the source operand is in double
                         extended-precision floating-point format.





Protected Mode Exceptions
#GP(0)              If destination is located in a non-writable segment.
                    If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                    If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment
                    selector.
#SS(0)              If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                 If the LOCK prefix is used.

Real-Address Mode Exceptions
#GP                 If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS                 If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#UD                 If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
#GP(0)              If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)              If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made.
#UD                 If the LOCK prefix is used.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#SS(0)              If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)              If the memory address is in a non-canonical form.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                 If there is a pending x87 FPU exception.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                 If the LOCK prefix is used.






platform: x86_64
mnem: FLD1
description:
FLD1/FLDL2T/FLDL2E/FLDPI/FLDLG2/FLDLN2/FLDZ-Load Constant
Opcode*               Instruction             64-Bit    Compat/    Description
                                              Mode      Leg Mode
D9 E8                 FLD1                    Valid     Valid      Push +1.0 onto the FPU register stack.
D9 E9                 FLDL2T                  Valid     Valid      Push log210 onto the FPU register stack.
D9 EA                 FLDL2E                  Valid     Valid      Push log2e onto the FPU register stack.
D9 EB                 FLDPI                   Valid     Valid      Push pi onto the FPU register stack.
D9 EC                 FLDLG2                  Valid     Valid      Push log102 onto the FPU register stack.
D9 ED                 FLDLN2                  Valid     Valid      Push loge2 onto the FPU register stack.
D9 EE                 FLDZ                    Valid     Valid      Push +0.0 onto the FPU register stack.
NOTES:
* See IA-32 Architecture Compatibility section below.



Description
Push one of seven commonly used constants (in double extended-precision floating-point format) onto the FPU
register stack. The constants that can be loaded with these instructions include +1.0, +0.0, log210, log2e, pi, log102,
and loge2. For each constant, an internal 66-bit constant is rounded (as specified by the RC field in the FPU control
word) to double extended-precision floating-point format. The inexact-result exception (#P) is not generated as a
result of the rounding, nor is the C1 flag set in the x87 FPU status word if the value is rounded up.
See the section titled "Approximation of Pi" in Chapter 8 of the Intel 64 and IA-32 Architectures Software Devel-
oper's Manual, Volume 1, for a description of the pi constant.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

IA-32 Architecture Compatibility
When the RC field is set to round-to-nearest, the FPU produces the same constants that is produced by the Intel
8087 and Intel 287 math coprocessors.

Operation
TOP <- TOP - 1;
ST(0) <- CONSTANT;

FPU Flags Affected
C1                     Set to 1 if stack overflow occurred; otherwise, set to 0.
C0, C2, C3             Undefined.

Floating-Point Exceptions
#IS                    Stack overflow occurred.

Protected Mode Exceptions
#NM                    CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                    If there is a pending x87 FPU exception.
#UD                    If the LOCK prefix is used.

Real-Address Mode Exceptions
Same exceptions as in protected mode.

Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.



Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: FLDCW
description:
FLDCW-Load x87 FPU Control Word
 Opcode                  Instruction                 64-Bit   Compat/    Description
                                                     Mode     Leg Mode
 D9 /5                   FLDCW m2byte                Valid    Valid      Load FPU control word from m2byte.



Description
Loads the 16-bit source operand into the FPU control word. The source operand is a memory location. This instruc-
tion is typically used to establish or change the FPU's mode of operation.
If one or more exception flags are set in the FPU status word prior to loading a new FPU control word and the new
control word unmasks one or more of those exceptions, a floating-point exception will be generated upon execution
of the next floating-point instruction (except for the no-wait floating-point instructions, see the section titled "Soft-
ware Exception Handling" in Chapter 8 of the Intel 64 and IA-32 Architectures Software Developer's Manual,
Volume 1). To avoid raising exceptions when changing FPU operating modes, clear any pending exceptions (using
the FCLEX or FNCLEX instruction) before loading the new control word.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
FPUControlWord <- SRC;

FPU Flags Affected
C0, C1, C2, C3 undefined.

Floating-Point Exceptions
None; however, this operation might unmask a pending exception in the FPU status word. That exception is then
generated upon execution of the next "waiting" floating-point instruction.

Protected Mode Exceptions
#GP(0)                 If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                       If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment
                       selector.
#SS(0)                 If a memory operand effective address is outside the SS segment limit.
#NM                    CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)        If a page fault occurs.
#AC(0)                 If alignment checking is enabled and an unaligned memory reference is made while the
                       current privilege level is 3.
#UD                    If the LOCK prefix is used.

Real-Address Mode Exceptions
#GP                    If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS                    If a memory operand effective address is outside the SS segment limit.
#NM                    CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#UD                    If the LOCK prefix is used.





Virtual-8086 Mode Exceptions
#GP(0)              If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)              If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made.
#UD                 If the LOCK prefix is used.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#SS(0)              If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)              If the memory address is in a non-canonical form.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                 If there is a pending x87 FPU exception.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                 If the LOCK prefix is used.






platform: x86_64
mnem: FLDENV
description:
FLDENV-Load x87 FPU Environment
Opcode            Instruction                      64-Bit   Compat/     Description
                                                   Mode     Leg Mode
D9 /4             FLDENV m14/28byte                Valid    Valid       Load FPU environment from m14byte or m28byte.



Description
Loads the complete x87 FPU operating environment from memory into the FPU registers. The source operand spec-
ifies the first byte of the operating-environment data in memory. This data is typically written to the specified
memory location by a FSTENV or FNSTENV instruction.
The FPU operating environment consists of the FPU control word, status word, tag word, instruction pointer, data
pointer, and last opcode. Figures 8-9 through 8-12 in the Intel 64 and IA-32 Architectures Software Developer's
Manual, Volume 1, show the layout in memory of the loaded environment, depending on the operating mode of the
processor (protected or real) and the current operand-size attribute (16-bit or 32-bit). In virtual-8086 mode, the
real mode layouts are used.
The FLDENV instruction should be executed in the same operating mode as the corresponding FSTENV/FNSTENV
instruction.
If one or more unmasked exception flags are set in the new FPU status word, a floating-point exception will be
generated upon execution of the next floating-point instruction (except for the no-wait floating-point instructions,
see the section titled "Software Exception Handling" in Chapter 8 of the Intel 64 and IA-32 Architectures Soft-
ware Developer's Manual, Volume 1). To avoid generating exceptions when loading a new environment, clear all
the exception flags in the FPU status word that is being loaded.
If a page or limit fault occurs during the execution of this instruction, the state of the x87 FPU registers as seen by
the fault handler may be different than the state being loaded from memory. In such situations, the fault handler
should ignore the status of the x87 FPU registers, handle the fault, and return. The FLDENV instruction will then
complete the loading of the x87 FPU registers with no resulting context inconsistency.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
FPUControlWord <- SRC[FPUControlWord];
FPUStatusWord <- SRC[FPUStatusWord];
FPUTagWord <- SRC[FPUTagWord];
FPUDataPointer <- SRC[FPUDataPointer];
FPUInstructionPointer <- SRC[FPUInstructionPointer];
FPULastInstructionOpcode <- SRC[FPULastInstructionOpcode];

FPU Flags Affected
The C0, C1, C2, C3 flags are loaded.

Floating-Point Exceptions
None; however, if an unmasked exception is loaded in the status word, it is generated upon execution of the next
"waiting" floating-point instruction.





Protected Mode Exceptions
#GP(0)              If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                    If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment
                    selector.
#SS(0)              If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                 If the LOCK prefix is used.

Real-Address Mode Exceptions
#GP                 If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS                 If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#UD                 If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
#GP(0)              If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)              If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made.
#UD                 If the LOCK prefix is used.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#SS(0)              If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)              If the memory address is in a non-canonical form.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                 If there is a pending x87 FPU exception.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                 If the LOCK prefix is used.






platform: x86_64
mnem: FMUL
description:
FMUL/FMULP/FIMUL-Multiply
 Opcode            Instruction                  64-Bit   Compat/     Description
                                                Mode     Leg Mode
 D8 /1             FMUL m32fp                   Valid    Valid       Multiply ST(0) by m32fp and store result in ST(0).
 DC /1             FMUL m64fp                   Valid    Valid       Multiply ST(0) by m64fp and store result in ST(0).
 D8 C8+i           FMUL ST(0), ST(i)            Valid    Valid       Multiply ST(0) by ST(i) and store result in ST(0).
 DC C8+i           FMUL ST(i), ST(0)            Valid    Valid       Multiply ST(i) by ST(0) and store result in ST(i).
 DE C8+i           FMULP ST(i), ST(0)           Valid    Valid       Multiply ST(i) by ST(0), store result in ST(i), and pop the
                                                                     register stack.
 DE C9             FMULP                        Valid    Valid       Multiply ST(1) by ST(0), store result in ST(1), and pop
                                                                     the register stack.
 DA /1             FIMUL m32int                 Valid    Valid       Multiply ST(0) by m32int and store result in ST(0).
 DE /1             FIMUL m16int                 Valid    Valid       Multiply ST(0) by m16int and store result in ST(0).



Description
Multiplies the destination and source operands and stores the product in the destination location. The destination
operand is always an FPU data register; the source operand can be an FPU data register or a memory location.
Source operands in memory can be in single-precision or double-precision floating-point format or in word or
doubleword integer format.
The no-operand version of the instruction multiplies the contents of the ST(1) register by the contents of the ST(0)
register and stores the product in the ST(1) register. The one-operand version multiplies the contents of the ST(0)
register by the contents of a memory location (either a floating point or an integer value) and stores the product in
the ST(0) register. The two-operand version, multiplies the contents of the ST(0) register by the contents of the
ST(i) register, or vice versa, with the result being stored in the register specified with the first operand (the desti-
nation operand).
The FMULP instructions perform the additional operation of popping the FPU register stack after storing the
product. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack
pointer (TOP) by 1. The no-operand version of the floating-point multiply instructions always results in the register
stack being popped. In some assemblers, the mnemonic for this instruction is FMUL rather than FMULP.
The FIMUL instructions convert an integer source operand to double extended-
precision floating-point format before performing the multiplication.
The sign of the result is always the exclusive-OR of the source signs, even if one or more of the values being multi-
plied is 0 or inf. When the source operand is an integer 0, it is treated as a +0.
The following table shows the results obtained when multiplying various classes of numbers, assuming that neither
overflow nor underflow occurs.





                                           Table 3-29. FMUL/FMULP/FIMUL Results
                                                                  DEST
                                 -inf              -F         -0           +0          +F      +inf           NaN
                  -inf             +inf              +inf          *             *         -inf      -inf           NaN
                   -F            +inf              +F         +0           -0          -F      -inf           NaN
                   -I            +inf              +F         +0           -0          -F      -inf           NaN
      SRC          -0              *             +0         +0           -0          -0       *           NaN
                   +0              *             -0         -0           +0          +0       *           NaN
                   +I            -inf              -F         -0           +0          +F      +inf           NaN
                   +F            -inf              -F         -0           +0          +F      +inf           NaN
                  +inf             -inf              -inf          *             *         +inf      +inf           NaN
                  NaN            NaN             NaN       NaN           NaN         NaN    NaN           NaN
 NOTES:
 F Means finite floating-point value.
 I Means Integer.
 * Indicates invalid-arithmetic-operand (#IA) exception.

This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
IF Instruction = FIMUL
     THEN
         DEST <- DEST * ConvertToDoubleExtendedPrecisionFP(SRC);
     ELSE (* Source operand is floating-point value *)
         DEST <- DEST * SRC;
FI;

IF Instruction = FMULP
     THEN
         PopRegisterStack;
FI;

FPU Flags Affected
C1                      Set to 0 if stack underflow occurred.
                        Set if result was rounded up; cleared otherwise.
C0, C2, C3              Undefined.

Floating-Point Exceptions
#IS                     Stack underflow occurred.
#IA                     Operand is an SNaN value or unsupported format.
                        One operand is +-0 and the other is +-inf.
#D                      Source operand is a denormal value.
#U                      Result is too small for destination format.
#O                      Result is too large for destination format.
#P                      Value cannot be represented exactly in destination format.





Protected Mode Exceptions
#GP(0)                If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                      If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment
                      selector.
#SS(0)                If a memory operand effective address is outside the SS segment limit.
#NM                   CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)       If a page fault occurs.
#AC(0)                If alignment checking is enabled and an unaligned memory reference is made while the
                      current privilege level is 3.
#UD                   If the LOCK prefix is used.

Real-Address Mode Exceptions
#GP                   If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS                   If a memory operand effective address is outside the SS segment limit.
#NM                   CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#UD                   If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
#GP(0)                If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)                If a memory operand effective address is outside the SS segment limit.
#NM                   CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)       If a page fault occurs.
#AC(0)                If alignment checking is enabled and an unaligned memory reference is made.
#UD                   If the LOCK prefix is used.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#SS(0)                If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)                If the memory address is in a non-canonical form.
#NM                   CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                   If there is a pending x87 FPU exception.
#PF(fault-code)       If a page fault occurs.
#AC(0)                If alignment checking is enabled and an unaligned memory reference is made while the
                      current privilege level is 3.
#UD                   If the LOCK prefix is used.






platform: x86_64
mnem: FNOP
description:
FNOP-No Operation
 Opcode                  Instruction        64-Bit   Compat/     Description
                                            Mode     Leg Mode
 D9 D0                   FNOP               Valid    Valid       No operation is performed.



Description
Performs no FPU operation. This instruction takes up space in the instruction stream but does not affect the FPU or
machine context, except the EIP register and the FPU Instruction Pointer.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

FPU Flags Affected
C0, C1, C2, C3 undefined.

Floating-Point Exceptions
None

Protected Mode Exceptions
#NM                  CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                  If there is a pending x87 FPU exception.
#UD                  If the LOCK prefix is used.

Real-Address Mode Exceptions
Same exceptions as in protected mode.

Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: FPATAN
description:
FPATAN-Partial Arctangent
Opcode*              Instruction            64-Bit        Compat/         Description
                                            Mode          Leg Mode
D9 F3                FPATAN                 Valid         Valid           Replace ST(1) with arctan(ST(1)/ST(0)) and pop the register stack.
NOTES:
* See IA-32 Architecture Compatibility section below.



Description
Computes the arctangent of the source operand in register ST(1) divided by the source operand in register ST(0),
stores the result in ST(1), and pops the FPU register stack. The result in register ST(0) has the same sign as the
source operand ST(1) and a magnitude less than +pi.
The FPATAN instruction returns the angle between the X axis and the line from the origin to the point (X,Y), where
Y (the ordinate) is ST(1) and X (the abscissa) is ST(0). The angle depends on the sign of X and Y independently,
not just on the sign of the ratio Y/X. This is because a point (-X,Y) is in the second quadrant, resulting in an angle
between pi/2 and pi, while a point (X,-Y) is in the fourth quadrant, resulting in an angle between 0 and -pi/2. A point
(-X,-Y) is in the third quadrant, giving an angle between -pi/2 and -pi.
The following table shows the results obtained when computing the arctangent of various classes of numbers,
assuming that underflow does not occur.
                                                    Table 3-30. FPATAN Results
                                                                              ST(0)
                             -inf            -F                     -0              +0            +F              +inf                 NaN
              -inf             - 3pi/4*       - pi/2                  - pi/2           - pi/2         - pi/2           - pi/4*             NaN
   ST(1)      -F             -p            -pi to -pi/2             -pi/2            -pi/2          -pi/2 to -0      -0                 NaN
              -0             -p            -p                     -p*             - 0*          -0              -0                 NaN
              +0             +p            +p                     + pi*            + 0*          +0              +0                 NaN
              +F             +p            +pi to +pi/2             + pi/2           +pi/2          +pi/2 to +0      +0                 NaN
              +inf             +3pi/4*        +pi/2                   +pi/2            +pi/2          + pi/2           + pi/4*             NaN
                   NaN             NaN              NaN                 NaN            NaN           NaN             NaN           NaN
 NOTES:
 F Means finite floating-point value.
 * Table 8-10 in the Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 1, specifies that the ratios 0/0 and inf/inf
   generate the floating-point invalid arithmetic-operation exception and, if this exception is masked, the floating-point QNaN indefi-
   nite value is returned. With the FPATAN instruction, the 0/0 or inf/inf value is actually not calculated using division. Instead, the arc-
   tangent of the two variables is derived from a standard mathematical formulation that is generalized to allow complex numbers as
   arguments. In this complex variable formulation, arctangent(0,0) etc. has well defined values. These values are needed to develop
   a library to compute transcendental functions with complex arguments, based on the FPU functions that only allow floating-point
   values as arguments.

There is no restriction on the range of source operands that FPATAN can accept.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

IA-32 Architecture Compatibility
The source operands for this instruction are restricted for the 80287 math coprocessor to the following range:

0 <= |ST(1)| < |ST(0)| < +inf





Operation
ST(1) <- arctan(ST(1) / ST(0));
PopRegisterStack;

FPU Flags Affected
C1                      Set to 0 if stack underflow occurred.
                        Set if result was rounded up; cleared otherwise.
C0, C2, C3              Undefined.

Floating-Point Exceptions
#IS                     Stack underflow occurred.
#IA                     Source operand is an SNaN value or unsupported format.
#D                      Source operand is a denormal value.
#U                      Result is too small for destination format.
#P                      Value cannot be represented exactly in destination format.

Protected Mode Exceptions
#NM                     CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                     If there is a pending x87 FPU exception.
#UD                     If the LOCK prefix is used.

Real-Address Mode Exceptions
Same exceptions as in protected mode.

Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: FPREM
description:
FPREM-Partial Remainder
Opcode                   Instruction          64-Bit       Compat/         Description
                                              Mode         Leg Mode
D9 F8                    FPREM                Valid        Valid           Replace ST(0) with the remainder obtained from dividing
                                                                           ST(0) by ST(1).



Description
Computes the remainder obtained from dividing the value in the ST(0) register (the dividend) by the value in the
ST(1) register (the divisor or modulus), and stores the result in ST(0). The remainder represents the following
value:
Remainder <- ST(0) - (Q * ST(1))
Here, Q is an integer value that is obtained by truncating the floating-point number quotient of [ST(0) / ST(1)]
toward zero. The sign of the remainder is the same as the sign of the dividend. The magnitude of the remainder is
less than that of the modulus, unless a partial remainder was computed (as described below).
This instruction produces an exact result; the inexact-result exception does not occur and the rounding control has
no effect. The following table shows the results obtained when computing the remainder of various classes of
numbers, assuming that underflow does not occur.
                                                      Table 3-31. FPREM Results
                                                                          ST(1)
                                       -inf          -F              -0             +0            +F             +inf            NaN
                   -inf                   *             *             *              *             *              *            NaN
 ST(0)              -F             ST(0)        -F or -0           **             **          -F or -0       ST(0)           NaN
                    -0                 -0          -0               *              *            -0             -0            NaN
                   +0                  +0         +0                *              *            +0             +0            NaN
                   +F              ST(0)       +F or +0            **             **         +F or +0        ST(0)           NaN
                   +inf                   *             *             *              *             *              *            NaN
                  NaN                  NaN        NaN              NaN            NaN          NaN            NaN            NaN
 NOTES:
 F Means finite floating-point value.
 * Indicates floating-point invalid-arithmetic-operand (#IA) exception.
 ** Indicates floating-point zero-divide (#Z) exception.

When the result is 0, its sign is the same as that of the dividend. When the modulus is inf, the result is equal to the
value in ST(0).
The FPREM instruction does not compute the remainder specified in IEEE Std 754. The IEEE specified remainder
can be computed with the FPREM1 instruction. The FPREM instruction is provided for compatibility with the Intel
8087 and Intel287 math coprocessors.
The FPREM instruction gets its name "partial remainder" because of the way it computes the remainder. This
instruction arrives at a remainder through iterative subtraction. It can, however, reduce the exponent of ST(0) by
no more than 63 in one execution of the instruction. If the instruction succeeds in producing a remainder that is
less than the modulus, the operation is complete and the C2 flag in the FPU status word is cleared. Otherwise, C2
is set, and the result in ST(0) is called the partial remainder. The exponent of the partial remainder will be less
than the exponent of the original dividend by at least 32. Software can re-execute the instruction (using the partial
remainder in ST(0) as the dividend) until C2 is cleared. (Note that while executing such a remainder-computation
loop, a higher-priority interrupting routine that needs the FPU can force a context switch in-between the instruc-
tions in the loop.)
An important use of the FPREM instruction is to reduce the arguments of periodic functions. When reduction is
complete, the instruction stores the three least-significant bits of the quotient in the C3, C1, and C0 flags of the FPU



status word. This information is important in argument reduction for the tangent function (using a modulus of pi/4),
because it locates the original angle in the correct one of eight sectors of the unit circle.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
D <- exponent(ST(0)) - exponent(ST(1));

IF D < 64
    THEN
        Q <- Integer(TruncateTowardZero(ST(0) / ST(1)));
        ST(0) <- ST(0) - (ST(1) * Q);
        C2 <- 0;
        C0, C3, C1 <- LeastSignificantBits(Q); (* Q2, Q1, Q0 *)
    ELSE
        C2 <- 1;
        N <- An implementation-dependent number between 32 and 63;
        QQ <- Integer(TruncateTowardZero((ST(0) / ST(1)) / 2(D - N)));
        ST(0) <- ST(0) - (ST(1) * QQ * 2(D - N));
FI;

FPU Flags Affected
C0                    Set to bit 2 (Q2) of the quotient.
C1                    Set to 0 if stack underflow occurred; otherwise, set to least significant bit of quotient (Q0).
C2                    Set to 0 if reduction complete; set to 1 if incomplete.
C3                    Set to bit 1 (Q1) of the quotient.

Floating-Point Exceptions
#IS                   Stack underflow occurred.
#IA                   Source operand is an SNaN value, modulus is 0, dividend is inf, or unsupported format.
#D                    Source operand is a denormal value.
#U                    Result is too small for destination format.

Protected Mode Exceptions
#NM                   CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                   If there is a pending x87 FPU exception.
#UD                   If the LOCK prefix is used.

Real-Address Mode Exceptions
Same exceptions as in protected mode.

Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: FPREM1
description:
FPREM1-Partial Remainder
 Opcode              Instruction               64-Bit       Compat/       Description
                                               Mode         Leg Mode
 D9 F5               FPREM1                    Valid        Valid         Replace ST(0) with the IEEE remainder obtained from dividing
                                                                          ST(0) by ST(1).



Description
Computes the IEEE remainder obtained from dividing the value in the ST(0) register (the dividend) by the value in
the ST(1) register (the divisor or modulus), and stores the result in ST(0). The remainder represents the following
value:
Remainder <- ST(0) - (Q * ST(1))
Here, Q is an integer value that is obtained by rounding the floating-point number quotient of [ST(0) / ST(1)]
toward the nearest integer value. The magnitude of the remainder is less than or equal to half the magnitude of the
modulus, unless a partial remainder was computed (as described below).
This instruction produces an exact result; the precision (inexact) exception does not occur and the rounding control
has no effect. The following table shows the results obtained when computing the remainder of various classes of
numbers, assuming that underflow does not occur.
                                                   Table 3-32. FPREM1 Results
                                                                          ST(1)
                                   -inf             -F                -0            +0             +F            +inf            NaN
                   -inf               *              *                 *             *              *              *           NaN
 ST(0)             -F            ST(0)         +-F or -0             **            **         +- F or - 0       ST(0)          NaN
                   -0              -0             -0                 *             *             -0             -0           NaN
                   +0              +0             +0                 *             *             +0             +0           NaN
                   +F            ST(0)         +- F or + 0           **            **         +- F or + 0       ST(0)          NaN
                   +inf               *              *                 *             *              *              *           NaN
                  NaN              NaN           NaN                NaN           NaN           NaN            NaN           NaN
 NOTES:
 F Means finite floating-point value.
 * Indicates floating-point invalid-arithmetic-operand (#IA) exception.
 ** Indicates floating-point zero-divide (#Z) exception.

When the result is 0, its sign is the same as that of the dividend. When the modulus is inf, the result is equal to the
value in ST(0).
The FPREM1 instruction computes the remainder specified in IEEE Standard 754. This instruction operates differ-
ently from the FPREM instruction in the way that it rounds the quotient of ST(0) divided by ST(1) to an integer (see
the "Operation" section below).
Like the FPREM instruction, FPREM1 computes the remainder through iterative subtraction, but can reduce the
exponent of ST(0) by no more than 63 in one execution of the instruction. If the instruction succeeds in producing
a remainder that is less than one half the modulus, the operation is complete and the C2 flag in the FPU status word
is cleared. Otherwise, C2 is set, and the result in ST(0) is called the partial remainder. The exponent of the partial
remainder will be less than the exponent of the original dividend by at least 32. Software can re-execute the
instruction (using the partial remainder in ST(0) as the dividend) until C2 is cleared. (Note that while executing
such a remainder-computation loop, a higher-priority interrupting routine that needs the FPU can force a context
switch in-between the instructions in the loop.)
An important use of the FPREM1 instruction is to reduce the arguments of periodic functions. When reduction is
complete, the instruction stores the three least-significant bits of the quotient in the C3, C1, and C0 flags of the FPU




status word. This information is important in argument reduction for the tangent function (using a modulus of pi/4),
because it locates the original angle in the correct one of eight sectors of the unit circle.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
D <- exponent(ST(0)) - exponent(ST(1));

IF D < 64
    THEN
        Q <- Integer(RoundTowardNearestInteger(ST(0) / ST(1)));
        ST(0) <- ST(0) - (ST(1) * Q);
        C2 <- 0;
        C0, C3, C1 <- LeastSignificantBits(Q); (* Q2, Q1, Q0 *)
    ELSE
        C2 <- 1;
        N <- An implementation-dependent number between 32 and 63;
        QQ <- Integer(TruncateTowardZero((ST(0) / ST(1)) / 2(D - N)));
        ST(0) <- ST(0) - (ST(1) * QQ * 2(D - N));
FI;

FPU Flags Affected
C0                    Set to bit 2 (Q2) of the quotient.
C1                    Set to 0 if stack underflow occurred; otherwise, set to least significant bit of quotient (Q0).
C2                    Set to 0 if reduction complete; set to 1 if incomplete.
C3                    Set to bit 1 (Q1) of the quotient.

Floating-Point Exceptions
#IS                   Stack underflow occurred.
#IA                   Source operand is an SNaN value, modulus (divisor) is 0, dividend is inf, or unsupported
                      format.
#D                    Source operand is a denormal value.
#U                    Result is too small for destination format.

Protected Mode Exceptions
#NM                   CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                   If there is a pending x87 FPU exception.
#UD                   If the LOCK prefix is used.

Real-Address Mode Exceptions
Same exceptions as in protected mode.

Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: FPTAN
description:
FPTAN-Partial Tangent
Opcode                  Instruction              64-Bit        Compat/    Description
                                                 Mode          Leg Mode
D9 F2                   FPTAN                    Valid         Valid      Replace ST(0) with its approximate tangent and push 1
                                                                          onto the FPU stack.



Description
Computes the approximate tangent of the source operand in register ST(0), stores the result in ST(0), and pushes
a 1.0 onto the FPU register stack. The source operand must be given in radians and must be less than +-263. The
following table shows the unmasked results obtained when computing the partial tangent of various classes of
numbers, assuming that underflow does not occur.
                                                   Table 3-33. FPTAN Results
                           ST(0) SRC                                                      ST(0) DEST
                              -inf                                                               *
                              -F                                                           - F to + F
                              -0                                                              -0
                              +0                                                              +0
                              +F                                                           - F to + F
                              +inf                                                               *
                              NaN                                                            NaN
NOTES:
F Means finite floating-point value.
* Indicates floating-point invalid-arithmetic-operand (#IA) exception.

If the source operand is outside the acceptable range, the C2 flag in the FPU status word is set, and the value in
register ST(0) remains unchanged. The instruction does not raise an exception when the source operand is out of
range. It is up to the program to check the C2 flag for out-of-range conditions. Source values outside the range -
263 to +263 can be reduced to the range of the instruction by subtracting an appropriate integer multiple of 2pi.
However, even within the range -263 to +263, inaccurate results can occur because the finite approximation of pi
used internally for argument reduction is not sufficient in all cases. Therefore, for accurate results it is safe to apply
FPTAN only to arguments reduced accurately in software, to a value smaller in absolute value than 3pi/8. See the
sections titled "Approximation of Pi" and "Transcendental Instruction Accuracy" in Chapter 8 of the Intel 64 and
IA-32 Architectures Software Developer's Manual, Volume 1, for a discussion of the proper value to use for pi in
performing such reductions.
The value 1.0 is pushed onto the register stack after the tangent has been computed to maintain compatibility with
the Intel 8087 and Intel287 math coprocessors. This operation also simplifies the calculation of other trigonometric
functions. For instance, the cotangent (which is the reciprocal of the tangent) can be computed by executing a
FDIVR instruction after the FPTAN instruction.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.





Operation
IF ST(0) < 263
    THEN
         C2 <- 0;
         ST(0) <- fptan(ST(0)); // approximation of tan
         TOP <- TOP - 1;
         ST(0) <- 1.0;
    ELSE (* Source operand is out-of-range *)
         C2 <- 1;
FI;

FPU Flags Affected
C1                      Set to 0 if stack underflow occurred; set to 1 if stack overflow occurred.
                        Set if result was rounded up; cleared otherwise.
C2                      Set to 1 if outside range (-263 < source operand < +263); otherwise, set to 0.
C0, C3                  Undefined.

Floating-Point Exceptions
#IS                     Stack underflow or overflow occurred.
#IA                     Source operand is an SNaN value, inf, or unsupported format.
#D                      Source operand is a denormal value.
#U                      Result is too small for destination format.
#P                      Value cannot be represented exactly in destination format.

Protected Mode Exceptions
#NM                     CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                     If there is a pending x87 FPU exception.
#UD                     If the LOCK prefix is used.

Real-Address Mode Exceptions
Same exceptions as in protected mode.

Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: FRNDINT
description:
FRNDINT-Round to Integer
Opcode                     Instruction      64-Bit     Compat/      Description
                                            Mode       Leg Mode
D9 FC                      FRNDINT          Valid      Valid        Round ST(0) to an integer.



Description
Rounds the source value in the ST(0) register to the nearest integral value, depending on the current rounding
mode (setting of the RC field of the FPU control word), and stores the result in ST(0).
If the source value is inf, the value is not changed. If the source value is not an integral value, the floating-point
inexact-result exception (#P) is generated.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
ST(0) <- RoundToIntegralValue(ST(0));

FPU Flags Affected
C1                     Set to 0 if stack underflow occurred.
                       Set if result was rounded up; cleared otherwise.
C0, C2, C3             Undefined.

Floating-Point Exceptions
#IS                    Stack underflow occurred.
#IA                    Source operand is an SNaN value or unsupported format.
#D                     Source operand is a denormal value.
#P                     Source operand is not an integral value.

Protected Mode Exceptions
#NM                    CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                    If there is a pending x87 FPU exception.
#UD                    If the LOCK prefix is used.

Real-Address Mode Exceptions
Same exceptions as in protected mode.

Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: FRSTOR
description:
FRSTOR-Restore x87 FPU State
Opcode                Instruction                    64-Bit   Compat/      Description
                                                     Mode     Leg Mode
DD /4                 FRSTOR m94/108byte             Valid    Valid        Load FPU state from m94byte or m108byte.



Description
Loads the FPU state (operating environment and register stack) from the memory area specified with the source
operand. This state data is typically written to the specified memory location by a previous FSAVE/FNSAVE instruc-
tion.
The FPU operating environment consists of the FPU control word, status word, tag word, instruction pointer, data
pointer, and last opcode. Figures 8-9 through 8-12 in the Intel 64 and IA-32 Architectures Software Developer's
Manual, Volume 1, show the layout in memory of the stored environment, depending on the operating mode of the
processor (protected or real) and the current operand-size attribute (16-bit or 32-bit). In virtual-8086 mode, the
real mode layouts are used. The contents of the FPU register stack are stored in the 80 bytes immediately following
the operating environment image.
The FRSTOR instruction should be executed in the same operating mode as the corresponding FSAVE/FNSAVE
instruction.
If one or more unmasked exception bits are set in the new FPU status word, a floating-point exception will be
generated. To avoid raising exceptions when loading a new operating environment, clear all the exception flags in
the FPU status word that is being loaded.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
FPUControlWord <- SRC[FPUControlWord];
FPUStatusWord <- SRC[FPUStatusWord];
FPUTagWord <- SRC[FPUTagWord];
FPUDataPointer <- SRC[FPUDataPointer];
FPUInstructionPointer <- SRC[FPUInstructionPointer];
FPULastInstructionOpcode <- SRC[FPULastInstructionOpcode];

ST(0) <- SRC[ST(0)];
ST(1) <- SRC[ST(1)];
ST(2) <- SRC[ST(2)];
ST(3) <- SRC[ST(3)];
ST(4) <- SRC[ST(4)];
ST(5) <- SRC[ST(5)];
ST(6) <- SRC[ST(6)];
ST(7) <- SRC[ST(7)];

FPU Flags Affected
The C0, C1, C2, C3 flags are loaded.

Floating-Point Exceptions
None; however, this operation might unmask an existing exception that has been detected but not generated,
because it was masked. Here, the exception is generated at the completion of the instruction.





Protected Mode Exceptions
#GP(0)                 If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                      If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment
                      selector.
#SS(0)                 If a memory operand effective address is outside the SS segment limit.
#NM                    CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)        If a page fault occurs.
#AC(0)                If alignment checking is enabled and an unaligned memory reference is made while the
                      current privilege level is 3.
#UD                    If the LOCK prefix is used.

Real-Address Mode Exceptions
#GP                    If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS                    If a memory operand effective address is outside the SS segment limit.
#NM                    CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#UD                    If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
#GP(0)                 If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)                 If a memory operand effective address is outside the SS segment limit.
#NM                    CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)        If a page fault occurs.
#AC(0)                 If alignment checking is enabled and an unaligned memory reference is made.
#UD                    If the LOCK prefix is used.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#SS(0)                 If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)                 If the memory address is in a non-canonical form.
#NM                    CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)        If a page fault occurs.
#AC(0)                If alignment checking is enabled and an unaligned memory reference is made while the
                      current privilege level is 3.
#UD                    If the LOCK prefix is used.






platform: x86_64
mnem: FSAVE
description:
FSAVE/FNSAVE-Store x87 FPU State
 Opcode           Instruction                            64-Bit   Compat/    Description
                                                         Mode     Leg Mode
 9B DD /6         FSAVE m94/108byte                      Valid    Valid      Store FPU state to m94byte or m108byte after
                                                                             checking for pending unmasked floating-point
                                                                             exceptions. Then re-initialize the FPU.
 DD /6            FNSAVE* m94/108byte                    Valid    Valid      Store FPU environment to m94byte or m108byte
                                                                             without checking for pending unmasked floating-
                                                                             point exceptions. Then re-initialize the FPU.
 NOTES:
 * See IA-32 Architecture Compatibility section below.



Description
Stores the current FPU state (operating environment and register stack) at the specified destination in memory,
and then re-initializes the FPU. The FSAVE instruction checks for and handles pending unmasked floating-point
exceptions before storing the FPU state; the FNSAVE instruction does not.
The FPU operating environment consists of the FPU control word, status word, tag word, instruction pointer, data
pointer, and last opcode. Figures 8-9 through 8-12 in the Intel 64 and IA-32 Architectures Software Developer's
Manual, Volume 1, show the layout in memory of the stored environment, depending on the operating mode of the
processor (protected or real) and the current operand-size attribute (16-bit or 32-bit). In virtual-8086 mode, the
real mode layouts are used. The contents of the FPU register stack are stored in the 80 bytes immediately follow
the operating environment image.
The saved image reflects the state of the FPU after all floating-point instructions preceding the FSAVE/FNSAVE
instruction in the instruction stream have been executed.
After the FPU state has been saved, the FPU is reset to the same default values it is set to with the FINIT/FNINIT
instructions (see "FINIT/FNINIT-Initialize Floating-Point Unit" in this chapter).
The FSAVE/FNSAVE instructions are typically used when the operating system needs to perform a context switch,
an exception handler needs to use the FPU, or an application program needs to pass a "clean" FPU to a procedure.
The assembler issues two instructions for the FSAVE instruction (an FWAIT instruction followed by an FNSAVE
instruction), and the processor executes each of these instructions separately. If an exception is generated for
either of these instructions, the save EIP points to the instruction that caused the exception.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

IA-32 Architecture Compatibility
For Intel math coprocessors and FPUs prior to the Intel Pentium processor, an FWAIT instruction should be
executed before attempting to read from the memory image stored with a prior FSAVE/FNSAVE instruction. This
FWAIT instruction helps ensure that the storage operation has been completed.
When operating a Pentium or Intel486 processor in MS-DOS compatibility mode, it is possible (under unusual
circumstances) for an FNSAVE instruction to be interrupted prior to being executed to handle a pending FPU excep-
tion. See the section titled "No-Wait FPU Instructions Can Get FPU Interrupt in Window" in Appendix D of the Intel
64 and IA-32 Architectures Software Developer's Manual, Volume 1, for a description of these circumstances. An
FNSAVE instruction cannot be interrupted in this way on later Intel processors, except for the Intel QuarkTM X1000
processor.





Operation
(* Save FPU State and Registers *)

DEST[FPUControlWord] <- FPUControlWord;
DEST[FPUStatusWord] <- FPUStatusWord;
DEST[FPUTagWord] <- FPUTagWord;
DEST[FPUDataPointer] <- FPUDataPointer;
DEST[FPUInstructionPointer] <- FPUInstructionPointer;
DEST[FPULastInstructionOpcode] <- FPULastInstructionOpcode;

DEST[ST(0)] <- ST(0);
DEST[ST(1)] <- ST(1);
DEST[ST(2)] <- ST(2);
DEST[ST(3)] <- ST(3);
DEST[ST(4)]<- ST(4);
DEST[ST(5)] <- ST(5);
DEST[ST(6)] <- ST(6);
DEST[ST(7)] <- ST(7);

(* Initialize FPU *)

FPUControlWord <- 037FH;
FPUStatusWord <- 0;
FPUTagWord <- FFFFH;
FPUDataPointer <- 0;
FPUInstructionPointer <- 0;
FPULastInstructionOpcode <- 0;

FPU Flags Affected
The C0, C1, C2, and C3 flags are saved and then cleared.

Floating-Point Exceptions
None.

Protected Mode Exceptions
#GP(0)                 If destination is located in a non-writable segment.
                       If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                       If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment
                       selector.
#SS(0)                 If a memory operand effective address is outside the SS segment limit.
#NM                    CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)        If a page fault occurs.
#AC(0)                 If alignment checking is enabled and an unaligned memory reference is made while the
                       current privilege level is 3.
#UD                    If the LOCK prefix is used.

Real-Address Mode Exceptions
#GP                    If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS                    If a memory operand effective address is outside the SS segment limit.
#NM                    CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#UD                    If the LOCK prefix is used.





Virtual-8086 Mode Exceptions
#GP(0)              If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)              If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made.
#UD                 If the LOCK prefix is used.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#SS(0)              If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)              If the memory address is in a non-canonical form.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                 If there is a pending x87 FPU exception.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.






platform: x86_64
mnem: FSCALE
description:
FSCALE-Scale
Opcode                     Instruction           64-Bit      Compat/       Description
                                                 Mode        Leg Mode
D9 FD                      FSCALE                Valid       Valid         Scale ST(0) by ST(1).



Description
Truncates the value in the source operand (toward 0) to an integral value and adds that value to the exponent of
the destination operand. The destination and source operands are floating-point values located in registers ST(0)
and ST(1), respectively. This instruction provides rapid multiplication or division by integral powers of 2. The
following table shows the results obtained when scaling various classes of numbers, assuming that neither over-
flow nor underflow occurs.


                                                   Table 3-34. FSCALE Results
                   ST(1)
                                         -inf       -F           -0          +0             +F           +inf           NaN
                       -inf            NaN          -inf           -inf          -inf            -inf            -inf           NaN
 ST(0)                 -F                -0       -F           -F          -F             -F           -inf           NaN
                       -0                -0       -0           -0          -0             -0           NaN          NaN
                       +0                +0       +0           +0          +0             +0           NaN          NaN
                       +F                +0       +F           +F          +F             +F           +inf           NaN
                       +inf            NaN          +inf           +inf          +inf            +inf            +inf           NaN
                      NaN            NaN          NaN         NaN         NaN            NaN           NaN          NaN
 NOTES:
 F Means finite floating-point value.

In most cases, only the exponent is changed and the mantissa (significand) remains unchanged. However, when
the value being scaled in ST(0) is a denormal value, the mantissa is also changed and the result may turn out to be
a normalized number. Similarly, if overflow or underflow results from a scale operation, the resulting mantissa will
differ from the source's mantissa.
The FSCALE instruction can also be used to reverse the action of the FXTRACT instruction, as shown in the following
example:
     FXTRACT;
     FSCALE;
     FSTP ST(1);
In this example, the FXTRACT instruction extracts the significand and exponent from the value in ST(0) and stores
them in ST(0) and ST(1) respectively. The FSCALE then scales the significand in ST(0) by the exponent in ST(1),
recreating the original value before the FXTRACT operation was performed. The FSTP ST(1) instruction overwrites
the exponent (extracted by the FXTRACT instruction) with the recreated value, which returns the stack to its orig-
inal state with only one register [ST(0)] occupied.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
ST(0) <- ST(0) * 2RoundTowardZero(ST(1));

FPU Flags Affected
C1                          Set to 0 if stack underflow occurred.
                            Set if result was rounded up; cleared otherwise.
C0, C2, C3                  Undefined.



Floating-Point Exceptions
#IS                 Stack underflow occurred.
#IA                 Source operand is an SNaN value or unsupported format.
#D                  Source operand is a denormal value.
#U                  Result is too small for destination format.
#O                  Result is too large for destination format.
#P                  Value cannot be represented exactly in destination format.

Protected Mode Exceptions
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                 If there is a pending x87 FPU exception.
#UD                 If the LOCK prefix is used.

Real-Address Mode Exceptions
Same exceptions as in protected mode.

Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: FSIN
description:
FSIN-Sine
Opcode                   Instruction             64-Bit        Compat/            Description
                                                 Mode          Leg Mode
D9 FE                    FSIN                    Valid         Valid          Replace ST(0) with the approximate of its sine.



Description
Computes an approximation of the sine of the source operand in register ST(0) and stores the result in ST(0). The
source operand must be given in radians and must be within the range -263 to +263. The following table shows the
results obtained when taking the sine of various classes of numbers, assuming that underflow does not occur.
                                                     Table 3-35. FSIN Results
                           SRC (ST(0))                                                          DEST (ST(0))
                                -inf                                                                    *
                                -F                                                               - 1 to + 1
                                -0                                                                   -0
                                +0                                                                  +0
                                +F                                                                - 1 to +1
                                +inf                                                                    *
                                NaN                                                                 NaN
 NOTES:
 F Means finite floating-point value.
 * Indicates floating-point invalid-arithmetic-operand (#IA) exception.

If the source operand is outside the acceptable range, the C2 flag in the FPU status word is set, and the value in
register ST(0) remains unchanged. The instruction does not raise an exception when the source operand is out of
range. It is up to the program to check the C2 flag for out-of-range conditions. Source values outside the range -
263 to +263 can be reduced to the range of the instruction by subtracting an appropriate integer multiple of 2pi.
However, even within the range -263 to +263, inaccurate results can occur because the finite approximation of pi
used internally for argument reduction is not sufficient in all cases. Therefore, for accurate results it is safe to apply
FSIN only to arguments reduced accurately in software, to a value smaller in absolute value than 3pi/4. See the
sections titled "Approximation of Pi" and "Transcendental Instruction Accuracy" in Chapter 8 of the Intel 64 and
IA-32 Architectures Software Developer's Manual, Volume 1, for a discussion of the proper value to use for pi in
performing such reductions.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
IF -263 < ST(0) < 263
    THEN
         C2 <- 0;
         ST(0) <- fsin(ST(0)); // approximation of the mathematical sin function
    ELSE (* Source operand out of range *)
         C2 <- 1;
FI;

FPU Flags Affected
C1                      Set to 0 if stack underflow occurred.
                        Set if result was rounded up; cleared otherwise.
C2                      Set to 1 if outside range (-263 < source operand < +263); otherwise, set to 0.
C0, C3                  Undefined.




Floating-Point Exceptions
#IS                 Stack underflow occurred.
#IA                 Source operand is an SNaN value, inf, or unsupported format.
#D                  Source operand is a denormal value.
#P                  Value cannot be represented exactly in destination format.

Protected Mode Exceptions
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                 If there is a pending x87 FPU exception.
#UD                 If the LOCK prefix is used.

Real-Address Mode Exceptions
Same exceptions as in protected mode.

Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: FSINCOS
description:
FSINCOS-Sine and Cosine
 Opcode                   Instruction            64-Bit    Compat/         Description
                                                 Mode      Leg Mode
 D9 FB                    FSINCOS                Valid     Valid           Compute the sine and cosine of ST(0); replace ST(0) with the
                                                                           approximate sine, and push the approximate cosine onto the
                                                                           register stack.



Description
Computes both the approximate sine and the cosine of the source operand in register ST(0), stores the sine in
ST(0), and pushes the cosine onto the top of the FPU register stack. (This instruction is faster than executing the
FSIN and FCOS instructions in succession.)
The source operand must be given in radians and must be within the range -263 to +263. The following table shows
the results obtained when taking the sine and cosine of various classes of numbers, assuming that underflow does
not occur.
                                                   Table 3-36. FSINCOS Results
                    SRC                                                                  DEST
                   ST(0)                                    ST(1) Cosine                                    ST(0) Sine
                    -inf                                              *                                            *
                    -F                                        - 1 to + 1                                     - 1 to + 1
                    -0                                             +1                                           -0
                    +0                                             +1                                           +0
                    +F                                        - 1 to + 1                                     - 1 to + 1
                    +inf                                              *                                            *
                   NaN                                             NaN                                         NaN
 NOTES:
 F Means finite floating-point value.
 * Indicates floating-point invalid-arithmetic-operand (#IA) exception.

If the source operand is outside the acceptable range, the C2 flag in the FPU status word is set, and the value in
register ST(0) remains unchanged. The instruction does not raise an exception when the source operand is out of
range. It is up to the program to check the C2 flag for out-of-range conditions. Source values outside the range -
263 to +263 can be reduced to the range of the instruction by subtracting an appropriate integer multiple of 2pi.
However, even within the range -263 to +263, inaccurate results can occur because the finite approximation of pi
used internally for argument reduction is not sufficient in all cases. Therefore, for accurate results it is safe to apply
FSINCOS only to arguments reduced accurately in software, to a value smaller in absolute value than 3pi/8. See the
sections titled "Approximation of Pi" and "Transcendental Instruction Accuracy" in Chapter 8 of the Intel 64 and
IA-32 Architectures Software Developer's Manual, Volume 1, for a discussion of the proper value to use for pi in
performing such reductions.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.





Operation
IF ST(0) < 263
    THEN
         C2 <- 0;
         TEMP <- fcos(ST(0)); // approximation of cosine
         ST(0) <- fsin(ST(0)); // approximation of sine
         TOP <- TOP - 1;
         ST(0) <- TEMP;
    ELSE (* Source operand out of range *)
         C2 <- 1;
FI;

FPU Flags Affected
C1                     Set to 0 if stack underflow occurred; set to 1 of stack overflow occurs.
                       Set if result was rounded up; cleared otherwise.
C2                     Set to 1 if outside range (-263 < source operand < +263); otherwise, set to 0.
C0, C3                 Undefined.

Floating-Point Exceptions
#IS                    Stack underflow or overflow occurred.
#IA                    Source operand is an SNaN value, inf, or unsupported format.
#D                     Source operand is a denormal value.
#U                     Result is too small for destination format.
#P                     Value cannot be represented exactly in destination format.

Protected Mode Exceptions
#NM                    CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                    If there is a pending x87 FPU exception.
#UD                    If the LOCK prefix is used.

Real-Address Mode Exceptions
Same exceptions as in protected mode.

Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: FSQRT
description:
FSQRT-Square Root
Opcode                  Instruction            64-Bit     Compat/         Description
                                               Mode       Leg Mode
D9 FA                   FSQRT                  Valid      Valid           Computes square root of ST(0) and stores the result in ST(0).



Description
Computes the square root of the source value in the ST(0) register and stores the result in ST(0).
The following table shows the results obtained when taking the square root of various classes of numbers,
assuming that neither overflow nor underflow occurs.
                                                    Table 3-37. FSQRT Results
                           SRC (ST(0))                                                         DEST (ST(0))
                                -inf                                                                   *
                                -F                                                                   *
                                -0                                                                  -0
                                +0                                                                  +0
                                +F                                                                  +F
                                +inf                                                                  +inf
                              NaN                                                                   NaN
 NOTES:
 F Means finite floating-point value.
 * Indicates floating-point invalid-arithmetic-operand (#IA) exception.

This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
ST(0) <- SquareRoot(ST(0));

FPU Flags Affected
C1                      Set to 0 if stack underflow occurred.
                        Set if result was rounded up; cleared otherwise.
C0, C2, C3              Undefined.

Floating-Point Exceptions
#IS                     Stack underflow occurred.
#IA                     Source operand is an SNaN value or unsupported format.
                        Source operand is a negative value (except for -0).
#D                      Source operand is a denormal value.
#P                      Value cannot be represented exactly in destination format.

Protected Mode Exceptions
#NM                     CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                     If there is a pending x87 FPU exception.
#UD                     If the LOCK prefix is used.

Real-Address Mode Exceptions
Same exceptions as in protected mode.




Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: FST
description:
FST/FSTP-Store Floating Point Value
 Opcode                   Instruction         64-Bit   Compat/       Description
                                              Mode     Leg Mode
 D9 /2                    FST m32fp           Valid    Valid         Copy ST(0) to m32fp.
 DD /2                    FST m64fp           Valid    Valid         Copy ST(0) to m64fp.
 DD D0+i                  FST ST(i)           Valid    Valid         Copy ST(0) to ST(i).
 D9 /3                    FSTP m32fp          Valid    Valid         Copy ST(0) to m32fp and pop register stack.
 DD /3                    FSTP m64fp          Valid    Valid         Copy ST(0) to m64fp and pop register stack.
 DB /7                    FSTP m80fp          Valid    Valid         Copy ST(0) to m80fp and pop register stack.
 DD D8+i                  FSTP ST(i)          Valid    Valid         Copy ST(0) to ST(i) and pop register stack.



Description
The FST instruction copies the value in the ST(0) register to the destination operand, which can be a memory loca-
tion or another register in the FPU register stack. When storing the value in memory, the value is converted to
single-precision or double-precision floating-point format.
The FSTP instruction performs the same operation as the FST instruction and then pops the register stack. To pop
the register stack, the processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1.
The FSTP instruction can also store values in memory in double extended-precision floating-point format.
If the destination operand is a memory location, the operand specifies the address where the first byte of the desti-
nation value is to be stored. If the destination operand is a register, the operand specifies a register in the register
stack relative to the top of the stack.
If the destination size is single-precision or double-precision, the significand of the value being stored is rounded
to the width of the destination (according to the rounding mode specified by the RC field of the FPU control word),
and the exponent is converted to the width and bias of the destination format. If the value being stored is too large
for the destination format, a numeric overflow exception (#O) is generated and, if the exception is unmasked, no
value is stored in the destination operand. If the value being stored is a denormal value, the denormal exception
(#D) is not generated. This condition is simply signaled as a numeric underflow exception (#U) condition.
If the value being stored is +-0, +-inf, or a NaN, the least-significant bits of the significand and the exponent are trun-
cated to fit the destination format. This operation preserves the value's identity as a 0, inf, or NaN.
If the destination operand is a non-empty register, the invalid-operation exception is not generated.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
DEST <- ST(0);

IF Instruction = FSTP
     THEN
         PopRegisterStack;
FI;

FPU Flags Affected
C1                       Set to 0 if stack underflow occurred.
                         Indicates rounding direction of if the floating-point inexact exception (#P) is generated: 0 <-
                         not roundup; 1 <- roundup.
C0, C2, C3               Undefined.





Floating-Point Exceptions
#IS                 Stack underflow occurred.
#IA                 If destination result is an SNaN value or unsupported format, except when the destination
                    format is in double extended-precision floating-point format.
#U                  Result is too small for the destination format.
#O                  Result is too large for the destination format.
#P                  Value cannot be represented exactly in destination format.

Protected Mode Exceptions
#GP(0)              If the destination is located in a non-writable segment.
                    If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                    If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment
                    selector.
#SS(0)              If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                 If the LOCK prefix is used.

Real-Address Mode Exceptions
#GP                 If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS                 If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#UD                 If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
#GP(0)              If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)              If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made.
#UD                 If the LOCK prefix is used.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#SS(0)              If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)              If the memory address is in a non-canonical form.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                 If there is a pending x87 FPU exception.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                 If the LOCK prefix is used.






platform: x86_64
mnem: FSTCW
description:
FSTCW/FNSTCW-Store x87 FPU Control Word
Opcode               Instruction                    64-Bit   Compat/    Description
                                                    Mode     Leg Mode
9B D9 /7             FSTCW m2byte                   Valid    Valid      Store FPU control word to m2byte after checking for
                                                                        pending unmasked floating-point exceptions.
D9 /7                FNSTCW* m2byte                 Valid    Valid      Store FPU control word to m2byte without checking for
                                                                        pending unmasked floating-point exceptions.
NOTES:
* See IA-32 Architecture Compatibility section below.



Description
Stores the current value of the FPU control word at the specified destination in memory. The FSTCW instruction
checks for and handles pending unmasked floating-point exceptions before storing the control word; the FNSTCW
instruction does not.
The assembler issues two instructions for the FSTCW instruction (an FWAIT instruction followed by an FNSTCW
instruction), and the processor executes each of these instructions in separately. If an exception is generated for
either of these instructions, the save EIP points to the instruction that caused the exception.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

IA-32 Architecture Compatibility
When operating a Pentium or Intel486 processor in MS-DOS compatibility mode, it is possible (under unusual
circumstances) for an FNSTCW instruction to be interrupted prior to being executed to handle a pending FPU
exception. See the section titled "No-Wait FPU Instructions Can Get FPU Interrupt in Window" in Appendix D of the
Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 1, for a description of these circum-
stances. An FNSTCW instruction cannot be interrupted in this way on later Intel processors, except for the Intel
QuarkTM X1000 processor.

Operation
DEST <- FPUControlWord;

FPU Flags Affected
The C0, C1, C2, and C3 flags are undefined.

Floating-Point Exceptions
None.

Protected Mode Exceptions
#GP(0)                 If the destination is located in a non-writable segment.
                       If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                       If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment
                       selector.
#SS(0)                 If a memory operand effective address is outside the SS segment limit.
#NM                    CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)        If a page fault occurs.
#AC(0)                 If alignment checking is enabled and an unaligned memory reference is made while the
                       current privilege level is 3.
#UD                    If the LOCK prefix is used.





Real-Address Mode Exceptions
#GP                 If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS                 If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#UD                 If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
#GP(0)              If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)              If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made.
#UD                 If the LOCK prefix is used.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#SS(0)              If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)              If the memory address is in a non-canonical form.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                 If there is a pending x87 FPU exception.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                 If the LOCK prefix is used.






platform: x86_64
mnem: FSTENV
description:
FSTENV/FNSTENV-Store x87 FPU Environment
 Opcode               Instruction                        64-Bit   Compat/    Description
                                                         Mode     Leg Mode
 9B D9 /6             FSTENV m14/28byte                  Valid    Valid      Store FPU environment to m14byte or m28byte
                                                                             after checking for pending unmasked floating-point
                                                                             exceptions. Then mask all floating-point exceptions.
 D9 /6                FNSTENV* m14/28byte                Valid    Valid      Store FPU environment to m14byte or m28byte
                                                                             without checking for pending unmasked floating-
                                                                             point exceptions. Then mask all floating-
                                                                             point exceptions.
 NOTES:
 * See IA-32 Architecture Compatibility section below.



Description
Saves the current FPU operating environment at the memory location specified with the destination operand, and
then masks all floating-point exceptions. The FPU operating environment consists of the FPU control word, status
word, tag word, instruction pointer, data pointer, and last opcode. Figures 8-9 through 8-12 in the Intel 64 and
IA-32 Architectures Software Developer's Manual, Volume 1, show the layout in memory of the stored environ-
ment, depending on the operating mode of the processor (protected or real) and the current operand-size attribute
(16-bit or 32-bit). In virtual-8086 mode, the real mode layouts are used.
The FSTENV instruction checks for and handles any pending unmasked floating-point exceptions before storing
the FPU environment; the FNSTENV instruction does not. The saved image reflects the state of the FPU after all
floating-point instructions preceding the FSTENV/FNSTENV instruction in the instruction stream have been
executed.
These instructions are often used by exception handlers because they provide access to the FPU instruction and
data pointers. The environment is typically saved in the stack. Masking all exceptions after saving the environment
prevents floating-point exceptions from interrupting the exception handler.
The assembler issues two instructions for the FSTENV instruction (an FWAIT instruction followed by an FNSTENV
instruction), and the processor executes each of these instructions separately. If an exception is generated for
either of these instructions, the save EIP points to the instruction that caused the exception.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

IA-32 Architecture Compatibility
When operating a Pentium or Intel486 processor in MS-DOS compatibility mode, it is possible (under unusual
circumstances) for an FNSTENV instruction to be interrupted prior to being executed to handle a pending FPU
exception. See the section titled "No-Wait FPU Instructions Can Get FPU Interrupt in Window" in Appendix D of the
Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 1, for a description of these circum-
stances. An FNSTENV instruction cannot be interrupted in this way on later Intel processors, except for the Intel
QuarkTM X1000 processor.

Operation
DEST[FPUControlWord] <- FPUControlWord;
DEST[FPUStatusWord] <- FPUStatusWord;
DEST[FPUTagWord] <- FPUTagWord;
DEST[FPUDataPointer] <- FPUDataPointer;
DEST[FPUInstructionPointer] <- FPUInstructionPointer;
DEST[FPULastInstructionOpcode] <- FPULastInstructionOpcode;

FPU Flags Affected
The C0, C1, C2, and C3 are undefined.




Floating-Point Exceptions
None

Protected Mode Exceptions
#GP(0)              If the destination is located in a non-writable segment.
                    If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                    If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment
                    selector.
#SS(0)              If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                 If the LOCK prefix is used.

Real-Address Mode Exceptions
#GP                 If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS                 If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#UD                 If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
#GP(0)              If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)              If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made.
#UD                 If the LOCK prefix is used.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#SS(0)              If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)              If the memory address is in a non-canonical form.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                 If there is a pending x87 FPU exception.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                 If the LOCK prefix is used.






platform: x86_64
mnem: FSTSW
description:
FSTSW/FNSTSW-Store x87 FPU Status Word
Opcode               Instruction                    64-Bit      Compat/    Description
                                                    Mode        Leg Mode
9B DD /7             FSTSW m2byte                       Valid   Valid      Store FPU status word at m2byte after checking
                                                                           for pending unmasked floating-point exceptions.
9B DF E0             FSTSW AX                           Valid   Valid      Store FPU status word in AX register after
                                                                           checking for pending unmasked floating-point
                                                                           exceptions.
DD /7                FNSTSW* m2byte                     Valid   Valid      Store FPU status word at m2byte without
                                                                           checking for pending unmasked floating-point
                                                                           exceptions.
DF E0                FNSTSW* AX                         Valid   Valid      Store FPU status word in AX register without
                                                                           checking for pending unmasked floating-point
                                                                           exceptions.
NOTES:
* See IA-32 Architecture Compatibility section below.



Description
Stores the current value of the x87 FPU status word in the destination location. The destination operand can be
either a two-byte memory location or the AX register. The FSTSW instruction checks for and handles pending
unmasked floating-point exceptions before storing the status word; the FNSTSW instruction does not.
The FNSTSW AX form of the instruction is used primarily in conditional branching (for instance, after an FPU
comparison instruction or an FPREM, FPREM1, or FXAM instruction), where the direction of the branch depends on
the state of the FPU condition code flags. (See the section titled "Branching and Conditional Moves on FPU Condi-
tion Codes" in Chapter 8 of the Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 1.) This
instruction can also be used to invoke exception handlers (by examining the exception flags) in environments that
do not use interrupts. When the FNSTSW AX instruction is executed, the AX register is updated before the
processor executes any further instructions. The status stored in the AX register is thus guaranteed to be from the
completion of the prior FPU instruction.
The assembler issues two instructions for the FSTSW instruction (an FWAIT instruction followed by an FNSTSW
instruction), and the processor executes each of these instructions separately. If an exception is generated for
either of these instructions, the save EIP points to the instruction that caused the exception.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

IA-32 Architecture Compatibility
When operating a Pentium or Intel486 processor in MS-DOS compatibility mode, it is possible (under unusual
circumstances) for an FNSTSW instruction to be interrupted prior to being executed to handle a pending FPU
exception. See the section titled "No-Wait FPU Instructions Can Get FPU Interrupt in Window" in Appendix D of the
Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 1, for a description of these circum-
stances. An FNSTSW instruction cannot be interrupted in this way on later Intel processors, except for the Intel
QuarkTM X1000 processor.

Operation
DEST <- FPUStatusWord;

FPU Flags Affected
The C0, C1, C2, and C3 are undefined.

Floating-Point Exceptions
None




Protected Mode Exceptions
#GP(0)              If the destination is located in a non-writable segment.
                    If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                    If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment
                    selector.
#SS(0)              If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                 If the LOCK prefix is used.

Real-Address Mode Exceptions
#GP                 If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS                 If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.

Virtual-8086 Mode Exceptions
#GP(0)              If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)              If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made.
#UD                 If the LOCK prefix is used.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#SS(0)              If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)              If the memory address is in a non-canonical form.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                 If there is a pending x87 FPU exception.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                 If the LOCK prefix is used.






platform: x86_64
mnem: FSUB
description:
FSUB/FSUBP/FISUB-Subtract
Opcode             Instruction               64-Bit      Compat/       Description
                                             Mode        Leg Mode
D8 /4              FSUB m32fp                Valid       Valid         Subtract m32fp from ST(0) and store result in ST(0).
DC /4              FSUB m64fp                Valid       Valid         Subtract m64fp from ST(0) and store result in ST(0).
D8 E0+i            FSUB ST(0), ST(i)         Valid       Valid         Subtract ST(i) from ST(0) and store result in ST(0).
DC E8+i            FSUB ST(i), ST(0)         Valid       Valid         Subtract ST(0) from ST(i) and store result in ST(i).
DE E8+i            FSUBP ST(i), ST(0)        Valid       Valid         Subtract ST(0) from ST(i), store result in ST(i), and
                                                                       pop register stack.
DE E9              FSUBP                     Valid       Valid         Subtract ST(0) from ST(1), store result in ST(1), and
                                                                       pop register stack.
DA /4              FISUB m32int              Valid       Valid         Subtract m32int from ST(0) and store result in ST(0).
DE /4              FISUB m16int              Valid       Valid         Subtract m16int from ST(0) and store result in ST(0).



Description
Subtracts the source operand from the destination operand and stores the difference in the destination location.
The destination operand is always an FPU data register; the source operand can be a register or a memory location.
Source operands in memory can be in single-precision or double-precision floating-point format or in word or
doubleword integer format.
The no-operand version of the instruction subtracts the contents of the ST(0) register from the ST(1) register and
stores the result in ST(1). The one-operand version subtracts the contents of a memory location (either a floating-
point or an integer value) from the contents of the ST(0) register and stores the result in ST(0). The two-operand
version, subtracts the contents of the ST(0) register from the ST(i) register or vice versa.
The FSUBP instructions perform the additional operation of popping the FPU register stack following the subtrac-
tion. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer
(TOP) by 1. The no-operand version of the floating-point subtract instructions always results in the register stack
being popped. In some assemblers, the mnemonic for this instruction is FSUB rather than FSUBP.
The FISUB instructions convert an integer source operand to double extended-precision floating-point format
before performing the subtraction.
Table 3-38 shows the results obtained when subtracting various classes of numbers from one another, assuming
that neither overflow nor underflow occurs. Here, the SRC value is subtracted from the DEST value (DEST - SRC =
result).
When the difference between two operands of like sign is 0, the result is +0, except for the round toward -inf mode,
in which case the result is -0. This instruction also guarantees that +0 - (-0) = +0, and that -0 - (+0) = -0. When the
source operand is an integer 0, it is treated as a +0.
When one operand is inf, the result is inf of the expected sign. If both operands are inf of the same sign, an invalid-
operation exception is generated.





                                            Table 3-38. FSUB/FSUBP/FISUB Results
                                                                          SRC
                                  -inf           - F or - I        -0             +0     + F or + I    +inf            NaN
                   -inf              *             -inf              -inf             -inf       -inf          -inf            NaN
                   -F             +inf           +-F or +-0         DEST            DEST      -F         -inf            NaN
 DEST              -0             +inf            -SRC              +-0            -0      - SRC        -inf            NaN
                   +0             +inf            -SRC             +0              +-0     - SRC        -inf            NaN
                   +F             +inf              +F            DEST            DEST   +-F or +-0      -inf            NaN
                   +inf             +inf             +inf              +inf             +inf       +inf            *           NaN
                  NaN            NaN             NaN             NaN            NaN      NaN         NaN           NaN
 NOTES:
 F Means finite floating-point value.
 I Means integer.
 * Indicates floating-point invalid-arithmetic-operand (#IA) exception.

This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
IF Instruction = FISUB
     THEN
         DEST <- DEST - ConvertToDoubleExtendedPrecisionFP(SRC);
     ELSE (* Source operand is floating-point value *)
         DEST <- DEST - SRC;
FI;

IF Instruction = FSUBP
     THEN
         PopRegisterStack;
FI;

FPU Flags Affected
C1                      Set to 0 if stack underflow occurred.
                        Set if result was rounded up; cleared otherwise.
C0, C2, C3              Undefined.

Floating-Point Exceptions
#IS                     Stack underflow occurred.
#IA                     Operand is an SNaN value or unsupported format.
                        Operands are infinities of like sign.
#D                      Source operand is a denormal value.
#U                      Result is too small for destination format.
#O                      Result is too large for destination format.
#P                      Value cannot be represented exactly in destination format.





Protected Mode Exceptions
#GP(0)                If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                      If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment
                      selector.
#SS(0)                If a memory operand effective address is outside the SS segment limit.
#NM                   CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)       If a page fault occurs.
#AC(0)                If alignment checking is enabled and an unaligned memory reference is made while the
                      current privilege level is 3.
#UD                   If the LOCK prefix is used.

Real-Address Mode Exceptions
#GP                   If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS                   If a memory operand effective address is outside the SS segment limit.
#NM                   CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#UD                   If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
#GP(0)                If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)                If a memory operand effective address is outside the SS segment limit.
#NM                   CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)       If a page fault occurs.
#AC(0)                If alignment checking is enabled and an unaligned memory reference is made.
#UD                   If the LOCK prefix is used.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#SS(0)                If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)                If the memory address is in a non-canonical form.
#NM                   CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                   If there is a pending x87 FPU exception.
#PF(fault-code)       If a page fault occurs.
#AC(0)                If alignment checking is enabled and an unaligned memory reference is made while the
                      current privilege level is 3.
#UD                   If the LOCK prefix is used.






platform: x86_64
mnem: FSUBR
description:
FSUBR/FSUBRP/FISUBR-Reverse Subtract
 Opcode           Instruction                   64-Bit    Compat/      Description
                                                Mode      Leg Mode
 D8 /5            FSUBR m32fp                   Valid     Valid        Subtract ST(0) from m32fp and store result in ST(0).
 DC /5            FSUBR m64fp                   Valid     Valid        Subtract ST(0) from m64fp and store result in ST(0).
 D8 E8+i          FSUBR ST(0), ST(i)            Valid     Valid        Subtract ST(0) from ST(i) and store result in ST(0).
 DC E0+i          FSUBR ST(i), ST(0)            Valid     Valid        Subtract ST(i) from ST(0) and store result in ST(i).
 DE E0+i          FSUBRP ST(i), ST(0)           Valid     Valid        Subtract ST(i) from ST(0), store result in ST(i), and
                                                                       pop register stack.
 DE E1            FSUBRP                        Valid     Valid        Subtract ST(1) from ST(0), store result in ST(1), and
                                                                       pop register stack.
 DA /5            FISUBR m32int                 Valid     Valid        Subtract ST(0) from m32int and store result in ST(0).
 DE /5            FISUBR m16int                 Valid     Valid        Subtract ST(0) from m16int and store result in ST(0).



Description
Subtracts the destination operand from the source operand and stores the difference in the destination location.
The destination operand is always an FPU register; the source operand can be a register or a memory location.
Source operands in memory can be in single-precision or double-precision floating-point format or in word or
doubleword integer format.
These instructions perform the reverse operations of the FSUB, FSUBP, and FISUB instructions. They are provided
to support more efficient coding.
The no-operand version of the instruction subtracts the contents of the ST(1) register from the ST(0) register and
stores the result in ST(1). The one-operand version subtracts the contents of the ST(0) register from the contents
of a memory location (either a floating-point or an integer value) and stores the result in ST(0). The two-operand
version, subtracts the contents of the ST(i) register from the ST(0) register or vice versa.
The FSUBRP instructions perform the additional operation of popping the FPU register stack following the subtrac-
tion. To pop the register stack, the processor marks the ST(0) register as empty and increments the stack pointer
(TOP) by 1. The no-operand version of the floating-point reverse subtract instructions always results in the register
stack being popped. In some assemblers, the mnemonic for this instruction is FSUBR rather than FSUBRP.
The FISUBR instructions convert an integer source operand to double extended-precision floating-point format
before performing the subtraction.
The following table shows the results obtained when subtracting various classes of numbers from one another,
assuming that neither overflow nor underflow occurs. Here, the DEST value is subtracted from the SRC value (SRC
- DEST = result).
When the difference between two operands of like sign is 0, the result is +0, except for the round toward -inf mode,
in which case the result is -0. This instruction also guarantees that +0 - (-0) = +0, and that -0 - (+0) = -0. When the
source operand is an integer 0, it is treated as a +0.
When one operand is inf, the result is inf of the expected sign. If both operands are inf of the same sign, an invalid-
operation exception is generated.





                                         Table 3-39. FSUBR/FSUBRP/FISUBR Results
                                                                          SRC
                                  -inf           -F or -I           -0             +0     +F or +I       +inf           NaN
                   -inf              *              +inf             +inf              +inf       +inf           +inf           NaN
                   -F             -inf           +-F or +-0        -DEST            -DEST     +F           +inf           NaN
 DEST              -0             -inf             SRC              +-0             +0      SRC           +inf           NaN
                   +0             -inf             SRC              -0             +-0      SRC           +inf           NaN
                   +F             -inf              -F           -DEST            -DEST   +-F or +-0       +inf           NaN
                   +inf             -inf              -inf             -inf              -inf       -inf             *          NaN
                  NaN            NaN             NaN             NaN            NaN      NaN           NaN          NaN
 NOTES:
 F Means finite floating-point value.
 I Means integer.
 * Indicates floating-point invalid-arithmetic-operand (#IA) exception.

This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
IF Instruction = FISUBR
     THEN
         DEST <- ConvertToDoubleExtendedPrecisionFP(SRC) - DEST;
     ELSE (* Source operand is floating-point value *)
         DEST <- SRC - DEST; FI;
IF Instruction = FSUBRP
     THEN
         PopRegisterStack; FI;

FPU Flags Affected
C1                      Set to 0 if stack underflow occurred.
                        Set if result was rounded up; cleared otherwise.
C0, C2, C3              Undefined.

Floating-Point Exceptions
#IS                     Stack underflow occurred.
#IA                     Operand is an SNaN value or unsupported format.
                        Operands are infinities of like sign.
#D                      Source operand is a denormal value.
#U                      Result is too small for destination format.
#O                      Result is too large for destination format.
#P                      Value cannot be represented exactly in destination format.





Protected Mode Exceptions
#GP(0)              If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                    If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment
                    selector.
#SS(0)              If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                 If the LOCK prefix is used.

Real-Address Mode Exceptions
#GP                 If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS                 If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#UD                 If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
#GP(0)              If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)              If a memory operand effective address is outside the SS segment limit.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made.
#UD                 If the LOCK prefix is used.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#SS(0)              If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)              If the memory address is in a non-canonical form.
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                 If there is a pending x87 FPU exception.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                 If the LOCK prefix is used.






platform: x86_64
mnem: FTST
description:
FTST-TEST
Opcode                    Instruction           64-Bit    Compat/         Description
                                                Mode      Leg Mode
D9 E4                     FTST                  Valid     Valid           Compare ST(0) with 0.0.



Description
Compares the value in the ST(0) register with 0.0 and sets the condition code flags C0, C2, and C3 in the FPU
status word according to the results (see table below).
                                               Table 3-40. FTST Results
                      Condition                              C3                    C2                      C0
                     ST(0) > 0.0                             0                     0                       0
                     ST(0) < 0.0                             0                     0                       1
                     ST(0) = 0.0                             1                     0                       0
                     Unordered                               1                     1                       1

This instruction performs an "unordered comparison." An unordered comparison also checks the class of the
numbers being compared (see "FXAM-Examine Floating-Point" in this chapter). If the value in register ST(0) is a
NaN or is in an undefined format, the condition flags are set to "unordered" and the invalid operation exception is
generated.
The sign of zero is ignored, so that (- 0.0 <- +0.0).
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
CASE (relation of operands) OF
   Not comparable: C3, C2, C0 <- 111;
   ST(0) > 0.0:       C3, C2, C0 <- 000;
   ST(0) < 0.0:       C3, C2, C0 <- 001;
   ST(0) = 0.0:       C3, C2, C0 <- 100;
ESAC;

FPU Flags Affected
C1                     Set to 0.
C0, C2, C3             See Table 3-40.

Floating-Point Exceptions
#IS                    Stack underflow occurred.
#IA                    The source operand is a NaN value or is in an unsupported format.
#D                     The source operand is a denormal value.

Protected Mode Exceptions
#NM                    CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                    If there is a pending x87 FPU exception.
#UD                    If the LOCK prefix is used.

Real-Address Mode Exceptions
Same exceptions as in protected mode.





Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: FUCOM
description:
FUCOM/FUCOMP/FUCOMPP-Unordered Compare Floating Point Values
Opcode                Instruction               64-Bit       Compat/      Description
                                                Mode         Leg Mode
DD E0+i               FUCOM ST(i)               Valid        Valid        Compare ST(0) with ST(i).
DD E1                 FUCOM                     Valid        Valid        Compare ST(0) with ST(1).
DD E8+i               FUCOMP ST(i)              Valid        Valid        Compare ST(0) with ST(i) and pop register stack.
DD E9                 FUCOMP                    Valid        Valid        Compare ST(0) with ST(1) and pop register stack.
DA E9                 FUCOMPP                   Valid        Valid        Compare ST(0) with ST(1) and pop register stack twice.



Description
Performs an unordered comparison of the contents of register ST(0) and ST(i) and sets condition code flags C0, C2,
and C3 in the FPU status word according to the results (see the table below). If no operand is specified, the
contents of registers ST(0) and ST(1) are compared. The sign of zero is ignored, so that -0.0 is equal to +0.0.
                                        Table 3-41. FUCOM/FUCOMP/FUCOMPP Results
                     Comparison Results*                                   C3                     C2                    C0
                          ST0 > ST(i)                                       0                      0                     0
                          ST0 < ST(i)                                       0                      0                     1
                          ST0 = ST(i)                                       1                      0                     0
                           Unordered                                        1                      1                     1
 NOTES:
 * Flags not set if unmasked invalid-arithmetic-operand (#IA) exception is generated.

An unordered comparison checks the class of the numbers being compared (see "FXAM-Examine Floating-Point"
in this chapter). The FUCOM/FUCOMP/FUCOMPP instructions perform the same operations as the
FCOM/FCOMP/FCOMPP instructions. The only difference is that the FUCOM/FUCOMP/FUCOMPP instructions raise
the invalid-arithmetic-operand exception (#IA) only when either or both operands are an SNaN or are in an unsup-
ported format; QNaNs cause the condition code flags to be set to unordered, but do not cause an exception to be
generated. The FCOM/FCOMP/FCOMPP instructions raise an invalid-operation exception when either or both of the
operands are a NaN value of any kind or are in an unsupported format.
As with the FCOM/FCOMP/FCOMPP instructions, if the operation results in an invalid-arithmetic-operand exception
being raised, the condition code flags are set only if the exception is masked.
The FUCOMP instruction pops the register stack following the comparison operation and the FUCOMPP instruction
pops the register stack twice following the comparison operation. To pop the register stack, the processor marks
the ST(0) register as empty and increments the stack pointer (TOP) by 1.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.





Operation
CASE (relation of operands) OF
   ST > SRC:          C3, C2, C0 <- 000;
   ST < SRC:          C3, C2, C0 <- 001;
   ST = SRC:          C3, C2, C0 <- 100;
ESAC;

IF ST(0) or SRC = QNaN, but not SNaN or unsupported format
    THEN
         C3, C2, C0 <- 111;
    ELSE (* ST(0) or SRC is SNaN or unsupported format *)
          #IA;
         IF FPUControlWord.IM = 1
               THEN
                   C3, C2, C0 <- 111;
         FI;
FI;

IF Instruction = FUCOMP
     THEN
         PopRegisterStack;
FI;

IF Instruction = FUCOMPP
     THEN
         PopRegisterStack;
FI;

FPU Flags Affected
C1                     Set to 0 if stack underflow occurred.
C0, C2, C3             See Table 3-41.

Floating-Point Exceptions
#IS                    Stack underflow occurred.
#IA                    One or both operands are SNaN values or have unsupported formats. Detection of a QNaN
                       value in and of itself does not raise an invalid-operand exception.
#D                     One or both operands are denormal values.

Protected Mode Exceptions
#NM                    CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                    If there is a pending x87 FPU exception.
#UD                    If the LOCK prefix is used.

Real-Address Mode Exceptions
Same exceptions as in protected mode.

Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.





64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: FXAM
description:
FXAM-Examine Floating-Point
    Opcode                 Instruction              64-Bit     Compat/       Description
                                                    Mode       Leg Mode
    D9 E5                  FXAM                     Valid       Valid        Classify value or number in ST(0).



Description
Examines the contents of the ST(0) register and sets the condition code flags C0, C2, and C3 in the FPU status word
to indicate the class of value or number in the register (see the table below).
                                                       Table 3-42. FXAM Results
.




                             Class                                      C3                   C2                      C0
    Unsupported                                                         0                     0                      0
    NaN                                                                 0                     0                      1
    Normal finite number                                                0                     1                      0
    Infinity                                                            0                     1                      1
    Zero                                                                1                     0                      0
    Empty                                                               1                     0                      1
    Denormal number                                                     1                     1                      0

The C1 flag is set to the sign of the value in ST(0), regardless of whether the register is empty or full.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
C1 <- sign bit of ST; (* 0 for positive, 1 for negative *)

CASE (class of value or number in ST(0)) OF
   Unsupported:C3, C2, C0 <- 000;
   NaN:           C3, C2, C0 <- 001;
   Normal:        C3, C2, C0 <- 010;
   Infinity:      C3, C2, C0 <- 011;
   Zero:          C3, C2, C0 <- 100;
   Empty:         C3, C2, C0 <- 101;
   Denormal:      C3, C2, C0 <- 110;
ESAC;

FPU Flags Affected
C1                         Sign of value in ST(0).
C0, C2, C3                 See Table 3-42.

Floating-Point Exceptions
None

Protected Mode Exceptions
#NM                        CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                        If there is a pending x87 FPU exception.
#UD                        If the LOCK prefix is used.

Real-Address Mode Exceptions
Same exceptions as in protected mode.



Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: FXCH
description:
FXCH-Exchange Register Contents
Opcode                  Instruction         64-Bit    Compat/       Description
                                            Mode      Leg Mode
D9 C8+i                 FXCH ST(i)          Valid     Valid         Exchange the contents of ST(0) and ST(i).
D9 C9                   FXCH                Valid     Valid         Exchange the contents of ST(0) and ST(1).



Description
Exchanges the contents of registers ST(0) and ST(i). If no source operand is specified, the contents of ST(0) and
ST(1) are exchanged.
This instruction provides a simple means of moving values in the FPU register stack to the top of the stack [ST(0)],
so that they can be operated on by those floating-point instructions that can only operate on values in ST(0). For
example, the following instruction sequence takes the square root of the third register from the top of the register
stack:
     FXCH ST(3);
     FSQRT;
     FXCH ST(3);
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
IF (Number-of-operands) is 1
    THEN
        temp <- ST(0);
        ST(0) <- SRC;
        SRC <- temp;
    ELSE
        temp <- ST(0);
        ST(0) <- ST(1);
        ST(1) <- temp;
FI;

FPU Flags Affected
C1                     Set to 0.
C0, C2, C3             Undefined.

Floating-Point Exceptions
#IS                    Stack underflow occurred.

Protected Mode Exceptions
#NM                    CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                    If there is a pending x87 FPU exception.
#UD                    If the LOCK prefix is used.

Real-Address Mode Exceptions
Same exceptions as in protected mode.

Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.





Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: FXRSTOR
description:
FXRSTOR-Restore x87 FPU, MMX, XMM, and MXCSR State
 Opcode/                                         Op/     64-Bit   Compat/ Description
 Instruction                                     En      Mode     Leg Mode
 0F AE /1                                        M       Valid    Valid        Restore the x87 FPU, MMX, XMM, and MXCSR
 FXRSTOR m512byte                                                              register state from m512byte.

 REX.W+ 0F AE /1                                 M       Valid    N.E.         Restore the x87 FPU, MMX, XMM, and MXCSR
 FXRSTOR64 m512byte                                                            register state from m512byte.



                                            Instruction Operand Encoding
   Op/En            Operand 1                Operand 2                    Operand 3                     Operand 4
     M             ModRM:r/m (r)                 NA                           NA                           NA

Description
Reloads the x87 FPU, MMX technology, XMM, and MXCSR registers from the 512-byte memory image specified in
the source operand. This data should have been written to memory previously using the FXSAVE instruction, and
in the same format as required by the operating modes. The first byte of the data should be located on a 16-byte
boundary. There are three distinct layouts of the FXSAVE state map: one for legacy and compatibility mode, a
second format for 64-bit mode FXSAVE/FXRSTOR with REX.W=0, and the third format is for 64-bit mode with
FXSAVE64/FXRSTOR64. Table 3-43 shows the layout of the legacy/compatibility mode state information in memory
and describes the fields in the memory image for the FXRSTOR and FXSAVE instructions. Table 3-46 shows the
layout of the 64-bit mode state information when REX.W is set (FXSAVE64/FXRSTOR64). Table 3-47 shows the
layout of the 64-bit mode state information when REX.W is clear (FXSAVE/FXRSTOR).
The state image referenced with an FXRSTOR instruction must have been saved using an FXSAVE instruction or be
in the same format as required by Table 3-43, Table 3-46, or Table 3-47. Referencing a state image saved with an
FSAVE, FNSAVE instruction or incompatible field layout will result in an incorrect state restoration.
The FXRSTOR instruction does not flush pending x87 FPU exceptions. To check and raise exceptions when loading
x87 FPU state information with the FXRSTOR instruction, use an FWAIT instruction after the FXRSTOR instruction.
If the OSFXSR bit in control register CR4 is not set, the FXRSTOR instruction may not restore the states of the XMM
and MXCSR registers. This behavior is implementation dependent.
If the MXCSR state contains an unmasked exception with a corresponding status flag also set, loading the register
with the FXRSTOR instruction will not result in a SIMD floating-point error condition being generated. Only the next
occurrence of this unmasked exception will result in the exception being generated.
Bits 16 through 32 of the MXCSR register are defined as reserved and should be set to 0. Attempting to write a 1 in
any of these bits from the saved state image will result in a general protection exception (#GP) being generated.
Bytes 464:511 of an FXSAVE image are available for software use. FXRSTOR ignores the content of bytes 464:511
in an FXSAVE state image.

Operation
IF 64-Bit Mode
    THEN
        (x87 FPU, MMX, XMM15-XMM0, MXCSR) Load(SRC);
    ELSE
         (x87 FPU, MMX, XMM7-XMM0, MXCSR) <- Load(SRC);
FI;

x87 FPU and SIMD Floating-Point Exceptions
None.





Protected Mode Exceptions
#GP(0)                 For an illegal memory operand effective address in the CS, DS, ES, FS or GS segments.
                       If a memory operand is not aligned on a 16-byte boundary, regardless of segment. (See align-
                       ment check exception [#AC] below.)
                       For an attempt to set reserved bits in MXCSR.
#SS(0)                 For an illegal address in the SS segment.
#PF(fault-code)        For a page fault.
#NM                    If CR0.TS[bit 3] = 1.
                       If CR0.EM[bit 2] = 1.
#UD                    If CPUID.01H:EDX.FXSR[bit 24] = 0.
                       If instruction is preceded by a LOCK prefix.
#AC                    If this exception is disabled a general protection exception (#GP) is signaled if the memory
                       operand is not aligned on a 16-byte boundary, as described above. If the alignment check
                       exception (#AC) is enabled (and the CPL is 3), signaling of #AC is not guaranteed and may
                       vary with implementation, as follows. In all implementations where #AC is not signaled, a
                       general protection exception is signaled in its place. In addition, the width of the alignment
                       check may also vary with implementation. For instance, for a given implementation, an align-
                       ment check exception might be signaled for a 2-byte misalignment, whereas a general protec-
                       tion exception might be signaled for all other misalignments (4-, 8-, or 16-byte
                       misalignments).
#UD                    If the LOCK prefix is used.

Real-Address Mode Exceptions
#GP                    If a memory operand is not aligned on a 16-byte boundary, regardless of segment.
                       If any part of the operand lies outside the effective address space from 0 to FFFFH.
                       For an attempt to set reserved bits in MXCSR.
#NM                    If CR0.TS[bit 3] = 1.
                       If CR0.EM[bit 2] = 1.
#UD                    If CPUID.01H:EDX.FXSR[bit 24] = 0.
                       If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
Same exceptions as in real address mode.
#PF(fault-code)        For a page fault.
#AC                    For unaligned memory reference.
#UD                    If the LOCK prefix is used.

Compatibility Mode Exceptions
Same exceptions as in protected mode.





64-Bit Mode Exceptions
#SS(0)              If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)              If the memory address is in a non-canonical form.
                    If memory operand is not aligned on a 16-byte boundary, regardless of segment.
                    For an attempt to set reserved bits in MXCSR.
#PF(fault-code)     For a page fault.
#NM                 If CR0.TS[bit 3] = 1.
                    If CR0.EM[bit 2] = 1.
#UD                 If CPUID.01H:EDX.FXSR[bit 24] = 0.
                    If instruction is preceded by a LOCK prefix.
#AC                 If this exception is disabled a general protection exception (#GP) is signaled if the memory
                    operand is not aligned on a 16-byte boundary, as described above. If the alignment check
                    exception (#AC) is enabled (and the CPL is 3), signaling of #AC is not guaranteed and may
                    vary with implementation, as follows. In all implementations where #AC is not signaled, a
                    general protection exception is signaled in its place. In addition, the width of the alignment
                    check may also vary with implementation. For instance, for a given implementation, an align-
                    ment check exception might be signaled for a 2-byte misalignment, whereas a general protec-
                    tion exception might be signaled for all other misalignments (4-, 8-, or 16-byte
                    misalignments).






platform: x86_64
mnem: FXSAVE
description:
FXSAVE-Save x87 FPU, MMX Technology, and SSE State
 Opcode/                                                Op/      64-Bit       Compat/ Description
 Instruction                                            En       Mode         Leg Mode
 0F AE /0                                               M        Valid        Valid          Save the x87 FPU, MMX, XMM, and MXCSR
 FXSAVE m512byte                                                                             register state to m512byte.

 REX.W+ 0F AE /0                                        M        Valid        N.E.           Save the x87 FPU, MMX, XMM, and MXCSR
 FXSAVE64 m512byte                                                                           register state to m512byte.



                                                Instruction Operand Encoding
   Op/En                Operand 1                    Operand 2                           Operand 3                  Operand 4
     M             ModRM:r/m (w)                        NA                                  NA                          NA

Description
Saves the current state of the x87 FPU, MMX technology, XMM, and MXCSR registers to a 512-byte memory loca-
tion specified in the destination operand. The content layout of the 512 byte region depends on whether the
processor is operating in non-64-bit operating modes or 64-bit sub-mode of IA-32e mode.
Bytes 464:511 are available to software use. The processor does not write to bytes 464:511 of an FXSAVE area.
The operation of FXSAVE in non-64-bit modes is described first.

Non-64-Bit Mode Operation
Table 3-43 shows the layout of the state information in memory when the processor is operating in legacy modes.

                               Table 3-43. Non-64-bit-Mode Layout of FXSAVE and FXRSTOR
                                                     Memory Region
   15      14      13     12        11 10        9      8          7      6          5         4     3         2    1    0
     Rsvd           FCS                 FIP[31:0]                   FOP         Rsvd        FTW          FSW         FCW           0
         MXCSR_MASK                     MXCSR                       Rsrvd                FDS                FDP[31:0]              16
                 Reserved                                                            ST0/MM0                                       32
                 Reserved                                                            ST1/MM1                                       48
                 Reserved                                                            ST2/MM2                                       64
                 Reserved                                                            ST3/MM3                                       80
                 Reserved                                                            ST4/MM4                                       96
                 Reserved                                                            ST5/MM5                                      112
                 Reserved                                                            ST6/MM6                                      128
                 Reserved                                                            ST7/MM7                                      144
                                                             XMM0                                                                 160
                                                             XMM1                                                                 176
                                                             XMM2                                                                 192
                                                             XMM3                                                                 208
                                                             XMM4                                                                 224
                                                             XMM5                                                                 240
                                                             XMM6                                                                 256
                                                             XMM7                                                                 272
                                                            Reserved                                                              288



                          Table 3-43. Non-64-bit-Mode Layout of FXSAVE and FXRSTOR
                                           Memory Region (Contd.)
   15    14     13   12       11 10           9     8          7    6       5        4           3   2         1    0
                                                        Reserved                                                             304
                                                        Reserved                                                             320
                                                        Reserved                                                             336
                                                        Reserved                                                             352
                                                        Reserved                                                             368
                                                        Reserved                                                             384
                                                        Reserved                                                             400
                                                        Reserved                                                             416
                                                        Reserved                                                             432
                                                        Reserved                                                             448
                                                        Available                                                            464
                                                        Available                                                            480
                                                        Available                                                            496

The destination operand contains the first byte of the memory image, and it must be aligned on a 16-byte
boundary. A misaligned destination operand will result in a general-protection (#GP) exception being generated (or
in some cases, an alignment check exception [#AC]).
The FXSAVE instruction is used when an operating system needs to perform a context switch or when an exception
handler needs to save and examine the current state of the x87 FPU, MMX technology, and/or XMM and MXCSR
registers.
The fields in Table 3-43 are defined in Table 3-44.


                                              Table 3-44. Field Definitions
 Field                     Definition
 FCW                       x87 FPU Control Word (16 bits). See Figure 8-6 in the Intel 64 and IA-32 Architectures Software
                           Developer's Manual, Volume 1, for the layout of the x87 FPU control word.
 FSW                       x87 FPU Status Word (16 bits). See Figure 8-4 in the Intel 64 and IA-32 Architectures Software
                           Developer's Manual, Volume 1, for the layout of the x87 FPU status word.
 Abridged FTW              x87 FPU Tag Word (8 bits). The tag information saved here is abridged, as described in the following
                           paragraphs.
 FOP                       x87 FPU Opcode (16 bits). The lower 11 bits of this field contain the opcode, upper 5 bits are reserved.
                           See Figure 8-8 in the Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 1, for
                           the layout of the x87 FPU opcode field.
 FIP                       x87 FPU Instruction Pointer Offset (64 bits). The contents of this field differ depending on the current
                           addressing mode (32-bit, 16-bit, or 64-bit) of the processor when the FXSAVE instruction was
                           executed:
                           32-bit mode - 32-bit IP offset.
                           16-bit mode - low 16 bits are IP offset; high 16 bits are reserved.
                           64-bit mode with REX.W - 64-bit IP offset.
                           64-bit mode without REX.W - 32-bit IP offset.
                           See "x87 FPU Instruction and Operand (Data) Pointers" in Chapter 8 of the Intel 64 and IA-32
                           Architectures Software Developer's Manual, Volume 1, for a description of the x87 FPU instruction
                           pointer.





                                            Table 3-44. Field Definitions (Contd.)
    Field                     Definition
    FCS                       x87 FPU Instruction Pointer Selector (16 bits). If CPUID.(EAX=07H,ECX=0H):EBX[bit 13] = 1, the
                              processor deprecates FCS and FDS, and this field is saved as 0000H.
    FDP                       x87 FPU Instruction Operand (Data) Pointer Offset (64 bits). The contents of this field differ
                              depending on the current addressing mode (32-bit, 16-bit, or 64-bit) of the processor when the
                              FXSAVE instruction was executed:
                              32-bit mode - 32-bit DP offset.
                              16-bit mode - low 16 bits are DP offset; high 16 bits are reserved.
                              64-bit mode with REX.W - 64-bit DP offset.
                              64-bit mode without REX.W - 32-bit DP offset.
                              See "x87 FPU Instruction and Operand (Data) Pointers" in Chapter 8 of the Intel 64 and IA-32
                              Architectures Software Developer's Manual, Volume 1, for a description of the x87 FPU operand
                              pointer.
    FDS                       x87 FPU Instruction Operand (Data) Pointer Selector (16 bits). If CPUID.(EAX=07H,ECX=0H):EBX[bit
                              13] = 1, the processor deprecates FCS and FDS, and this field is saved as 0000H.
    MXCSR                     MXCSR Register State (32 bits). See Figure 10-3 in the Intel 64 and IA-32 Architectures Software
                              Developer's Manual, Volume 1, for the layout of the MXCSR register. If the OSFXSR bit in control
                              register CR4 is not set, the FXSAVE instruction may not save this register. This behavior is
                              implementation dependent.
    MXCSR_                    MXCSR_MASK (32 bits). This mask can be used to adjust values written to the MXCSR register,
    MASK                      ensuring that reserved bits are set to 0. Set the mask bits and flags in MXCSR to the mode of
                              operation desired for SSE and SSE2 SIMD floating-point instructions. See "Guidelines for Writing to the
                              MXCSR Register" in Chapter 11 of the Intel 64 and IA-32 Architectures Software Developer's Manual,
                              Volume 1, for instructions for how to determine and use the MXCSR_MASK value.
    ST0/MM0 through           x87 FPU or MMX technology registers. These 80-bit fields contain the x87 FPU data registers or the
    ST7/MM7                   MMX technology registers, depending on the state of the processor prior to the execution of the
                              FXSAVE instruction. If the processor had been executing x87 FPU instruction prior to the FXSAVE
                              instruction, the x87 FPU data registers are saved; if it had been executing MMX instructions (or SSE or
                              SSE2 instructions that operated on the MMX technology registers), the MMX technology registers are
                              saved. When the MMX technology registers are saved, the high 16 bits of the field are reserved.
    XMM0 through XMM7         XMM registers (128 bits per field). If the OSFXSR bit in control register CR4 is not set, the FXSAVE
                              instruction may not save these registers. This behavior is implementation dependent.

The FXSAVE instruction saves an abridged version of the x87 FPU tag word in the FTW field (unlike the FSAVE
instruction, which saves the complete tag word). The tag information is saved in physical register order (R0
through R7), rather than in top-of-stack (TOS) order. With the FXSAVE instruction, however, only a single bit (1 for
valid or 0 for empty) is saved for each tag. For example, assume that the tag word is currently set as follows:

     R7 R6 R5 R4 R3 R2 R1 R0
     11 xx xx xx 11 11 11 11
Here, 11B indicates empty stack elements and "xx" indicates valid (00B), zero (01B), or special (10B).
For this example, the FXSAVE instruction saves only the following 8 bits of information:

     R7 R6 R5 R4 R3 R2 R1 R0
     0 1 1 1 0 0 0 0
Here, a 1 is saved for any valid, zero, or special tag, and a 0 is saved for any empty tag.
The operation of the FXSAVE instruction differs from that of the FSAVE instruction, the as follows:
.     FXSAVE instruction does not check for pending unmasked floating-point exceptions. (The FXSAVE operation in
      this regard is similar to the operation of the FNSAVE instruction).
.     After the FXSAVE instruction has saved the state of the x87 FPU, MMX technology, XMM, and MXCSR registers,
      the processor retains the contents of the registers. Because of this behavior, the FXSAVE instruction cannot be



      used by an application program to pass a "clean" x87 FPU state to a procedure, since it retains the current
      state. To clean the x87 FPU state, an application must explicitly execute an FINIT instruction after an FXSAVE
      instruction to reinitialize the x87 FPU state.
.     The format of the memory image saved with the FXSAVE instruction is the same regardless of the current
      addressing mode (32-bit or 16-bit) and operating mode (protected, real address, or system management).
      This behavior differs from the FSAVE instructions, where the memory image format is different depending on
      the addressing mode and operating mode. Because of the different image formats, the memory image saved
      with the FXSAVE instruction cannot be restored correctly with the FRSTOR instruction, and likewise the state
      saved with the FSAVE instruction cannot be restored correctly with the FXRSTOR instruction.
The FSAVE format for FTW can be recreated from the FTW valid bits and the stored 80-bit FP data (assuming the
stored data was not the contents of MMX technology registers) using Table 3-45.

                                         Table 3-45. Recreating FSAVE Format
       Exponent             Exponent       Fraction           J and M         FTW valid bit
         all 1's              all 0's       all 0's             bits                                      x87 FTW
            0                   0             0                 0x                  1           Special              10
            0                   0             0                 1x                  1           Valid                00
            0                   0             1                 00                  1           Special              10
            0                   0             1                 10                  1           Valid                00
            0                   1             0                 0x                  1           Special              10
            0                   1             0                 1x                  1           Special              10
            0                   1             1                 00                  1           Zero                 01
            0                   1             1                 10                  1           Special              10
            1                   0             0                 1x                  1           Special              10
            1                   0             0                 1x                  1           Special              10
            1                   0             1                 00                  1           Special              10
            1                   0             1                 10                  1           Special              10
    For all legal combinations above.                                               0           Empty                11

The J-bit is defined to be the 1-bit binary integer to the left of the decimal place in the significand. The M-bit is
defined to be the most significant bit of the fractional portion of the significand (i.e., the bit immediately to the right
of the decimal place).
When the M-bit is the most significant bit of the fractional portion of the significand, it must be 0 if the fraction is all
0's.

IA-32e Mode Operation
In compatibility sub-mode of IA-32e mode, legacy SSE registers, XMM0 through XMM7, are saved according to the
legacy FXSAVE map. In 64-bit mode, all of the SSE registers, XMM0 through XMM15, are saved. Additionally, there
are two different layouts of the FXSAVE map in 64-bit mode, corresponding to FXSAVE64 (which requires
REX.W=1) and FXSAVE (REX.W=0). In the FXSAVE64 map (Table 3-46), the FPU IP and FPU DP pointers are 64-bit
wide. In the FXSAVE map for 64-bit mode (Table 3-47), the FPU IP and FPU DP pointers are 32-bits.





                                      Table 3-46. Layout of the 64-bit-mode FXSAVE64 Map
                                                      (requires REX.W = 1)
   15    14      13   12         11    10     9      8      7    6      5        4    3      2       1   0
                           FIP                               FOP     Reserved   FTW   FSW            FCW          0
        MXCSR_MASK                      MXCSR                                   FDP                               16
                Reserved                                                 ST0/MM0                                  32
                Reserved                                                 ST1/MM1                                  48
                Reserved                                                 ST2/MM2                                  64
                Reserved                                                 ST3/MM3                                  80
                Reserved                                                 ST4/MM4                                  96
                Reserved                                                 ST5/MM5                                 112
                Reserved                                                 ST6/MM6                                 128
                Reserved                                                 ST7/MM7                                 144
                                                          XMM0                                                   160
                                                          XMM1                                                   176
                                                          XMM2                                                   192
                                                          XMM3                                                   208
                                                          XMM4                                                   224
                                                          XMM5                                                   240
                                                          XMM6                                                   256
                                                          XMM7                                                   272
                                                          XMM8                                                   288
                                                          XMM9                                                   304
                                                         XMM10                                                   320
                                                         XMM11                                                   336
                                                         XMM12                                                   352
                                                         XMM13                                                   368
                                                         XMM14                                                   384
                                                         XMM15                                                   400
                                                         Reserved                                                416
                                                         Reserved                                                432
                                                         Reserved                                                448
                                                         Available                                               464
                                                         Available                                               480
                                                         Available                                               496





                           Table 3-47. Layout of the 64-bit-mode FXSAVE Map (REX.W = 0)
   15    14      13   12     11   10       9   8       7       6      5           4         3   2        1    0
   Reserved       FCS              FIP[31:0]            FOP        Reserved      FTW        FSW          FCW            0
        MXCSR_MASK                 MXCSR              Reserved             FDS                  FDP[31:0]               16
                Reserved                                                  ST0/MM0                                       32
                Reserved                                                  ST1/MM1                                       48
                Reserved                                                  ST2/MM2                                       64
                Reserved                                                  ST3/MM3                                       80
                Reserved                                                  ST4/MM4                                       96
                Reserved                                                  ST5/MM5                                      112
                Reserved                                                  ST6/MM6                                      128
                Reserved                                                  ST7/MM7                                      144
                                                    XMM0                                                               160
                                                    XMM1                                                               176
                                                    XMM2                                                               192
                                                    XMM3                                                               208
                                                    XMM4                                                               224
                                                    XMM5                                                               240
                                                    XMM6                                                               256
                                                    XMM7                                                               272
                                                    XMM8                                                               288
                                                    XMM9                                                               304
                                                   XMM10                                                               320
                                                   XMM11                                                               336
                                                   XMM12                                                               352
                                                   XMM13                                                               368
                                                   XMM14                                                               384
                                                   XMM15                                                               400
                                                   Reserved                                                            416
                                                   Reserved                                                            432
                                                   Reserved                                                            448
                                                   Available                                                           464
                                                   Available                                                           480
                                                   Available                                                           496





Operation
IF 64-Bit Mode
    THEN
         IF REX.W = 1
              THEN
                  DEST <- Save64BitPromotedFxsave(x87 FPU, MMX, XMM15-XMM0,
                  MXCSR);
              ELSE
                  DEST <- Save64BitDefaultFxsave(x87 FPU, MMX, XMM15-XMM0, MXCSR);
         FI;
    ELSE
         DEST <- SaveLegacyFxsave(x87 FPU, MMX, XMM7-XMM0, MXCSR);
FI;

Protected Mode Exceptions
#GP(0)                 For an illegal memory operand effective address in the CS, DS, ES, FS or GS segments.
                       If a memory operand is not aligned on a 16-byte boundary, regardless of segment. (See the
                       description of the alignment check exception [#AC] below.)
#SS(0)                 For an illegal address in the SS segment.
#PF(fault-code)        For a page fault.
#NM                    If CR0.TS[bit 3] = 1.
                       If CR0.EM[bit 2] = 1.
#UD                    If CPUID.01H:EDX.FXSR[bit 24] = 0.
#UD                    If the LOCK prefix is used.
#AC                    If this exception is disabled a general protection exception (#GP) is signaled if the memory
                       operand is not aligned on a 16-byte boundary, as described above. If the alignment check
                       exception (#AC) is enabled (and the CPL is 3), signaling of #AC is not guaranteed and may
                       vary with implementation, as follows. In all implementations where #AC is not signaled, a
                       general protection exception is signaled in its place. In addition, the width of the alignment
                       check may also vary with implementation. For instance, for a given implementation, an align-
                       ment check exception might be signaled for a 2-byte misalignment, whereas a general protec-
                       tion exception might be signaled for all other misalignments (4-, 8-, or 16-byte
                       misalignments).

Real-Address Mode Exceptions
#GP                    If a memory operand is not aligned on a 16-byte boundary, regardless of segment.
                       If any part of the operand lies outside the effective address space from 0 to FFFFH.
#NM                    If CR0.TS[bit 3] = 1.
                       If CR0.EM[bit 2] = 1.
#UD                    If CPUID.01H:EDX.FXSR[bit 24] = 0.
                       If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
Same exceptions as in real address mode.
#PF(fault-code)        For a page fault.
#AC                    For unaligned memory reference.
#UD                    If the LOCK prefix is used.

Compatibility Mode Exceptions
Same exceptions as in protected mode.




64-Bit Mode Exceptions
#SS(0)              If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)              If the memory address is in a non-canonical form.
                    If memory operand is not aligned on a 16-byte boundary, regardless of segment.
#PF(fault-code)     For a page fault.
#NM                 If CR0.TS[bit 3] = 1.
                    If CR0.EM[bit 2] = 1.
#UD                 If CPUID.01H:EDX.FXSR[bit 24] = 0.
                    If the LOCK prefix is used.
#AC                 If this exception is disabled a general protection exception (#GP) is signaled if the memory
                    operand is not aligned on a 16-byte boundary, as described above. If the alignment check
                    exception (#AC) is enabled (and the CPL is 3), signaling of #AC is not guaranteed and may
                    vary with implementation, as follows. In all implementations where #AC is not signaled, a
                    general protection exception is signaled in its place. In addition, the width of the alignment
                    check may also vary with implementation. For instance, for a given implementation, an align-
                    ment check exception might be signaled for a 2-byte misalignment, whereas a general protec-
                    tion exception might be signaled for all other misalignments (4-, 8-, or 16-byte
                    misalignments).

Implementation Note
The order in which the processor signals general-protection (#GP) and page-fault (#PF) exceptions when they both
occur on an instruction boundary is given in Table 5-2 in the Intel 64 and IA-32 Architectures Software Devel-
oper's Manual, Volume 3B. This order vary for FXSAVE for different processor implementations.






platform: x86_64
mnem: FXTRACT
description:
FXTRACT-Extract Exponent and Significand
 Opcode/                                       64-Bit   Compat/    Description
 Instruction                                   Mode     Leg Mode
 D9 F4                                         Valid    Valid      Separate value in ST(0) into exponent and significand, store
 FXTRACT                                                           exponent in ST(0), and push the significand onto the register
                                                                   stack.



Description
Separates the source value in the ST(0) register into its exponent and significand, stores the exponent in ST(0),
and pushes the significand onto the register stack. Following this operation, the new top-of-stack register ST(0)
contains the value of the original significand expressed as a floating-point value. The sign and significand of this
value are the same as those found in the source operand, and the exponent is 3FFFH (biased value for a true expo-
nent of zero). The ST(1) register contains the value of the original operand's true (unbiased) exponent expressed
as a floating-point value. (The operation performed by this instruction is a superset of the IEEE-recommended
logb(x) function.)
This instruction and the F2XM1 instruction are useful for performing power and range scaling operations. The
FXTRACT instruction is also useful for converting numbers in double extended-precision floating-point format to
decimal representations (e.g., for printing or displaying).
If the floating-point zero-divide exception (#Z) is masked and the source operand is zero, an exponent value of -
inf is stored in register ST(1) and 0 with the sign of the source operand is stored in register ST(0).
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
TEMP <- Significand(ST(0));
ST(0) <- Exponent(ST(0));
TOP<- TOP - 1;
ST(0) <- TEMP;

FPU Flags Affected
C1                      Set to 0 if stack underflow occurred; set to 1 if stack overflow occurred.
C0, C2, C3              Undefined.

Floating-Point Exceptions
#IS                     Stack underflow or overflow occurred.
#IA                     Source operand is an SNaN value or unsupported format.
#Z                      ST(0) operand is +-0.
#D                      Source operand is a denormal value.

Protected Mode Exceptions
#NM                     CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                     If there is a pending x87 FPU exception.
#UD                     If the LOCK prefix is used.

Real-Address Mode Exceptions
Same exceptions as in protected mode.

Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.





Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: FYL2X
description:
FYL2X-Compute y * log2x
Opcode                   Instruction             64-Bit           Compat/           Description
                                                 Mode             Leg Mode
D9 F1                    FYL2X                   Valid            Valid             Replace ST(1) with (ST(1) * log2ST(0)) and pop the
                                                                                    register stack.



Description
Computes (ST(1) * log2 (ST(0))), stores the result in resister ST(1), and pops the FPU register stack. The source
operand in ST(0) must be a non-zero positive number.
The following table shows the results obtained when taking the log of various classes of numbers, assuming that
neither overflow nor underflow occurs.
                                                    Table 3-48. FYL2X Results
                                                                            ST(0)
                                 -inf         -F            +-0              +0<+F<+1            +1        +F>+1           +inf           NaN

                   -inf             *          *            +inf                 +inf                   *        -inf           -inf           NaN

     ST(1)         -F             *          *            **                 +F               -0           -F           -inf           NaN

                   -0             *          *                *              +0               -0           -0             *          NaN

                   +0             *          *                *              -0               +0           +0             *          NaN

                   +F             *          *            **                 -F               +0           +F           +inf           NaN

                   +inf             *          *            -   inf              -inf                   *        +inf           +inf           NaN

                   NaN           NaN       NaN            NaN                NaN              NaN          NaN          NaN          NaN

 NOTES:
 F Means finite floating-point value.
 * Indicates floating-point invalid-operation (#IA) exception.
 ** Indicates floating-point zero-divide (#Z) exception.


If the divide-by-zero exception is masked and register ST(0) contains +-0, the instruction returns inf with a sign that
is the opposite of the sign of the source operand in register ST(1).
The FYL2X instruction is designed with a built-in multiplication to optimize the calculation of logarithms with an
arbitrary positive base (b):

     logbx <- (log2b)-1 * log2x
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
ST(1) <- ST(1) * log2ST(0);
PopRegisterStack;

FPU Flags Affected
C1                        Set to 0 if stack underflow occurred.
                          Set if result was rounded up; cleared otherwise.
C0, C2, C3                Undefined.





Floating-Point Exceptions
#IS                 Stack underflow occurred.
#IA                 Either operand is an SNaN or unsupported format.
                    Source operand in register ST(0) is a negative finite value
                    (not -0).
#Z                  Source operand in register ST(0) is +-0.
#D                  Source operand is a denormal value.
#U                  Result is too small for destination format.
#O                  Result is too large for destination format.
#P                  Value cannot be represented exactly in destination format.

Protected Mode Exceptions
#NM                 CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                 If there is a pending x87 FPU exception.
#UD                 If the LOCK prefix is used.

Real-Address Mode Exceptions
Same exceptions as in protected mode.

Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: FYL2XP1
description:
FYL2XP1-Compute y * log2(x +1)
 Opcode                   Instruction              64-Bit        Compat/             Description
                                                   Mode          Leg Mode
 D9 F9                    FYL2XP1                  Valid         Valid               Replace ST(1) with ST(1) * log2(ST(0) + 1.0) and pop the
                                                                                     register stack.



Description
Computes (ST(1) * log2(ST(0) + 1.0)), stores the result in register ST(1), and pops the FPU register stack. The
source operand in ST(0) must be in the range:
     - ( 1 - 2 / 2 ) )to ( 1 - 2 / 2 )
The source operand in ST(1) can range from -inf to +inf. If the ST(0) operand is outside of its acceptable range, the
result is undefined and software should not rely on an exception being generated. Under some circumstances
exceptions may be generated when ST(0) is out of range, but this behavior is implementation specific and not
guaranteed.
The following table shows the results obtained when taking the log epsilon of various classes of numbers, assuming
that underflow does not occur.
                                                     Table 3-49. FYL2XP1 Results
                                                                             ST(0)
                                     -(1 - ( 2 / 2 )) to -0          -0              +0             +0 to +(1 - ( 2 / 2 ))          NaN
                     -inf                       +inf                         *            *                     -inf                      NaN
     ST(1)           -F                       +F                     +0               -0                     -F                     NaN
                     -0                       +0                     +0               -0                     -0                     NaN
                     +0                       -0                    -0               +0                      +0                     NaN
                     +F                       -F                    -0               +0                      +F                     NaN
                     +inf                       -inf                         *            *                     +inf                      NaN
                    NaN                      NaN                    NaN              NaN                    NaN                     NaN
 NOTES:
 F Means finite floating-point value.
 * Indicates floating-point invalid-operation (#IA) exception.

This instruction provides optimal accuracy for values of epsilon [the value in register ST(0)] that are close to 0. For
small epsilon (e) values, more significant digits can be retained by using the FYL2XP1 instruction than by using
(e+1) as an argument to the FYL2X instruction. The (e+1) expression is commonly found in compound interest and
annuity calculations. The result can be simply converted into a value in another logarithm base by including a scale
factor in the ST(1) source operand. The following equation is used to calculate the scale factor for a particular loga-
rithm base, where n is the logarithm base desired for the result of the FYL2XP1 instruction:

   scale factor <- logn 2
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
ST(1) <- ST(1) * log2(ST(0) + 1.0);
PopRegisterStack;





FPU Flags Affected
C1                   Set to 0 if stack underflow occurred.
                     Set if result was rounded up; cleared otherwise.
C0, C2, C3           Undefined.

Floating-Point Exceptions
#IS                  Stack underflow occurred.
#IA                  Either operand is an SNaN value or unsupported format.
#D                   Source operand is a denormal value.
#U                   Result is too small for destination format.
#O                   Result is too large for destination format.
#P                   Value cannot be represented exactly in destination format.

Protected Mode Exceptions
#NM                  CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#MF                  If there is a pending x87 FPU exception.
#UD                  If the LOCK prefix is used.

Real-Address Mode Exceptions
Same exceptions as in protected mode.

Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: HADDPD
description:
HADDPD-Packed Double-FP Horizontal Add
 Opcode/                                              Op/      64/32-bit CPUID            Description
 Instruction                                          En       Mode      Feature
                                                                         Flag
 66 0F 7C /r                                          RM       V/V        SSE3            Horizontal add packed double-precision
 HADDPD xmm1, xmm2/m128                                                                   floating-point values from xmm2/m128 to
                                                                                          xmm1.
 VEX.NDS.128.66.0F.WIG 7C /r                          RVM V/V             AVX             Horizontal add packed double-precision
 VHADDPD xmm1,xmm2, xmm3/m128                                                             floating-point values from xmm2 and
                                                                                          xmm3/mem.
 VEX.NDS.256.66.0F.WIG 7C /r                          RVM V/V             AVX             Horizontal add packed double-precision
 VHADDPD ymm1, ymm2, ymm3/m256                                                            floating-point values from ymm2 and
                                                                                          ymm3/mem.



                                                Instruction Operand Encoding
  Op/En             Operand 1                    Operand 2                       Operand 3                           Operand 4
    RM           ModRM:reg (r, w)              ModRM:r/m (r)                             NA                             NA
   RVM            ModRM:reg (w)                 VEX.vvvv (r)                  ModRM:r/m (r)                             NA

Description
Adds the double-precision floating-point values in the high and low quadwords of the destination operand and
stores the result in the low quadword of the destination operand.
Adds the double-precision floating-point values in the high and low quadwords of the source operand and stores the
result in the high quadword of the destination operand.
In 64-bit mode, use of the REX.R prefix permits this instruction to access additional registers (XMM8-XMM15).
See Figure 3-16 for HADDPD; see Figure 3-17 for VHADDPD.




                                                 HADDPD xmm1, xmm2/m128

                                                                                                         xmm2
                                          [127:64]                              [63:0]
                                                                                                         /m128




                                          [127:64]                              [63:0]                   xmm1




                                     xmm2/m128[63:0] +                                                   Result:
                                                                     xmm1[63:0] + xmm1[127:64]
                                     xmm2/m128[127:64]                                                   xmm1

                                          [127:64]                               [63:0]


                                                                                                           OM15993



                                  Figure 3-16. HADDPD-Packed Double-FP Horizontal Add





                       SRC1         X3               X2             X1            X0



                       SRC2         Y3               Y2             Y1            Y0



                       DEST      Y2 + Y3          X2 + X3        Y0 + Y1       X0 + X1




                                            Figure 3-17. VHADDPD operation

128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The desti-
nation is not distinct from the first source XMM register and the upper bits (VLMAX-1:128) of the corresponding
YMM register destination are unmodified.
VEX.128 encoded version: the first source operand is an XMM register or 128-bit memory location. The destination
operand is an XMM register. The upper bits (VLMAX-1:128) of the corresponding YMM register destination are
zeroed.
VEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM
register or a 256-bit memory location. The destination operand is a YMM register.

Operation
HADDPD (128-bit Legacy SSE version)
DEST[63:0] <- SRC1[127:64] + SRC1[63:0]
DEST[127:64] <- SRC2[127:64] + SRC2[63:0]
DEST[VLMAX-1:128] (Unmodified)

VHADDPD (VEX.128 encoded version)
DEST[63:0] <- SRC1[127:64] + SRC1[63:0]
DEST[127:64] <- SRC2[127:64] + SRC2[63:0]
DEST[VLMAX-1:128] <- 0

VHADDPD (VEX.256 encoded version)
DEST[63:0] <- SRC1[127:64] + SRC1[63:0]
DEST[127:64] <- SRC2[127:64] + SRC2[63:0]
DEST[191:128] <- SRC1[255:192] + SRC1[191:128]
DEST[255:192] <- SRC2[255:192] + SRC2[191:128]

Intel C/C++ Compiler Intrinsic Equivalent
VHADDPD: __m256d _mm256_hadd_pd (__m256d a, __m256d b);

HADDPD:      __m128d _mm_hadd_pd (__m128d a, __m128d b);

Exceptions
When the source operand is a memory operand, the operand must be aligned on a 16-byte boundary or a general-
protection exception (#GP) will be generated.





Numeric Exceptions
Overflow, Underflow, Invalid, Precision, Denormal

Other Exceptions
See Exceptions Type 2.






platform: x86_64
mnem: HADDPS
description:
HADDPS-Packed Single-FP Horizontal Add
Opcode/                                         Op/    64/32-bit CPUID       Description
Instruction                                     En     Mode      Feature
                                                                 Flag
F2 0F 7C /r                                     RM     V/V       SSE3        Horizontal add packed single-precision
HADDPS xmm1, xmm2/m128                                                       floating-point values from xmm2/m128 to
                                                                             xmm1.
VEX.NDS.128.F2.0F.WIG 7C /r                     RVM V/V          AVX         Horizontal add packed single-precision
VHADDPS xmm1, xmm2, xmm3/m128                                                floating-point values from xmm2 and
                                                                             xmm3/mem.
VEX.NDS.256.F2.0F.WIG 7C /r                     RVM V/V          AVX         Horizontal add packed single-precision
VHADDPS ymm1, ymm2, ymm3/m256                                                floating-point values from ymm2 and
                                                                             ymm3/mem.



                                           Instruction Operand Encoding
   Op/En            Operand 1                  Operand 2                   Operand 3                     Operand 4
     RM          ModRM:reg (r, w)            ModRM:r/m (r)                    NA                            NA
    RVM           ModRM:reg (w)               VEX.vvvv (r)              ModRM:r/m (r)                       NA

Description
Adds the single-precision floating-point values in the first and second dwords of the destination operand and stores
the result in the first dword of the destination operand.
Adds single-precision floating-point values in the third and fourth dword of the destination operand and stores the
result in the second dword of the destination operand.
Adds single-precision floating-point values in the first and second dword of the source operand and stores the
result in the third dword of the destination operand.
Adds single-precision floating-point values in the third and fourth dword of the source operand and stores the result
in the fourth dword of the destination operand.
In 64-bit mode, use of the REX.R prefix permits this instruction to access additional registers (XMM8-XMM15).





See Figure 3-18 for HADDPS; see Figure 3-19 for VHADDPS.



                                                      HADDPS xmm1, xmm2/m128

                                                                                                               xmm2/
                                  [127:96]               [95:64]               [63:32]          [31:0]
                                                                                                               m128




                                  [127:96]               [95:64]               [63:32]          [31:0]         xmm1




                                 xmm2/m128             xmm2/m128
                                                                         xmm1[95:64] +      xmm1[31:0] +       RESULT:
                               [95:64] + xmm2/        [31:0] + xmm2/
                                                                         xmm1[127:96]       xmm1[63:32]        xmm1
                                m128[127:96]           m128[63:32]


                                  [127:96]               [95:64]            [63:32]               [31:0]


                                                                                                                      OM15994


                                  Figure 3-18. HADDPS-Packed Single-FP Horizontal Add




                           SRC1     X7           X6         X5         X4           X3     X2            X1      X0



                           SRC2     Y7           Y6         Y5         Y4           Y3     Y2            Y1      Y0



                           DEST Y6+Y7        Y4+Y5         X6+X7       X4+X5      Y2+Y3   Y0+Y1      X2+X3      X0+X1




                                                  Figure 3-19. VHADDPS operation



128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The desti-
nation is not distinct from the first source XMM register and the upper bits (VLMAX-1:128) of the corresponding
YMM register destination are unmodified.
VEX.128 encoded version: the first source operand is an XMM register or 128-bit memory location. The destination
operand is an XMM register. The upper bits (VLMAX-1:128) of the corresponding YMM register destination are
zeroed.
VEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM
register or a 256-bit memory location. The destination operand is a YMM register.





Operation
HADDPS (128-bit Legacy SSE version)
DEST[31:0] <- SRC1[63:32] + SRC1[31:0]
DEST[63:32] <- SRC1[127:96] + SRC1[95:64]
DEST[95:64] <- SRC2[63:32] + SRC2[31:0]
DEST[127:96] <- SRC2[127:96] + SRC2[95:64]
DEST[VLMAX-1:128] (Unmodified)

VHADDPS (VEX.128 encoded version)
DEST[31:0] <- SRC1[63:32] + SRC1[31:0]
DEST[63:32] <- SRC1[127:96] + SRC1[95:64]
DEST[95:64] <- SRC2[63:32] + SRC2[31:0]
DEST[127:96] <- SRC2[127:96] + SRC2[95:64]
DEST[VLMAX-1:128] <- 0

VHADDPS (VEX.256 encoded version)
DEST[31:0] <- SRC1[63:32] + SRC1[31:0]
DEST[63:32] <- SRC1[127:96] + SRC1[95:64]
DEST[95:64] <- SRC2[63:32] + SRC2[31:0]
DEST[127:96] <- SRC2[127:96] + SRC2[95:64]
DEST[159:128] <- SRC1[191:160] + SRC1[159:128]
DEST[191:160] <- SRC1[255:224] + SRC1[223:192]
DEST[223:192] <- SRC2[191:160] + SRC2[159:128]
DEST[255:224] <- SRC2[255:224] + SRC2[223:192]

Intel C/C++ Compiler Intrinsic Equivalent
HADDPS:      __m128 _mm_hadd_ps (__m128 a, __m128 b);

VHADDPS:     __m256 _mm256_hadd_ps (__m256 a, __m256 b);

Exceptions
When the source operand is a memory operand, the operand must be aligned on a 16-byte boundary or a general-
protection exception (#GP) will be generated.

Numeric Exceptions
Overflow, Underflow, Invalid, Precision, Denormal

Other Exceptions
See Exceptions Type 2.






platform: x86_64
mnem: HLT
description:
HLT-Halt
Opcode                  Instruction                 Op/    64-Bit   Compat/ Description
                                                    En     Mode     Leg Mode
F4                      HLT                         NP     Valid    Valid       Halt



                                             Instruction Operand Encoding
   Op/En            Operand 1                  Operand 2                    Operand 3              Operand 4
     NP                NA                         NA                           NA                      NA

Description
Stops instruction execution and places the processor in a HALT state. An enabled interrupt (including NMI and
SMI), a debug exception, the BINIT# signal, the INIT# signal, or the RESET# signal will resume execution. If an
interrupt (including NMI) is used to resume execution after a HLT instruction, the saved instruction pointer
(CS:EIP) points to the instruction following the HLT instruction.
When a HLT instruction is executed on an Intel 64 or IA-32 processor supporting Intel Hyper-Threading Technology,
only the logical processor that executes the instruction is halted. The other logical processors in the physical
processor remain active, unless they are each individually halted by executing a HLT instruction.
The HLT instruction is a privileged instruction. When the processor is running in protected or virtual-8086 mode,
the privilege level of a program or procedure must be 0 to execute the HLT instruction.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
Enter Halt state;

Flags Affected
None

Protected Mode Exceptions
#GP(0)                If the current privilege level is not 0.
#UD                   If the LOCK prefix is used.

Real-Address Mode Exceptions
None.

Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: HSUBPD
description:
HSUBPD-Packed Double-FP Horizontal Subtract
Opcode/                                               Op/    64/32-bit CPUID            Description
Instruction                                           En     Mode      Feature
                                                                       Flag
66 0F 7D /r                                           RM     V/V        SSE3            Horizontal subtract packed double-precision
HSUBPD xmm1, xmm2/m128                                                                  floating-point values from xmm2/m128 to
                                                                                        xmm1.
VEX.NDS.128.66.0F.WIG 7D /r                           RVM V/V           AVX             Horizontal subtract packed double-precision
VHSUBPD xmm1,xmm2, xmm3/m128                                                            floating-point values from xmm2 and
                                                                                        xmm3/mem.
VEX.NDS.256.66.0F.WIG 7D /r                           RVM V/V           AVX             Horizontal subtract packed double-precision
VHSUBPD ymm1, ymm2, ymm3/m256                                                           floating-point values from ymm2 and
                                                                                        ymm3/mem.



                                              Instruction Operand Encoding
   Op/En           Operand 1                        Operand 2                     Operand 3                        Operand 4
    RM          ModRM:reg (r, w)               ModRM:r/m (r)                            NA                             NA
    RVM          ModRM:reg (w)                     VEX.vvvv (r)                 ModRM:r/m (r)                          NA

Description
The HSUBPD instruction subtracts horizontally the packed DP FP numbers of both operands.
Subtracts the double-precision floating-point value in the high quadword of the destination operand from the low
quadword of the destination operand and stores the result in the low quadword of the destination operand.
Subtracts the double-precision floating-point value in the high quadword of the source operand from the low quad-
word of the source operand and stores the result in the high quadword of the destination operand.
In 64-bit mode, use of the REX.R prefix permits this instruction to access additional registers (XMM8-XMM15).


See Figure 3-20 for HSUBPD; see Figure 3-21 for VHSUBPD.


                                                   HSUBPD xmm1, xmm2/m128

                                                                                                      xmm2
                                        [127:64]                              [63:0]
                                                                                                      /m128




                                        [127:64]                              [63:0]                  xmm1




                                    xmm2/m128[63:0] -                                                 Result:
                                                                   xmm1[63:0] - xmm1[127:64]
                                   xmm2/m128[127:64]                                                  xmm1

                                        [127:64]                               [63:0]


                                                                                                        OM15995



                           Figure 3-20. HSUBPD-Packed Double-FP Horizontal Subtract





                         SRC1           X3              X2             X1          X0



                         SRC2           Y3              Y2             Y1          Y0



                         DEST        Y2 - Y3         X2 - X3        Y0 - Y1     X0 - X1




                                               Figure 3-21. VHSUBPD operation

128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The desti-
nation is not distinct from the first source XMM register and the upper bits (VLMAX-1:128) of the corresponding
YMM register destination are unmodified.
VEX.128 encoded version: the first source operand is an XMM register or 128-bit memory location. The destination
operand is an XMM register. The upper bits (VLMAX-1:128) of the corresponding YMM register destination are
zeroed.
VEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM
register or a 256-bit memory location. The destination operand is a YMM register.

Operation
HSUBPD (128-bit Legacy SSE version)
DEST[63:0] <- SRC1[63:0] - SRC1[127:64]
DEST[127:64] <- SRC2[63:0] - SRC2[127:64]
DEST[VLMAX-1:128] (Unmodified)

VHSUBPD (VEX.128 encoded version)
DEST[63:0] <- SRC1[63:0] - SRC1[127:64]
DEST[127:64] <- SRC2[63:0] - SRC2[127:64]
DEST[VLMAX-1:128] <- 0

VHSUBPD (VEX.256 encoded version)
DEST[63:0] <- SRC1[63:0] - SRC1[127:64]
DEST[127:64] <- SRC2[63:0] - SRC2[127:64]
DEST[191:128] <- SRC1[191:128] - SRC1[255:192]
DEST[255:192] <- SRC2[191:128] - SRC2[255:192]

Intel C/C++ Compiler Intrinsic Equivalent
HSUBPD:       __m128d _mm_hsub_pd(__m128d a, __m128d b)

VHSUBPD:      __m256d _mm256_hsub_pd (__m256d a, __m256d b);

Exceptions
When the source operand is a memory operand, the operand must be aligned on a 16-byte boundary or a general-
protection exception (#GP) will be generated.

Numeric Exceptions
Overflow, Underflow, Invalid, Precision, Denormal



Other Exceptions
See Exceptions Type 2.






platform: x86_64
mnem: HSUBPS
description:
HSUBPS-Packed Single-FP Horizontal Subtract
 Opcode/                                           Op/   64/32-bit CPUID       Description
 Instruction                                       En    Mode      Feature
                                                                   Flag
 F2 0F 7D /r                                       RM    V/V       SSE3        Horizontal subtract packed single-precision
 HSUBPS xmm1, xmm2/m128                                                        floating-point values from xmm2/m128 to
                                                                               xmm1.
 VEX.NDS.128.F2.0F.WIG 7D /r                       RVM V/V         AVX         Horizontal subtract packed single-precision
 VHSUBPS xmm1, xmm2, xmm3/m128                                                 floating-point values from xmm2 and
                                                                               xmm3/mem.
 VEX.NDS.256.F2.0F.WIG 7D /r                       RVM V/V         AVX         Horizontal subtract packed single-precision
 VHSUBPS ymm1, ymm2, ymm3/m256                                                 floating-point values from ymm2 and
                                                                               ymm3/mem.



                                              Instruction Operand Encoding
   Op/En              Operand 1                 Operand 2                    Operand 3                    Operand 4
     RM            ModRM:reg (r, w)           ModRM:r/m (r)                     NA                           NA
    RVM             ModRM:reg (w)              VEX.vvvv (r)               ModRM:r/m (r)                      NA

Description
Subtracts the single-precision floating-point value in the second dword of the destination operand from the first
dword of the destination operand and stores the result in the first dword of the destination operand.
Subtracts the single-precision floating-point value in the fourth dword of the destination operand from the third
dword of the destination operand and stores the result in the second dword of the destination operand.
Subtracts the single-precision floating-point value in the second dword of the source operand from the first dword
of the source operand and stores the result in the third dword of the destination operand.
Subtracts the single-precision floating-point value in the fourth dword of the source operand from the third dword
of the source operand and stores the result in the fourth dword of the destination operand.
In 64-bit mode, use of the REX.R prefix permits this instruction to access additional registers (XMM8-XMM15).
See Figure 3-22 for HSUBPS; see Figure 3-23 for VHSUBPS.





                                                HSUBPS xmm1, xmm2/m128

                                                                                                              xmm2/
                             [127:96]                 [95:64]              [63:32]             [31:0]
                                                                                                              m128




                             [127:96]                 [95:64]              [63:32]             [31:0]         xmm1




                             xmm2/m128              xmm2/m128
                                                                      xmm1[95:64] -       xmm1[31:0] -        RESULT:
                           [95:64] - xmm2/         [31:0] - xmm2/
                                                                      xmm1[127:96]        xmm1[63:32]         xmm1
                            m128[127:96]            m128[63:32]


                              [127:96]                [95:64]             [63:32]               [31:0]


                                                                                                                     OM15996



                           Figure 3-22. HSUBPS-Packed Single-FP Horizontal Subtract




                         SRC1    X7           X6          X5         X4             X3    X2             X1      X0



                         SRC2    Y7           Y6          Y5         Y4             Y3    Y2             Y1      Y0



                         DEST Y6-Y7          Y4-Y5       X6-X7      X4-X5      Y2-Y3     Y0-Y1      X2-X3      X0-X1




                                               Figure 3-23. VHSUBPS operation

128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The desti-
nation is not distinct from the first source XMM register and the upper bits (VLMAX-1:128) of the corresponding
YMM register destination are unmodified.
VEX.128 encoded version: the first source operand is an XMM register or 128-bit memory location. The destination
operand is an XMM register. The upper bits (VLMAX-1:128) of the corresponding YMM register destination are
zeroed.
VEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM
register or a 256-bit memory location. The destination operand is a YMM register.





Operation
HSUBPS (128-bit Legacy SSE version)
DEST[31:0] <- SRC1[31:0] - SRC1[63:32]
DEST[63:32] <- SRC1[95:64] - SRC1[127:96]
DEST[95:64] <- SRC2[31:0] - SRC2[63:32]
DEST[127:96] <- SRC2[95:64] - SRC2[127:96]
DEST[VLMAX-1:128] (Unmodified)

VHSUBPS (VEX.128 encoded version)
DEST[31:0] <- SRC1[31:0] - SRC1[63:32]
DEST[63:32] <- SRC1[95:64] - SRC1[127:96]
DEST[95:64] <- SRC2[31:0] - SRC2[63:32]
DEST[127:96] <- SRC2[95:64] - SRC2[127:96]
DEST[VLMAX-1:128] <- 0

VHSUBPS (VEX.256 encoded version)
DEST[31:0] <- SRC1[31:0] - SRC1[63:32]
DEST[63:32] <- SRC1[95:64] - SRC1[127:96]
DEST[95:64] <- SRC2[31:0] - SRC2[63:32]
DEST[127:96] <- SRC2[95:64] - SRC2[127:96]
DEST[159:128] <- SRC1[159:128] - SRC1[191:160]
DEST[191:160] <- SRC1[223:192] - SRC1[255:224]
DEST[223:192] <- SRC2[159:128] - SRC2[191:160]
DEST[255:224] <- SRC2[223:192] - SRC2[255:224]

Intel C/C++ Compiler Intrinsic Equivalent
HSUBPS:     __m128 _mm_hsub_ps(__m128 a, __m128 b);

VHSUBPS: __m256 _mm256_hsub_ps (__m256 a, __m256 b);

Exceptions
When the source operand is a memory operand, the operand must be aligned on a 16-byte boundary or a general-
protection exception (#GP) will be generated.

Numeric Exceptions
Overflow, Underflow, Invalid, Precision, Denormal

Other Exceptions
See Exceptions Type 2.






platform: x86_64
mnem: IDIV
description:
IDIV-Signed Divide
 Opcode                   Instruction                  Op/    64-Bit          Compat/ Description
                                                       En     Mode            Leg Mode
 F6 /7                    IDIV r/m8                    M      Valid           Valid       Signed divide AX by r/m8, with result stored in:
                                                                                          AL <- Quotient, AH <- Remainder.
 REX + F6 /7              IDIV r/m8*                   M      Valid           N.E.        Signed divide AX by r/m8, with result stored in
                                                                                          AL <- Quotient, AH <- Remainder.
 F7 /7                    IDIV r/m16                   M      Valid           Valid       Signed divide DX:AX by r/m16, with result
                                                                                          stored in AX <- Quotient, DX <- Remainder.
 F7 /7                    IDIV r/m32                   M      Valid           Valid       Signed divide EDX:EAX by r/m32, with result
                                                                                          stored in EAX <- Quotient, EDX <- Remainder.
 REX.W + F7 /7            IDIV r/m64                   M      Valid           N.E.        Signed divide RDX:RAX by r/m64, with result
                                                                                          stored in RAX <- Quotient, RDX <- Remainder.
 NOTES:
 * In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.



                                                   Instruction Operand Encoding
   Op/En              Operand 1                     Operand 2                          Operand 3                      Operand 4
     M              ModRM:r/m (r)                       NA                                NA                             NA

Description
Divides the (signed) value in the AX, DX:AX, or EDX:EAX (dividend) by the source operand (divisor) and stores the
result in the AX (AH:AL), DX:AX, or EDX:EAX registers. The source operand can be a general-purpose register or a
memory location. The action of this instruction depends on the operand size (dividend/divisor).
Non-integral results are truncated (chopped) towards 0. The remainder is always less than the divisor in magni-
tude. Overflow is indicated with the #DE (divide error) exception rather than with the CF flag.
In 64-bit mode, the instruction's default operation size is 32 bits. Use of the REX.R prefix permits access to addi-
tional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits. In 64-bit mode when REX.W is
applied, the instruction divides the signed value in RDX:RAX by the source operand. RAX contains a 64-bit
quotient; RDX contains a 64-bit remainder.
See the summary chart at the beginning of this section for encoding data and limits. See Table 3-50.
                                                     Table 3-50. IDIV Results
           Operand Size                 Dividend        Divisor             Quotient        Remainder              Quotient Range
 Word/byte                          AX               r/m8              AL                 AH                 -128 to +127
 Doubleword/word                    DX:AX            r/m16             AX                 DX                 -32,768 to +32,767
 Quadword/doubleword                EDX:EAX          r/m32             EAX                EDX                -231 to 231 - 1
 Doublequadword/ quadword           RDX:RAX          r/m64             RAX                RDX                -263 to 263 - 1





Operation
IF SRC = 0
    THEN #DE; (* Divide error *)
FI;

IF OperandSize = 8 (* Word/byte operation *)
    THEN
        temp <- AX / SRC; (* Signed division *)
        IF (temp > 7FH) or (temp < 80H)
        (* If a positive result is greater than 7FH or a negative result is less than 80H *)
              THEN #DE; (* Divide error *)
              ELSE
                    AL <- temp;
                    AH <- AX SignedModulus SRC;
        FI;
    ELSE IF OperandSize = 16 (* Doubleword/word operation *)
        THEN
              temp <- DX:AX / SRC; (* Signed division *)
              IF (temp > 7FFFH) or (temp < 8000H)
              (* If a positive result is greater than 7FFFH
              or a negative result is less than 8000H *)
                    THEN
                         #DE; (* Divide error *)
                    ELSE
                         AX <- temp;
                         DX <- DX:AX SignedModulus SRC;
              FI;
        FI;
    ELSE IF OperandSize = 32 (* Quadword/doubleword operation *)
              temp <- EDX:EAX / SRC; (* Signed division *)
              IF (temp > 7FFFFFFFH) or (temp < 80000000H)
              (* If a positive result is greater than 7FFFFFFFH
              or a negative result is less than 80000000H *)
                    THEN
                         #DE; (* Divide error *)
                    ELSE
                         EAX <- temp;
                         EDX <- EDXE:AX SignedModulus SRC;
              FI;
        FI;
    ELSE IF OperandSize = 64 (* Doublequadword/quadword operation *)
              temp <- RDX:RAX / SRC; (* Signed division *)
              IF (temp > 7FFFFFFFFFFFFFFFH) or (temp < 8000000000000000H)
              (* If a positive result is greater than 7FFFFFFFFFFFFFFFH
              or a negative result is less than 8000000000000000H *)
                    THEN
                         #DE; (* Divide error *)
                    ELSE
                         RAX <- temp;
                         RDX <- RDE:RAX SignedModulus SRC;
              FI;
        FI;
FI;




Flags Affected
The CF, OF, SF, ZF, AF, and PF flags are undefined.

Protected Mode Exceptions
#DE                  If the source operand (divisor) is 0.
                     The signed result (quotient) is too large for the destination.
#GP(0)               If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                    If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment
                    selector.
#SS(0)               If a memory operand effective address is outside the SS segment limit.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                  If the LOCK prefix is used.

Real-Address Mode Exceptions
#DE                  If the source operand (divisor) is 0.

                    The signed result (quotient) is too large for the destination.
#GP                  If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS                  If a memory operand effective address is outside the SS segment limit.
#UD                  If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
#DE                  If the source operand (divisor) is 0.

                    The signed result (quotient) is too large for the destination.
#GP(0)               If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)               If a memory operand effective address is outside the SS segment limit.
#PF(fault-code)     If a page fault occurs.
#AC(0)               If alignment checking is enabled and an unaligned memory reference is made.
#UD                  If the LOCK prefix is used.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#SS(0)               If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)              If the memory address is in a non-canonical form.
#DE                  If the source operand (divisor) is 0
                     If the quotient is too large for the designated register.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                  If the LOCK prefix is used.






platform: x86_64
mnem: IMUL
description:
IMUL-Signed Multiply
 Opcode                    Instruction                  Op/      64-Bit     Compat/ Description
                                                        En       Mode       Leg Mode
 F6 /5                     IMUL r/m8*                   M        Valid      Valid       AX<- AL * r/m byte.
 F7 /5                     IMUL r/m16                   M        Valid      Valid       DX:AX <- AX * r/m word.
 F7 /5                     IMUL r/m32                   M        Valid      Valid       EDX:EAX <- EAX * r/m32.
 REX.W + F7 /5             IMUL r/m64                   M        Valid      N.E.        RDX:RAX <- RAX * r/m64.
 0F AF /r                  IMUL r16, r/m16              RM       Valid      Valid       word register <- word register * r/m16.
 0F AF /r                  IMUL r32, r/m32              RM       Valid      Valid       doubleword register <- doubleword register *
                                                                                        r/m32.
 REX.W + 0F AF /r          IMUL r64, r/m64              RM       Valid      N.E.        Quadword register <- Quadword register *
                                                                                        r/m64.
 6B /r ib                  IMUL r16, r/m16, imm8        RMI      Valid      Valid       word register <- r/m16 * sign-extended
                                                                                        immediate byte.
 6B /r ib                  IMUL r32, r/m32, imm8        RMI      Valid      Valid       doubleword register <- r/m32 * sign-
                                                                                        extended immediate byte.
 REX.W + 6B /r ib          IMUL r64, r/m64, imm8        RMI      Valid      N.E.        Quadword register <- r/m64 * sign-extended
                                                                                        immediate byte.
 69 /r iw                  IMUL r16, r/m16, imm16       RMI      Valid      Valid       word register <- r/m16 * immediate word.
 69 /r id                  IMUL r32, r/m32, imm32       RMI      Valid      Valid       doubleword register <- r/m32 * immediate
                                                                                        doubleword.
 REX.W + 69 /r id          IMUL r64, r/m64, imm32       RMI      Valid      N.E.        Quadword register <- r/m64 * immediate
                                                                                        doubleword.
 NOTES:
 * In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.



                                                  Instruction Operand Encoding
    Op/En              Operand 1                     Operand 2                      Operand 3                     Operand 4
      M             ModRM:r/m (r, w)                    NA                             NA                             NA
     RM             ModRM:reg (r, w)               ModRM:r/m (r)                       NA                             NA
    RMI             ModRM:reg (r, w)               ModRM:r/m (r)                    imm8/16/32                        NA

Description
Performs a signed multiplication of two operands. This instruction has three forms, depending on the number of
operands.
.   One-operand form - This form is identical to that used by the MUL instruction. Here, the source operand (in
    a general-purpose register or memory location) is multiplied by the value in the AL, AX, EAX, or RAX register
    (depending on the operand size) and the product (twice the size of the input operand) is stored in the AX,
    DX:AX, EDX:EAX, or RDX:RAX registers, respectively.
.   Two-operand form - With this form the destination operand (the first operand) is multiplied by the source
    operand (second operand). The destination operand is a general-purpose register and the source operand is an
    immediate value, a general-purpose register, or a memory location. The intermediate product (twice the size of
    the input operand) is truncated and stored in the destination operand location.
.   Three-operand form - This form requires a destination operand (the first operand) and two source operands
    (the second and the third operands). Here, the first source operand (which can be a general-purpose register
    or a memory location) is multiplied by the second source operand (an immediate value). The intermediate
    product (twice the size of the first source operand) is truncated and stored in the destination operand (a
    general-purpose register).



When an immediate value is used as an operand, it is sign-extended to the length of the destination operand
format.
The CF and OF flags are set when the signed integer value of the intermediate product differs from the sign
extended operand-size-truncated product, otherwise the CF and OF flags are cleared.
The three forms of the IMUL instruction are similar in that the length of the product is calculated to twice the length
of the operands. With the one-operand form, the product is stored exactly in the destination. With the two- and
three- operand forms, however, the result is truncated to the length of the destination before it is stored in the
destination register. Because of this truncation, the CF or OF flag should be tested to ensure that no significant bits
are lost.
The two- and three-operand forms may also be used with unsigned operands because the lower half of the product
is the same regardless if the operands are signed or unsigned. The CF and OF flags, however, cannot be used to
determine if the upper half of the result is non-zero.
In 64-bit mode, the instruction's default operation size is 32 bits. Use of the REX.R prefix permits access to addi-
tional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits. Use of REX.W modifies the three
forms of the instruction as follows.
.   One-operand form -The source operand (in a 64-bit general-purpose register or memory location) is
    multiplied by the value in the RAX register and the product is stored in the RDX:RAX registers.
.   Two-operand form - The source operand is promoted to 64 bits if it is a register or a memory location. The
    destination operand is promoted to 64 bits.
.   Three-operand form - The first source operand (either a register or a memory location) and destination
    operand are promoted to 64 bits. If the source operand is an immediate, it is sign extended to 64 bits.

Operation
IF (NumberOfOperands = 1)
    THEN IF (OperandSize = 8)
        THEN
             TMP_XP <- AL * SRC (* Signed multiplication; TMP_XP is a signed integer at twice the width of the SRC *);
             AX <- TMP_XP[15:0];
             IF SignExtend(TMP_XP[7:0]) = TMP_XP
                  THEN CF <- 0; OF <- 0;
                  ELSE CF <- 1; OF <- 1; FI;
        ELSE IF OperandSize = 16
             THEN
                  TMP_XP <- AX * SRC (* Signed multiplication; TMP_XP is a signed integer at twice the width of the SRC *)
                  DX:AX <- TMP_XP[31:0];
                  IF SignExtend(TMP_XP[15:0]) = TMP_XP
                       THEN CF <- 0; OF <- 0;
                       ELSE CF <- 1; OF <- 1; FI;
             ELSE IF OperandSize = 32
                  THEN
                       TMP_XP <- EAX * SRC (* Signed multiplication; TMP_XP is a signed integer at twice the width of the SRC*)
                       EDX:EAX <- TMP_XP[63:0];
                       IF SignExtend(TMP_XP[31:0]) = TMP_XP
                            THEN CF <- 0; OF <- 0;
                            ELSE CF <- 1; OF <- 1; FI;
                  ELSE (* OperandSize = 64 *)
                       TMP_XP <- RAX * SRC (* Signed multiplication; TMP_XP is a signed integer at twice the width of the SRC *)
                       EDX:EAX <- TMP_XP[127:0];
                       IF SignExtend(TMP_XP[63:0]) = TMP_XP
                            THEN CF <- 0; OF <- 0;
                            ELSE CF <- 1; OF <- 1; FI;
                  FI;




          FI;
      ELSE IF (NumberOfOperands = 2)
          THEN
                TMP_XP <- DEST * SRC (* Signed multiplication; TMP_XP is a signed integer at twice the width of the SRC *)
                DEST <- TruncateToOperandSize(TMP_XP);
                IF SignExtend(DEST) != TMP_XP
                     THEN CF <- 1; OF <- 1;
                     ELSE CF <- 0; OF <- 0; FI;
          ELSE (* NumberOfOperands = 3 *)
                TMP_XP <- SRC1 * SRC2 (* Signed multiplication; TMP_XP is a signed integer at twice the width of the SRC1 *)
                DEST <- TruncateToOperandSize(TMP_XP);
                IF SignExtend(DEST) != TMP_XP
                     THEN CF <- 1; OF <- 1;
                     ELSE CF <- 0; OF <- 0; FI;
      FI;
FI;

Flags Affected
For the one operand form of the instruction, the CF and OF flags are set when significant bits are carried into the
upper half of the result and cleared when the result fits exactly in the lower half of the result. For the two- and
three-operand forms of the instruction, the CF and OF flags are set when the result must be truncated to fit in the
destination operand size and cleared when the result fits exactly in the destination operand size. The SF, ZF, AF, and
PF flags are undefined.

Protected Mode Exceptions
#GP(0)                    If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                          If the DS, ES, FS, or GS register is used to access memory and it contains a NULL NULL
                          segment selector.
#SS(0)                    If a memory operand effective address is outside the SS segment limit.
#PF(fault-code)           If a page fault occurs.
#AC(0)                    If alignment checking is enabled and an unaligned memory reference is made while the
                          current privilege level is 3.
#UD                       If the LOCK prefix is used.

Real-Address Mode Exceptions
#GP                       If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS                       If a memory operand effective address is outside the SS segment limit.
#UD                       If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
#GP(0)                    If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)                    If a memory operand effective address is outside the SS segment limit.
#PF(fault-code)           If a page fault occurs.
#AC(0)                    If alignment checking is enabled and an unaligned memory reference is made.
#UD                       If the LOCK prefix is used.

Compatibility Mode Exceptions
Same exceptions as in protected mode.





64-Bit Mode Exceptions
#SS(0)              If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)              If the memory address is in a non-canonical form.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                 If the LOCK prefix is used.






platform: x86_64
mnem: IN
description:
IN-Input from Port
 Opcode                   Instruction                  Op/   64-Bit    Compat/ Description
                                                       En    Mode      Leg Mode
 E4 ib                    IN AL, imm8                  I     Valid     Valid      Input byte from imm8 I/O port address into
                                                                                  AL.
 E5 ib                    IN AX, imm8                  I     Valid     Valid      Input word from imm8 I/O port address into
                                                                                  AX.
 E5 ib                    IN EAX, imm8                 I     Valid     Valid      Input dword from imm8 I/O port address into
                                                                                  EAX.
 EC                       IN AL,DX                     NP    Valid     Valid      Input byte from I/O port in DX into AL.
 ED                       IN AX,DX                     NP    Valid     Valid      Input word from I/O port in DX into AX.
 ED                       IN EAX,DX                    NP    Valid     Valid      Input doubleword from I/O port in DX into
                                                                                  EAX.



                                                 Instruction Operand Encoding
      Op/En           Operand 1                    Operand 2                   Operand 3                     Operand 4
         I              imm8                           NA                         NA                            NA
       NP                 NA                           NA                         NA                            NA

Description
Copies the value from the I/O port specified with the second operand (source operand) to the destination operand
(first operand). The source operand can be a byte-immediate or the DX register; the destination operand can be
register AL, AX, or EAX, depending on the size of the port being accessed (8, 16, or 32 bits, respectively). Using the
DX register as a source operand allows I/O port addresses from 0 to 65,535 to be accessed; using a byte imme-
diate allows I/O port addresses 0 to 255 to be accessed.
When accessing an 8-bit I/O port, the opcode determines the port size; when accessing a 16- and 32-bit I/O port,
the operand-size attribute determines the port size. At the machine code level, I/O instructions are shorter when
accessing 8-bit I/O ports. Here, the upper eight bits of the port address will be 0.
This instruction is only useful for accessing I/O ports located in the processor's I/O address space. See Chapter 18,
"Input/Output," in the Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 1, for more infor-
mation on accessing I/O ports in the I/O address space.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

Operation
IF ((PE = 1) and ((CPL > IOPL) or (VM = 1)))
     THEN (* Protected mode with CPL > IOPL or virtual-8086 mode *)
         IF (Any I/O Permission Bit for I/O port being accessed = 1)
              THEN (* I/O operation is not allowed *)
                   #GP(0);
              ELSE ( * I/O operation is allowed *)
                   DEST <- SRC; (* Read from selected I/O port *)
         FI;
     ELSE (Real Mode or Protected Mode with CPL <= IOPL *)
         DEST <- SRC; (* Read from selected I/O port *)
FI;

Flags Affected
None




Protected Mode Exceptions
#GP(0)              If the CPL is greater than (has less privilege) the I/O privilege level (IOPL) and any of the
                    corresponding I/O permission bits in TSS for the I/O port being accessed is 1.
#UD                 If the LOCK prefix is used.

Real-Address Mode Exceptions
#UD                 If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
#GP(0)              If any of the I/O permission bits in the TSS for the I/O port being accessed is 1.
#PF(fault-code)     If a page fault occurs.
#UD                 If the LOCK prefix is used.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#GP(0)              If the CPL is greater than (has less privilege) the I/O privilege level (IOPL) and any of the
                    corresponding I/O permission bits in TSS for the I/O port being accessed is 1.
#UD                 If the LOCK prefix is used.






platform: x86_64
mnem: INC
description:
INC-Increment by 1
 Opcode                      Instruction               Op/    64-Bit      Compat/ Description
                                                       En     Mode        Leg Mode
 FE /0                       INC r/m8                  M      Valid       Valid        Increment r/m byte by 1.
 REX + FE /0                 INC r/m8*                 M      Valid       N.E.         Increment r/m byte by 1.
 FF /0                       INC r/m16                 M      Valid       Valid        Increment r/m word by 1.
 FF /0                       INC r/m32                 M      Valid       Valid        Increment r/m doubleword by 1.
 REX.W + FF /0               INC r/m64                 M      Valid       N.E.         Increment r/m quadword by 1.
          **
 40+ rw                      INC r16                   O      N.E.        Valid        Increment word register by 1.
 40+ rd                      INC r32                   O      N.E.        Valid        Increment doubleword register by 1.
 NOTES:
 * In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
 ** 40H through 47H are REX prefixes in 64-bit mode.



                                                  Instruction Operand Encoding
   Op/En                Operand 1                    Operand 2                      Operand 3                      Operand 4
     M               ModRM:r/m (r, w)                   NA                             NA                              NA
     O               opcode + rd (r, w)                 NA                             NA                              NA

Description
Adds 1 to the destination operand, while preserving the state of the CF flag. The destination operand can be a
register or a memory location. This instruction allows a loop counter to be updated without disturbing the CF flag.
(Use a ADD instruction with an immediate operand of 1 to perform an increment operation that does updates the
CF flag.)
This instruction can be used with a LOCK prefix to allow the instruction to be executed atomically.
In 64-bit mode, INC r16 and INC r32 are not encodable (because opcodes 40H through 47H are REX prefixes).
Otherwise, the instruction's 64-bit mode default operation size is 32 bits. Use of the REX.R prefix permits access to
additional registers (R8-R15). Use of the REX.W prefix promotes operation to 64 bits.

Operation
DEST <- DEST + 1;

AFlags Affected
The CF flag is not affected. The OF, SF, ZF, AF, and PF flags are set according to the result.

Protected Mode Exceptions
#GP(0)                     If the destination operand is located in a non-writable segment.
                           If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                           If the DS, ES, FS, or GS register is used to access memory and it contains a NULLsegment
                           selector.
#SS(0)                     If a memory operand effective address is outside the SS segment limit.
#PF(fault-code)            If a page fault occurs.
#AC(0)                     If alignment checking is enabled and an unaligned memory reference is made while the
                           current privilege level is 3.
#UD                        If the LOCK prefix is used but the destination is not a memory operand.





Real-Address Mode Exceptions
#GP                 If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS                 If a memory operand effective address is outside the SS segment limit.
#UD                 If the LOCK prefix is used but the destination is not a memory operand.

Virtual-8086 Mode Exceptions
#GP(0)              If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)              If a memory operand effective address is outside the SS segment limit.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made.
#UD                 If the LOCK prefix is used but the destination is not a memory operand.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#SS(0)              If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)              If the memory address is in a non-canonical form.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3.
#UD                 If the LOCK prefix is used but the destination is not a memory operand.






platform: x86_64
mnem: INS
description:
INS/INSB/INSW/INSD-Input from Port to String
 Opcode                     Instruction                  Op/   64-Bit       Compat/ Description
                                                         En    Mode         Leg Mode
 6C                         INS m8, DX                   NP    Valid        Valid        Input byte from I/O port specified in DX into
                                                                                         memory location specified in ES:(E)DI or RDI.*
 6D                         INS m16, DX                  NP    Valid        Valid        Input word from I/O port specified in DX into
                                                                                         memory location specified in ES:(E)DI or RDI.1
 6D                         INS m32, DX                  NP    Valid        Valid        Input doubleword from I/O port specified in DX
                                                                                         into memory location specified in ES:(E)DI or
                                                                                         RDI.1
 6C                         INSB                         NP    Valid        Valid        Input byte from I/O port specified in DX into
                                                                                         memory location specified with ES:(E)DI or
                                                                                         RDI.1
 6D                         INSW                         NP    Valid        Valid        Input word from I/O port specified in DX into
                                                                                         memory location specified in ES:(E)DI or RDI.1
 6D                         INSD                         NP    Valid        Valid        Input doubleword from I/O port specified in DX
                                                                                         into memory location specified in ES:(E)DI or
                                                                                         RDI.1
 NOTES:
 * In 64-bit mode, only 64-bit (RDI) and 32-bit (EDI) address sizes are supported. In non-64-bit mode, only 32-bit (EDI) and 16-bit (DI)
   address sizes are supported.



                                                   Instruction Operand Encoding
      Op/En             Operand 1                     Operand 2                      Operand 3                      Operand 4
       NP                   NA                            NA                             NA                             NA

Description
Copies the data from the I/O port specified with the source operand (second operand) to the destination operand
(first operand). The source operand is an I/O port address (from 0 to 65,535) that is read from the DX register. The
destination operand is a memory location, the address of which is read from either the ES:DI, ES:EDI or the RDI
registers (depending on the address-size attribute of the instruction, 16, 32 or 64, respectively). (The ES segment
cannot be overridden with a segment override prefix.) The size of the I/O port being accessed (that is, the size of
the source and destination operands) is determined by the opcode for an 8-bit I/O port or by the operand-size attri-
bute of the instruction for a 16- or 32-bit I/O port.
At the assembly-code level, two forms of this instruction are allowed: the "explicit-operands" form and the "no-
operands" form. The explicit-operands form (specified with the INS mnemonic) allows the source and destination
operands to be specified explicitly. Here, the source operand must be "DX," and the destination operand should be
a symbol that indicates the size of the I/O port and the destination address. This explicit-operands form is provided
to allow documentation; however, note that the documentation provided by this form can be misleading. That is,
the destination operand symbol must specify the correct type (size) of the operand (byte, word, or doubleword),
but it does not have to specify the correct location. The location is always specified by the ES:(E)DI registers,
which must be loaded correctly before the INS instruction is executed.
The no-operands form provides "short forms" of the byte, word, and doubleword versions of the INS instructions.
Here also DX is assumed by the processor to be the source operand and ES:(E)DI is assumed to be the destination
operand. The size of the I/O port is specified with the choice of mnemonic: INSB (byte), INSW (word), or INSD
(doubleword).
After the byte, word, or doubleword is transfer from the I/O port to the memory location, the DI/EDI/RDI register
is incremented or decremented automatically according to the setting of the DF flag in the EFLAGS register. (If the
DF flag is 0, the (E)DI register is incremented; if the DF flag is 1, the (E)DI register is decremented.) The (E)DI
register is incremented or decremented by 1 for byte operations, by 2 for word operations, or by 4 for doubleword
operations.



The INS, INSB, INSW, and INSD instructions can be preceded by the REP prefix for block input of ECX bytes, words,
or doublewords. See "REP/REPE/REPZ /REPNE/REPNZ-Repeat String Operation Prefix" in Chapter 4 of the Intel
64 and IA-32 Architectures Software Developer's Manual, Volume 2B, for a description of the REP prefix.
These instructions are only useful for accessing I/O ports located in the processor's I/O address space. See Chapter
18, "Input/Output," in the Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 1, for more
information on accessing I/O ports in the I/O address space.
In 64-bit mode, default address size is 64 bits, 32 bit address size is supported using the prefix 67H. The address
of the memory destination is specified by RDI or EDI. 16-bit address size is not supported in 64-bit mode. The
operand size is not promoted.
These instructions may read from the I/O port without writing to the memory location if an exception or VM exit
occurs due to the write (e.g. #PF). If this would be problematic, for example because the I/O port read has side-
effects, software should ensure the write to the memory location does not cause an exception or VM exit.

Operation
IF ((PE = 1) and ((CPL > IOPL) or (VM = 1)))
     THEN (* Protected mode with CPL > IOPL or virtual-8086 mode *)
         IF (Any I/O Permission Bit for I/O port being accessed = 1)
              THEN (* I/O operation is not allowed *)
                   #GP(0);
              ELSE (* I/O operation is allowed *)
                   DEST <- SRC; (* Read from I/O port *)
         FI;
     ELSE (Real Mode or Protected Mode with CPL IOPL *)
         DEST <- SRC; (* Read from I/O port *)
FI;

Non-64-bit Mode:

IF (Byte transfer)
    THEN IF DF = 0
         THEN (E)DI <- (E)DI + 1;
         ELSE (E)DI <- (E)DI - 1; FI;
    ELSE IF (Word transfer)
         THEN IF DF = 0
             THEN (E)DI <- (E)DI + 2;
             ELSE (E)DI <- (E)DI - 2; FI;
         ELSE (* Doubleword transfer *)
             THEN IF DF = 0
                   THEN (E)DI <- (E)DI + 4;
                   ELSE (E)DI <- (E)DI - 4; FI;
         FI;
FI;

FI64-bit Mode:

IF (Byte transfer)
    THEN IF DF = 0
         THEN (E|R)DI <- (E|R)DI + 1;
         ELSE (E|R)DI <- (E|R)DI - 1; FI;
    ELSE IF (Word transfer)
         THEN IF DF = 0
             THEN (E)DI <- (E)DI + 2;
             ELSE (E)DI <- (E)DI - 2; FI;
         ELSE (* Doubleword transfer *)




              THEN IF DF = 0
                 THEN (E|R)DI <- (E|R)DI + 4;
                 ELSE (E|R)DI <- (E|R)DI - 4; FI;
        FI;
FI;

Flags Affected
None

Protected Mode Exceptions
#GP(0)                   If the CPL is greater than (has less privilege) the I/O privilege level (IOPL) and any of the
                         corresponding I/O permission bits in TSS for the I/O port being accessed is 1.
                         If the destination is located in a non-writable segment.
                         If an illegal memory operand effective address in the ES segments is given.
#PF(fault-code)          If a page fault occurs.
#AC(0)                   If alignment checking is enabled and an unaligned memory reference is made while the
                         current privilege level is 3.
#UD                      If the LOCK prefix is used.

Real-Address Mode Exceptions
#GP                      If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS                      If a memory operand effective address is outside the SS segment limit.
#UD                      If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
#GP(0)                   If any of the I/O permission bits in the TSS for the I/O port being accessed is 1.
#PF(fault-code)          If a page fault occurs.
#AC(0)                   If alignment checking is enabled and an unaligned memory reference is made.
#UD                      If the LOCK prefix is used.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#SS(0)                   If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)                   If the CPL is greater than (has less privilege) the I/O privilege level (IOPL) and any of the
                         corresponding I/O permission bits in TSS for the I/O port being accessed is 1.
                         If the memory address is in a non-canonical form.
#PF(fault-code)          If a page fault occurs.
#AC(0)                   If alignment checking is enabled and an unaligned memory reference is made while the
                         current privilege level is 3.
#UD                      If the LOCK prefix is used.






platform: x86_64
mnem: INSERTPS
description:
INSERTPS-Insert Scalar Single-Precision Floating-Point Value
 Opcode/                                 Op /    64/32       CPUID     Description
 Instruction                             En      bit Mode    Feature
                                                 Support     Flag
 66 0F 3A 21 /r ib                       RMI     V/V         SSE4_1    Insert a single-precision floating-point value selected
 INSERTPS xmm1, xmm2/m32, imm8                                         by imm8 from xmm2/m32 into xmm1 at the specified
                                                                       destination element specified by imm8 and zero out
                                                                       destination elements in xmm1 as indicated in imm8.
 VEX.NDS.128.66.0F3A.WIG 21 /r ib        RVMI    V/V         AVX       Insert a single-precision floating-point value selected
 VINSERTPS xmm1, xmm2,                                                 by imm8 from xmm3/m32 and merge with values in
 xmm3/m32, imm8                                                        xmm2 at the specified destination element specified
                                                                       by imm8 and write out the result and zero out
                                                                       destination elements in xmm1 as indicated in imm8.
 EVEX.NDS.128.66.0F3A.W0 21 /r ib        T1S     V/V         AVX512F   Insert a single-precision floating-point value selected
 VINSERTPS xmm1, xmm2,                                                 by imm8 from xmm3/m32 and merge with values in
 xmm3/m32, imm8                                                        xmm2 at the specified destination element specified
                                                                       by imm8 and write out the result and zero out
                                                                       destination elements in xmm1 as indicated in imm8.



                                                Instruction Operand Encoding
       Op/En                Operand 1                  Operand 2               Operand 3                      Operand 4
        RMI              ModRM:reg (r, w)           ModRM:r/m (r)                Imm8                             NA
       RVMI              ModRM:reg (w)                 VEX.vvvv              ModRM:r/m (r)                       Imm8
        T1S              ModRM:reg (w)                 EVEX.vvvv             ModRM:r/m (r)                       Imm8

Description
(register source form)
Select a single-precision floating-point element from second source as indicated by Count_S bits of the immediate
operand and destination operand it into the first source at the location indicated by the Count_D bits of the imme-
diate operand. Store in the destination and zero out destination elements based on the ZMask bits of the immediate
operand.
(memory source form)
Load a floating-point element from a 32-bit memory location and destination operand it into the first source at the
location indicated by the Count_D bits of the immediate operand. Store in the destination and zero out destination
elements based on the ZMask bits of the immediate operand.
128-bit Legacy SSE version: The first source register is an XMM register. The second source operand is either an
XMM register or a 32-bit memory location. The destination is not distinct from the first source XMM register and the
upper bits (MAX_VL-1:128) of the corresponding register destination are unmodified.
VEX.128 and EVEX encoded version: The destination and first source register is an XMM register. The second
source operand is either an XMM register or a 32-bit memory location. The upper bits (MAX_VL-1:128) of the corre-
sponding register destination are zeroed.
If VINSERTPS is encoded with VEX.L= 1, an attempt to execute the instruction encoded with VEX.L= 1 will cause
an #UD exception.





Operation
VINSERTPS (VEX.128 and EVEX encoded version)
IF (SRC = REG) THEN COUNT_S <- imm8[7:6]
    ELSE COUNT_S <- 0
COUNT_D <- imm8[5:4]
ZMASK <- imm8[3:0]
CASE (COUNT_S) OF
    0: TMP <- SRC2[31:0]
    1: TMP <- SRC2[63:32]
    2: TMP <- SRC2[95:64]
    3: TMP <- SRC2[127:96]
ESAC;
CASE (COUNT_D) OF
    0: TMP2[31:0] <- TMP
         TMP2[127:32] <- SRC1[127:32]
    1: TMP2[63:32] <- TMP
         TMP2[31:0] <- SRC1[31:0]
         TMP2[127:64] <- SRC1[127:64]
    2: TMP2[95:64] <- TMP
         TMP2[63:0] <- SRC1[63:0]
         TMP2[127:96] <- SRC1[127:96]
    3: TMP2[127:96] <- TMP
         TMP2[95:0] <- SRC1[95:0]
ESAC;

IF (ZMASK[0] = 1) THEN DEST[31:0] <- 00000000H
    ELSE DEST[31:0] <- TMP2[31:0]
IF (ZMASK[1] = 1) THEN DEST[63:32] <- 00000000H
    ELSE DEST[63:32] <- TMP2[63:32]
IF (ZMASK[2] = 1) THEN DEST[95:64] <- 00000000H
    ELSE DEST[95:64] <- TMP2[95:64]
IF (ZMASK[3] = 1) THEN DEST[127:96] <- 00000000H
    ELSE DEST[127:96] <- TMP2[127:96]
DEST[MAX_VL-1:128] <- 0

INSERTPS (128-bit Legacy SSE version)
IF (SRC = REG) THEN COUNT_S <-imm8[7:6]
    ELSE COUNT_S <-0
COUNT_D <-imm8[5:4]
ZMASK <-imm8[3:0]
CASE (COUNT_S) OF
    0: TMP <-SRC[31:0]
    1: TMP <-SRC[63:32]
    2: TMP <-SRC[95:64]
    3: TMP <-SRC[127:96]
ESAC;

CASE (COUNT_D) OF
   0: TMP2[31:0] <-TMP
        TMP2[127:32] <-DEST[127:32]
   1: TMP2[63:32] <-TMP
        TMP2[31:0] <-DEST[31:0]
        TMP2[127:64] <-DEST[127:64]
   2: TMP2[95:64] <-TMP



        TMP2[63:0] <-DEST[63:0]
        TMP2[127:96] <-DEST[127:96]
   3: TMP2[127:96] <-TMP
        TMP2[95:0] <-DEST[95:0]
ESAC;

IF (ZMASK[0] = 1) THEN DEST[31:0] <-00000000H
    ELSE DEST[31:0] <-TMP2[31:0]
IF (ZMASK[1] = 1) THEN DEST[63:32] <-00000000H
    ELSE DEST[63:32] <-TMP2[63:32]
IF (ZMASK[2] = 1) THEN DEST[95:64] <-00000000H
    ELSE DEST[95:64] <-TMP2[95:64]
IF (ZMASK[3] = 1) THEN DEST[127:96] <-00000000H
    ELSE DEST[127:96] <-TMP2[127:96]
DEST[MAX_VL-1:128] (Unmodified)

Intel C/C++ Compiler Intrinsic Equivalent
VINSERTPS __m128 _mm_insert_ps(__m128 dst, __m128 src, const int nidx);
INSETRTPS __m128 _mm_insert_ps(__m128 dst, __m128 src, const int nidx);

SIMD Floating-Point Exceptions
None

Other Exceptions
Non-EVEX-encoded instruction, see Exceptions Type 5; additionally
#UD                   If VEX.L = 0.
EVEX-encoded instruction, see Exceptions Type E9NF.






platform: x86_64
mnem: INT n
description:
INT n/INTO/INT 3-Call to Interrupt Procedure
 Opcode                      Instruction            Op/     64-Bit    Compat/ Description
                                                    En      Mode      Leg Mode
 CC                          INT 3                  NP      Valid     Valid       Interrupt 3-trap to debugger.
 CD ib                       INT imm8               I       Valid     Valid       Interrupt vector specified by immediate byte.
 CE                          INTO                   NP      Invalid   Valid       Interrupt 4-if overflow flag is 1.



                                               Instruction Operand Encoding
    Op/En              Operand 1                Operand 2                     Operand 3                     Operand 4
      NP                   NA                      NA                            NA                             NA
      I                   imm8                     NA                            NA                             NA

Description
The INT n instruction generates a call to the interrupt or exception handler specified with the destination operand
(see the section titled "Interrupts and Exceptions" in Chapter 6 of the Intel 64 and IA-32 Architectures Software
Developer's Manual, Volume 1). The destination operand specifies a vector from 0 to 255, encoded as an 8-bit
unsigned intermediate value. Each vector provides an index to a gate descriptor in the IDT. The first 32 vectors are
reserved by Intel for system use. Some of these vectors are used for internally generated exceptions.
The INT n instruction is the general mnemonic for executing a software-generated call to an interrupt handler. The
INTO instruction is a special mnemonic for calling overflow exception (#OF), exception 4. The overflow interrupt
checks the OF flag in the EFLAGS register and calls the overflow interrupt handler if the OF flag is set to 1. (The
INTO instruction cannot be used in 64-bit mode.)
The INT 3 instruction generates a special one byte opcode (CC) that is intended for calling the debug exception
handler. (This one byte form is valuable because it can be used to replace the first byte of any instruction with a
breakpoint, including other one byte instructions, without over-writing other code). To further support its function
as a debug breakpoint, the interrupt generated with the CC opcode also differs from the regular software interrupts
as follows:
.     Interrupt redirection does not happen when in VME mode; the interrupt is handled by a protected-mode
      handler.
.     The virtual-8086 mode IOPL checks do not occur. The interrupt is taken without faulting at any IOPL level.
Note that the "normal" 2-byte opcode for INT 3 (CD03) does not have these special features. Intel and Microsoft
assemblers will not generate the CD03 opcode from any mnemonic, but this opcode can be created by direct
numeric code definition or by self-modifying code.
The action of the INT n instruction (including the INTO and INT 3 instructions) is similar to that of a far call made
with the CALL instruction. The primary difference is that with the INT n instruction, the EFLAGS register is pushed
onto the stack before the return address. (The return address is a far address consisting of the current values of
the CS and EIP registers.) Returns from interrupt procedures are handled with the IRET instruction, which pops the
EFLAGS information and return address from the stack.
The vector specifies an interrupt descriptor in the interrupt descriptor table (IDT); that is, it provides index into the
IDT. The selected interrupt descriptor in turn contains a pointer to an interrupt or exception handler procedure.
In protected mode, the IDT contains an array of 8-byte descriptors, each of which is an interrupt gate, trap gate,
or task gate. In real-address mode, the IDT is an array of 4-byte far pointers (2-byte code segment selector and
a 2-byte instruction pointer), each of which point directly to a procedure in the selected segment. (Note that in
real-address mode, the IDT is called the interrupt vector table, and its pointers are called interrupt vectors.)
The following decision table indicates which action in the lower portion of the table is taken given the conditions in
the upper portion of the table. Each Y in the lower section of the decision table represents a procedure defined in
the "Operation" section for this instruction (except #GP).





                                                Table 3-51. Decision Table
PE                          0     1         1          1            1           1               1               1
VM                          -     -         -          -            -           0               1               1
IOPL                        -     -         -          -            -           -               <3              =3
DPL/CPL                     -     DPL<      -          DPL>         DPL=        DPL<            -               -
RELATIONSHIP                      CPL                  CPL          CPL or C    CPL & NC
INTERRUPT TYPE              -     S/W       -          -            -           -               -               -
GATE TYPE                   -     -         Task       Trap or      Trap or     Trap or         Trap or         Trap or
                                                       Interrupt    Interrupt   Interrupt       Interrupt       Interrupt
REAL-ADDRESS-MODE           Y
PROTECTED-MODE                    Y         Y          Y            Y           Y               Y               Y
TRAP-OR-INTERRUPT-                                     Y            Y           Y               Y               Y
GATE
INTER-PRIVILEGE-LEVEL-                                                          Y
INTERRUPT
INTRA-PRIVILEGE-LEVEL-                                              Y
INTERRUPT
INTERRUPT-FROM-                                                                                                 Y
VIRTUAL-8086-MODE
TASK-GATE                                   Y
#GP                               Y                    Y                                        Y
NOTES:
   -   Don't Care.
   Y   Yes, action taken.
Blank Action not taken.

When the processor is executing in virtual-8086 mode, the IOPL determines the action of the INT n instruction. If
the IOPL is less than 3, the processor generates a #GP(selector) exception; if the IOPL is 3, the processor executes
a protected mode interrupt to privilege level 0. The interrupt gate's DPL must be set to 3 and the target CPL of the
interrupt handler procedure must be 0 to execute the protected mode interrupt to privilege level 0.
The interrupt descriptor table register (IDTR) specifies the base linear address and limit of the IDT. The initial base
address value of the IDTR after the processor is powered up or reset is 0.

Operation
The following operational description applies not only to the INT n and INTO instructions, but also to external inter-
rupts, nonmaskable interrupts (NMIs), and exceptions. Some of these events push onto the stack an error code.
The operational description specifies numerous checks whose failure may result in delivery of a nested exception.
In these cases, the original event is not delivered.
The operational description specifies the error code delivered by any nested exception. In some cases, the error
code is specified with a pseudofunction error_code(num,idt,ext), where idt and ext are bit values. The pseudofunc-
tion produces an error code as follows: (1) if idt is 0, the error code is (num & FCH) | ext; (2) if idt is 1, the error
code is (num << 3) | 2 | ext.
In many cases, the pseudofunction error_code is invoked with a pseudovariable EXT. The value of EXT depends on
the nature of the event whose delivery encountered a nested exception: if that event is a software interrupt, EXT is
0; otherwise, EXT is 1.





IF PE = 0
    THEN
          GOTO REAL-ADDRESS-MODE;
    ELSE (* PE = 1 *)
          IF (VM = 1 and IOPL < 3 AND INT n)
                THEN
                      #GP(0); (* Bit 0 of error code is 0 because INT n *)
                ELSE (* Protected mode, IA-32e mode, or virtual-8086 mode interrupt *)
                     IF (IA32_EFER.LMA = 0)
                           THEN (* Protected mode, or virtual-8086 mode interrupt *)
                               GOTO PROTECTED-MODE;
                     ELSE (* IA-32e mode interrupt *)
                           GOTO IA-32e-MODE;
                     FI;
          FI;
FI;
REAL-ADDRESS-MODE:
    IF ((vector_number << 2) + 3) is not within IDT limit
          THEN #GP; FI;
    IF stack not large enough for a 6-byte return information
          THEN #SS; FI;
    Push (EFLAGS[15:0]);
    IF <- 0; (* Clear interrupt flag *)
    TF <- 0; (* Clear trap flag *)
    AC <- 0; (* Clear AC flag *)
    Push(CS);
    Push(IP);
    (* No error codes are pushed in real-address mode*)
    CS <- IDT(Descriptor (vector_number << 2), selector));
    EIP <- IDT(Descriptor (vector_number << 2), offset)); (* 16 bit offset AND 0000FFFFH *)
END;
PROTECTED-MODE:
    IF ((vector_number << 3) + 7) is not within IDT limits
    or selected IDT descriptor is not an interrupt-, trap-, or task-gate type
          THEN #GP(error_code(vector_number,1,EXT)); FI;
          (* idt operand to error_code set because vector is used *)
    IF software interrupt (* Generated by INT n, INT3, or INTO *)
          THEN
                IF gate DPL < CPL (* PE = 1, DPL < CPL, software interrupt *)
                     THEN #GP(error_code(vector_number,1,0)); FI;
                     (* idt operand to error_code set because vector is used *)
                     (* ext operand to error_code is 0 because INT n, INT3, or INTO*)
    FI;
    IF gate not present
          THEN #NP(error_code(vector_number,1,EXT)); FI;
          (* idt operand to error_code set because vector is used *)
    IF task gate (* Specified in the selected interrupt table descriptor *)
          THEN GOTO TASK-GATE;
          ELSE GOTO TRAP-OR-INTERRUPT-GATE; (* PE = 1, trap/interrupt gate *)
    FI;
END;
IA-32e-MODE:
    IF INTO and CS.L = 1 (64-bit mode)
          THEN #UD;



   FI;
   IF ((vector_number << 4) + 15) is not in IDT limits
   or selected IDT descriptor is not an interrupt-, or trap-gate type
         THEN #GP(error_code(vector_number,1,EXT));
         (* idt operand to error_code set because vector is used *)
   FI;
   IF software interrupt (* Generated by INT n, INT 3, or INTO *)
         THEN
               IF gate DPL < CPL (* PE = 1, DPL < CPL, software interrupt *)
                     THEN #GP(error_code(vector_number,1,0));
                     (* idt operand to error_code set because vector is used *)
                     (* ext operand to error_code is 0 because INT n, INT3, or INTO*)
               FI;
   FI;
   IF gate not present
         THEN #NP(error_code(vector_number,1,EXT));
         (* idt operand to error_code set because vector is used *)
   FI;
   GOTO TRAP-OR-INTERRUPT-GATE; (* Trap/interrupt gate *)
END;
TASK-GATE: (* PE = 1, task gate *)
   Read TSS selector in task gate (IDT descriptor);
         IF local/global bit is set to local or index not within GDT limits
               THEN #GP(error_code(TSS selector,0,EXT)); FI;
               (* idt operand to error_code is 0 because selector is used *)
         Access TSS descriptor in GDT;
         IF TSS descriptor specifies that the TSS is busy (low-order 5 bits set to 00001)
               THEN #GP(TSS selector,0,EXT)); FI;
               (* idt operand to error_code is 0 because selector is used *)
         IF TSS not present
               THEN #NP(TSS selector,0,EXT)); FI;
               (* idt operand to error_code is 0 because selector is used *)
   SWITCH-TASKS (with nesting) to TSS;
   IF interrupt caused by fault with error code
         THEN
               IF stack limit does not allow push of error code
                     THEN #SS(EXT); FI;
               Push(error code);
   FI;
   IF EIP not within code segment limit
         THEN #GP(EXT); FI;
END;
TRAP-OR-INTERRUPT-GATE:
   Read new code-segment selector for trap or interrupt gate (IDT descriptor);
   IF new code-segment selector is NULL
         THEN #GP(EXT); FI; (* Error code contains NULL selector *)
   IF new code-segment selector is not within its descriptor table limits
         THEN #GP(error_code(new code-segment selector,0,EXT)); FI;
         (* idt operand to error_code is 0 because selector is used *)
   Read descriptor referenced by new code-segment selector;
   IF descriptor does not indicate a code segment or new code-segment DPL > CPL
         THEN #GP(error_code(new code-segment selector,0,EXT)); FI;
         (* idt operand to error_code is 0 because selector is used *)
   IF new code-segment descriptor is not present,



         THEN #NP(error_code(new code-segment selector,0,EXT)); FI;
         (* idt operand to error_code is 0 because selector is used *)
   IF new code segment is non-conforming with DPL < CPL
         THEN
               IF VM = 0
                    THEN
                          GOTO INTER-PRIVILEGE-LEVEL-INTERRUPT;
                          (* PE = 1, VM = 0, interrupt or trap gate, nonconforming code segment,
                          DPL < CPL *)
                    ELSE (* VM = 1 *)
                          IF new code-segment DPL != 0
                                THEN #GP(error_code(new code-segment selector,0,EXT));
                                (* idt operand to error_code is 0 because selector is used *)
                          GOTO INTERRUPT-FROM-VIRTUAL-8086-MODE; FI;
                          (* PE = 1, interrupt or trap gate, DPL < CPL, VM = 1 *)
               FI;
         ELSE (* PE = 1, interrupt or trap gate, DPL >= CPL *)
               IF VM = 1
                    THEN #GP(error_code(new code-segment selector,0,EXT));
                    (* idt operand to error_code is 0 because selector is used *)
               IF new code segment is conforming or new code-segment DPL = CPL
                    THEN
                          GOTO INTRA-PRIVILEGE-LEVEL-INTERRUPT;
                    ELSE (* PE = 1, interrupt or trap gate, nonconforming code segment, DPL > CPL *)
                          #GP(error_code(new code-segment selector,0,EXT));
                          (* idt operand to error_code is 0 because selector is used *)
               FI;
   FI;
END;
INTER-PRIVILEGE-LEVEL-INTERRUPT:
   (* PE = 1, interrupt or trap gate, non-conforming code segment, DPL < CPL *)
   IF (IA32_EFER.LMA = 0) (* Not IA-32e mode *)
         THEN
         (* Identify stack-segment selector for new privilege level in current TSS *)
               IF current TSS is 32-bit
                    THEN
                          TSSstackAddress <- (new code-segment DPL << 3) + 4;
                          IF (TSSstackAddress + 5) > current TSS limit
                                THEN #TS(error_code(current TSS selector,0,EXT)); FI;
                                (* idt operand to error_code is 0 because selector is used *)
                          NewSS <- 2 bytes loaded from (TSS base + TSSstackAddress + 4);
                          NewESP <- 4 bytes loaded from (TSS base + TSSstackAddress);
                    ELSE        (* current TSS is 16-bit *)
                          TSSstackAddress <- (new code-segment DPL << 2) + 2
                          IF (TSSstackAddress + 3) > current TSS limit
                                THEN #TS(error_code(current TSS selector,0,EXT)); FI;
                                (* idt operand to error_code is 0 because selector is used *)
                          NewSS <- 2 bytes loaded from (TSS base + TSSstackAddress + 2);
                          NewESP <- 2 bytes loaded from (TSS base + TSSstackAddress);
               FI;
               IF NewSS is NULL
                    THEN #TS(EXT); FI;
               IF NewSS index is not within its descriptor-table limits
               or NewSS RPL != new code-segment DPL



                  THEN #TS(error_code(NewSS,0,EXT)); FI;
                  (* idt operand to error_code is 0 because selector is used *)
            Read new stack-segment descriptor for NewSS in GDT or LDT;
            IF new stack-segment DPL != new code-segment DPL
            or new stack-segment Type does not indicate writable data segment
                  THEN #TS(error_code(NewSS,0,EXT)); FI;
                  (* idt operand to error_code is 0 because selector is used *)
            IF NewSS is not present
                  THEN #SS(error_code(NewSS,0,EXT)); FI;
                  (* idt operand to error_code is 0 because selector is used *)
        ELSE (* IA-32e mode *)
            IF IDT-gate IST = 0
                  THEN TSSstackAddress <- (new code-segment DPL << 3) + 4;
                  ELSE TSSstackAddress <- (IDT gate IST << 3) + 28;
            FI;
            IF (TSSstackAddress + 7) > current TSS limit
                  THEN #TS(error_code(current TSS selector,0,EXT); FI;
                  (* idt operand to error_code is 0 because selector is used *)
            NewRSP <- 8 bytes loaded from (current TSS base + TSSstackAddress);
            NewSS <- new code-segment DPL; (* NULL selector with RPL = new CPL *)
   FI;
   IF IDT gate is 32-bit
             THEN
                   IF new stack does not have room for 24 bytes (error code pushed)
                   or 20 bytes (no error code pushed)
                        THEN #SS(error_code(NewSS,0,EXT)); FI;
                        (* idt operand to error_code is 0 because selector is used *)
             FI
         ELSE
             IF IDT gate is 16-bit
                   THEN
                        IF new stack does not have room for 12 bytes (error code pushed)
                        or 10 bytes (no error code pushed);
                              THEN #SS(error_code(NewSS,0,EXT)); FI;
                              (* idt operand to error_code is 0 because selector is used *)
             ELSE (* 64-bit IDT gate*)
                   IF StackAddress is non-canonical
                        THEN #SS(EXT); FI; (* Error code contains NULL selector *)
         FI;
   FI;
   IF (IA32_EFER.LMA = 0) (* Not IA-32e mode *)
         THEN
             IF instruction pointer from IDT gate is not within new code-segment limits
                   THEN #GP(EXT); FI; (* Error code contains NULL selector *)
             ESP <- NewESP;
             SS <- NewSS; (* Segment descriptor information also loaded *)
         ELSE (* IA-32e mode *)
             IF instruction pointer from IDT gate contains a non-canonical address
                   THEN #GP(EXT); FI; (* Error code contains NULL selector *)
             RSP <- NewRSP & FFFFFFFFFFFFFFF0H;
             SS <- NewSS;
   FI;
   IF IDT gate is 32-bit
         THEN



             CS:EIP <- Gate(CS:EIP); (* Segment descriptor information also loaded *)
         ELSE
             IF IDT gate 16-bit
                  THEN
                       CS:IP <- Gate(CS:IP);
                       (* Segment descriptor information also loaded *)
                  ELSE (* 64-bit IDT gate *)
                       CS:RIP <- Gate(CS:RIP);
                       (* Segment descriptor information also loaded *)
             FI;
   FI;
   IF IDT gate is 32-bit
             THEN
                   Push(far pointer to old stack);
                   (* Old SS and ESP, 3 words padded to 4 *)
                   Push(EFLAGS);
                   Push(far pointer to return instruction);
                   (* Old CS and EIP, 3 words padded to 4 *)
                   Push(ErrorCode); (* If needed, 4 bytes *)
             ELSE
                   IF IDT gate 16-bit
                         THEN
                             Push(far pointer to old stack);
                             (* Old SS and SP, 2 words *)
                             Push(EFLAGS(15-0]);
                             Push(far pointer to return instruction);
                             (* Old CS and IP, 2 words *)
                             Push(ErrorCode); (* If needed, 2 bytes *)
                         ELSE (* 64-bit IDT gate *)
                             Push(far pointer to old stack);
                             (* Old SS and SP, each an 8-byte push *)
                             Push(RFLAGS); (* 8-byte push *)
                             Push(far pointer to return instruction);
                             (* Old CS and RIP, each an 8-byte push *)
                             Push(ErrorCode); (* If needed, 8-bytes *)
             FI;
   FI;
   CPL <- new code-segment DPL;
   CS(RPL) <- CPL;
   IF IDT gate is interrupt gate
         THEN IF <- 0 (* Interrupt flag set to 0, interrupts disabled *); FI;
   TF <- 0;
   VM <- 0;
   RF <- 0;
   NT <- 0;
END;
INTERRUPT-FROM-VIRTUAL-8086-MODE:
   (* Identify stack-segment selector for privilege level 0 in current TSS *)
   IF current TSS is 32-bit
         THEN
             IF TSS limit < 9
                   THEN #TS(error_code(current TSS selector,0,EXT)); FI;
                   (* idt operand to error_code is 0 because selector is used *)
             NewSS <- 2 bytes loaded from (current TSS base + 8);



            NewESP <- 4 bytes loaded from (current TSS base + 4);
        ELSE (* current TSS is 16-bit *)
            IF TSS limit < 5
                 THEN #TS(error_code(current TSS selector,0,EXT)); FI;
                 (* idt operand to error_code is 0 because selector is used *)
            NewSS <- 2 bytes loaded from (current TSS base + 4);
            NewESP <- 2 bytes loaded from (current TSS base + 2);
   FI;
   IF NewSS is NULL
         THEN #TS(EXT); FI; (* Error code contains NULL selector *)
   IF NewSS index is not within its descriptor table limits
   or NewSS RPL != 0
         THEN #TS(error_code(NewSS,0,EXT)); FI;
         (* idt operand to error_code is 0 because selector is used *)
   Read new stack-segment descriptor for NewSS in GDT or LDT;
   IF new stack-segment DPL != 0 or stack segment does not indicate writable data segment
         THEN #TS(error_code(NewSS,0,EXT)); FI;
         (* idt operand to error_code is 0 because selector is used *)
   IF new stack segment not present
         THEN #SS(error_code(NewSS,0,EXT)); FI;
         (* idt operand to error_code is 0 because selector is used *)
   IF IDT gate is 32-bit
         THEN
               IF new stack does not have room for 40 bytes (error code pushed)
               or 36 bytes (no error code pushed)
                    THEN #SS(error_code(NewSS,0,EXT)); FI;
                    (* idt operand to error_code is 0 because selector is used *)
         ELSE (* IDT gate is 16-bit)
               IF new stack does not have room for 20 bytes (error code pushed)
               or 18 bytes (no error code pushed)
                    THEN #SS(error_code(NewSS,0,EXT)); FI;
                    (* idt operand to error_code is 0 because selector is used *)
   FI;
   IF instruction pointer from IDT gate is not within new code-segment limits
         THEN #GP(EXT); FI; (* Error code contains NULL selector *)
   tempEFLAGS <- EFLAGS;
   VM <- 0;
   TF <- 0;
   RF <- 0;
   NT <- 0;
   IF service through interrupt gate
         THEN IF = 0; FI;
   TempSS <- SS;
   TempESP <- ESP;
   SS <- NewSS;
   ESP <- NewESP;
   (* Following pushes are 16 bits for 16-bit IDT gates and 32 bits for 32-bit IDT gates;
   Segment selector pushes in 32-bit mode are padded to two words *)
   Push(GS);
   Push(FS);
   Push(DS);
   Push(ES);
   Push(TempSS);
   Push(TempESP);



   Push(TempEFlags);
   Push(CS);
   Push(EIP);
   GS <- 0; (* Segment registers made NULL, invalid for use in protected mode *)
   FS <- 0;
   DS <- 0;
   ES <- 0;
   CS:IP <- Gate(CS); (* Segment descriptor information also loaded *)
   IF OperandSize = 32
         THEN
              EIP <- Gate(instruction pointer);
         ELSE (* OperandSize is 16 *)
              EIP <- Gate(instruction pointer) AND 0000FFFFH;
   FI;
   (* Start execution of new routine in Protected Mode *)
END;
INTRA-PRIVILEGE-LEVEL-INTERRUPT:
   (* PE = 1, DPL = CPL or conforming segment *)
   IF IA32_EFER.LMA = 1 (* IA-32e mode *)
         IF IDT-descriptor IST != 0
              THEN
                    TSSstackAddress <- (IDT-descriptor IST << 3) + 28;
                    IF (TSSstackAddress + 7) > TSS limit
                         THEN #TS(error_code(current TSS selector,0,EXT)); FI;
                         (* idt operand to error_code is 0 because selector is used *)
                    NewRSP <- 8 bytes loaded from (current TSS base + TSSstackAddress);
   FI;
   IF 32-bit gate (* implies IA32_EFER.LMA = 0 *)
         THEN
              IF current stack does not have room for 16 bytes (error code pushed)
              or 12 bytes (no error code pushed)
                    THEN #SS(EXT); FI; (* Error code contains NULL selector *)
         ELSE IF 16-bit gate (* implies IA32_EFER.LMA = 0 *)
              IF current stack does not have room for 8 bytes (error code pushed)
              or 6 bytes (no error code pushed)
                    THEN #SS(EXT); FI; (* Error code contains NULL selector *)
         ELSE (* IA32_EFER.LMA = 1, 64-bit gate*)
                    IF NewRSP contains a non-canonical address
                         THEN #SS(EXT); (* Error code contains NULL selector *)
         FI;
   FI;
   IF (IA32_EFER.LMA = 0) (* Not IA-32e mode *)
         THEN
              IF instruction pointer from IDT gate is not within new code-segment limit
                    THEN #GP(EXT); FI; (* Error code contains NULL selector *)
         ELSE
              IF instruction pointer from IDT gate contains a non-canonical address
                    THEN #GP(EXT); FI; (* Error code contains NULL selector *)
              RSP <- NewRSP & FFFFFFFFFFFFFFF0H;
   FI;
   IF IDT gate is 32-bit (* implies IA32_EFER.LMA = 0 *)
         THEN
              Push (EFLAGS);
              Push (far pointer to return instruction); (* 3 words padded to 4 *)



            CS:EIP <- Gate(CS:EIP); (* Segment descriptor information also loaded *)
            Push (ErrorCode); (* If any *)
        ELSE
            IF IDT gate is 16-bit (* implies IA32_EFER.LMA = 0 *)
                 THEN
                      Push (FLAGS);
                      Push (far pointer to return location); (* 2 words *)
                      CS:IP <- Gate(CS:IP);
                      (* Segment descriptor information also loaded *)
                      Push (ErrorCode); (* If any *)
                 ELSE (* IA32_EFER.LMA = 1, 64-bit gate*)
                      Push(far pointer to old stack);
                      (* Old SS and SP, each an 8-byte push *)
                      Push(RFLAGS); (* 8-byte push *)
                      Push(far pointer to return instruction);
                      (* Old CS and RIP, each an 8-byte push *)
                      Push(ErrorCode); (* If needed, 8 bytes *)
                      CS:RIP <- GATE(CS:RIP);
                      (* Segment descriptor information also loaded *)
            FI;
   FI;
   CS(RPL) <- CPL;
   IF IDT gate is interrupt gate
        THEN IF <- 0; FI; (* Interrupt flag set to 0; interrupts disabled *)
   TF <- 0;
   NT <- 0;
   VM <- 0;
   RF <- 0;
END;

Flags Affected
The EFLAGS register is pushed onto the stack. The IF, TF, NT, AC, RF, and VM flags may be cleared, depending on
the mode of operation of the processor when the INT instruction is executed (see the "Operation" section). If the
interrupt uses a task gate, any flags may be set or cleared, controlled by the EFLAGS image in the new task's TSS.

Protected Mode Exceptions
#GP(error_code)          If the instruction pointer in the IDT or in the interrupt-, trap-, or task gate is beyond the code
                         segment limits.
                         If the segment selector in the interrupt-, trap-, or task gate is NULL.
                         If an interrupt-, trap-, or task gate, code segment, or TSS segment selector index is outside its
                         descriptor table limits.
                         If the vector selects a descriptor outside the IDT limits.
                         If an IDT descriptor is not an interrupt-, trap-, or task-descriptor.
                         If an interrupt is generated by the INT n, INT 3, or INTO instruction and the DPL of an inter-
                         rupt-, trap-, or task-descriptor is less than the CPL.
                         If the segment selector in an interrupt- or trap-gate does not point to a segment descriptor for
                         a code segment.
                         If the segment selector for a TSS has its local/global bit set for local.
                         If a TSS segment descriptor specifies that the TSS is busy or not available.





#SS(error_code)           If pushing the return address, flags, or error code onto the stack exceeds the bounds of the
                          stack segment and no stack switch occurs.
                          If the SS register is being loaded and the segment pointed to is marked not present.
                          If pushing the return address, flags, error code, or stack segment pointer exceeds the bounds
                          of the new stack segment when a stack switch occurs.
#NP(error_code)           If code segment, interrupt-, trap-, or task gate, or TSS is not present.
#TS(error_code)           If the RPL of the stack segment selector in the TSS is not equal to the DPL of the code segment
                          being accessed by the interrupt or trap gate.
                          If DPL of the stack segment descriptor pointed to by the stack segment selector in the TSS is
                          not equal to the DPL of the code segment descriptor for the interrupt or trap gate.
                          If the stack segment selector in the TSS is NULL.
                          If the stack segment for the TSS is not a writable data segment.
                          If segment-selector index for stack segment is outside descriptor table limits.
#PF(fault-code)           If a page fault occurs.
#UD                       If the LOCK prefix is used.
#AC(EXT)                  If alignment checking is enabled, the gate DPL is 3, and a stack push is unaligned.

Real-Address Mode Exceptions
#GP                       If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                          If the interrupt vector number is outside the IDT limits.
#SS                       If stack limit violation on push.
                          If pushing the return address, flags, or error code onto the stack exceeds the bounds of the
                          stack segment.
#UD                       If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
#GP(error_code)           (For INT n, INTO, or BOUND instruction) If the IOPL is less than 3 or the DPL of the interrupt-
                          , trap-, or task-gate descriptor is not equal to 3.
                          If the instruction pointer in the IDT or in the interrupt-, trap-, or task gate is beyond the code
                          segment limits.
                          If the segment selector in the interrupt-, trap-, or task gate is NULL.
                          If a interrupt-, trap-, or task gate, code segment, or TSS segment selector index is outside its
                          descriptor table limits.
                          If the vector selects a descriptor outside the IDT limits.
                          If an IDT descriptor is not an interrupt-, trap-, or task-descriptor.
                          If an interrupt is generated by the INT n instruction and the DPL of an interrupt-, trap-, or
                          task-descriptor is less than the CPL.
                          If the segment selector in an interrupt- or trap-gate does not point to a segment descriptor for
                          a code segment.
                          If the segment selector for a TSS has its local/global bit set for local.
#SS(error_code)           If the SS register is being loaded and the segment pointed to is marked not present.
                          If pushing the return address, flags, error code, stack segment pointer, or data segments
                          exceeds the bounds of the stack segment.
#NP(error_code)           If code segment, interrupt-, trap-, or task gate, or TSS is not present.





#TS(error_code)     If the RPL of the stack segment selector in the TSS is not equal to the DPL of the code segment
                    being accessed by the interrupt or trap gate.
                    If DPL of the stack segment descriptor for the TSS's stack segment is not equal to the DPL of
                    the code segment descriptor for the interrupt or trap gate.
                    If the stack segment selector in the TSS is NULL.
                    If the stack segment for the TSS is not a writable data segment.
                    If segment-selector index for stack segment is outside descriptor table limits.
#PF(fault-code)     If a page fault occurs.
#BP                 If the INT 3 instruction is executed.
#OF                 If the INTO instruction is executed and the OF flag is set.
#UD                 If the LOCK prefix is used.
#AC(EXT)            If alignment checking is enabled, the gate DPL is 3, and a stack push is unaligned.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#GP(error_code)     If the instruction pointer in the 64-bit interrupt gate or 64-bit trap gate is non-canonical.
                    If the segment selector in the 64-bit interrupt or trap gate is NULL.
                    If the vector selects a descriptor outside the IDT limits.
                    If the vector points to a gate which is in non-canonical space.
                    If the vector points to a descriptor which is not a 64-bit interrupt gate or 64-bit trap gate.
                    If the descriptor pointed to by the gate selector is outside the descriptor table limit.
                    If the descriptor pointed to by the gate selector is in non-canonical space.
                    If the descriptor pointed to by the gate selector is not a code segment.
                    If the descriptor pointed to by the gate selector doesn't have the L-bit set, or has both the L-
                    bit and D-bit set.
                    If the descriptor pointed to by the gate selector has DPL > CPL.
#SS(error_code)     If a push of the old EFLAGS, CS selector, EIP, or error code is in non-canonical space with no
                    stack switch.
                    If a push of the old SS selector, ESP, EFLAGS, CS selector, EIP, or error code is in non-canonical
                    space on a stack switch (either CPL change or no-CPL with IST).
#NP(error_code)     If the 64-bit interrupt-gate, 64-bit trap-gate, or code segment is not present.
#TS(error_code)     If an attempt to load RSP from the TSS causes an access to non-canonical space.
                    If the RSP from the TSS is outside descriptor table limits.
#PF(fault-code)     If a page fault occurs.
#UD                 If the LOCK prefix is used.
#AC(EXT)            If alignment checking is enabled, the gate DPL is 3, and a stack push is unaligned.






platform: x86_64
mnem: INVD
description:
INVD-Invalidate Internal Caches
 Opcode                      Instruction                Op/   64-Bit   Compat/ Description
                                                        En    Mode     Leg Mode
 0F 08                       INVD                       NP    Valid    Valid      Flush internal caches; initiate flushing of
                                                                                  external caches.
 NOTES:
 * See the IA-32 Architecture Compatibility section below.



                                                 Instruction Operand Encoding
    Op/En               Operand 1                   Operand 2                  Operand 3                     Operand 4
     NP                     NA                          NA                        NA                             NA

Description
Invalidates (flushes) the processor's internal caches and issues a special-function bus cycle that directs external
caches to also flush themselves. Data held in internal caches is not written back to main memory.
After executing this instruction, the processor does not wait for the external caches to complete their flushing oper-
ation before proceeding with instruction execution. It is the responsibility of hardware to respond to the cache flush
signal.
The INVD instruction is a privileged instruction. When the processor is running in protected mode, the CPL of a
program or procedure must be 0 to execute this instruction.
The INVD instruction may be used when the cache is used as temporary memory and the cache contents need to
be invalidated rather than written back to memory. When the cache is used as temporary memory, no external
device should be actively writing data to main memory.
Use this instruction with care. Data cached internally and not written back to main memory will be lost. Note that
any data from an external device to main memory (for example, via a PCIWrite) can be temporarily stored in the
caches; these data can be lost when an INVD instruction is executed. Unless there is a specific requirement or
benefit to flushing caches without writing back modified cache lines (for example, temporary memory, testing, or
fault recovery where cache coherency with main memory is not a concern), software should instead use the
WBINVD instruction.
This instruction's operation is the same in non-64-bit modes and 64-bit mode.

IA-32 Architecture Compatibility
The INVD instruction is implementation dependent; it may be implemented differently on different families of Intel
64 or IA-32 processors. This instruction is not supported on IA-32 processors earlier than the Intel486 processor.

Operation
Flush(InternalCaches);
SignalFlush(ExternalCaches);
Continue (* Continue execution *)

Flags Affected
None

Protected Mode Exceptions
#GP(0)                    If the current privilege level is not 0.
#UD                       If the LOCK prefix is used.

Real-Address Mode Exceptions
#UD                       If the LOCK prefix is used.



Virtual-8086 Mode Exceptions
#GP(0)              The INVD instruction cannot be executed in virtual-8086 mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
Same exceptions as in protected mode.






platform: x86_64
mnem: INVLPG
description:
INVLPG-Invalidate TLB Entries
 Opcode                     Instruction                 Op/    64-Bit      Compat/ Description
                                                        En     Mode        Leg Mode
 0F 01/7                    INVLPG m                    M      Valid       Valid       Invalidate TLB entries for page containing m.
 NOTES:
 * See the IA-32 Architecture Compatibility section below.



                                                  Instruction Operand Encoding
  Op/En              Operand 1                     Operand 2                       Operand 3                    Operand 4
    M              ModRM:r/m (r)                      NA                              NA                            NA

Description
Invalidates any translation lookaside buffer (TLB) entries specified with the source operand. The source operand is
a memory address. The processor determines the page that contains that address and flushes all TLB entries for
that page.1
The INVLPG instruction is a privileged instruction. When the processor is running in protected mode, the CPL must
be 0 to execute this instruction.
The INVLPG instruction normally flushes TLB entries only for the specified page; however, in some cases, it may
flush more entries, even the entire TLB. The instruction is guaranteed to invalidates only TLB entries associated
with the current PCID. (If PCIDs are disabled - CR4.PCIDE = 0 - the current PCID is 000H.) The instruction also
invalidates any global TLB entries for the specified page, regardless of PCID.
For more details on operations that flush the TLB, see "MOV-Move to/from Control Registers" in the Intel 64 and
IA-32 Architectures Software Developer's Manual, Volume 2B and Section 4.10.4.1, "Operations that Invalidate
TLBs and Paging-Structure Caches," in the Intel 64 and IA-32 Architectures Software Developer's Manual,
Volume 3A.
This instruction's operation is the same in all non-64-bit modes. It also operates the same in 64-bit mode, except
if the memory address is in non-canonical form. In this case, INVLPG is the same as a NOP.

IA-32 Architecture Compatibility
The INVLPG instruction is implementation dependent, and its function may be implemented differently on different
families of Intel 64 or IA-32 processors. This instruction is not supported on IA-32 processors earlier than the
Intel486 processor.

Operation
Invalidate(RelevantTLBEntries);
Continue; (* Continue execution *)

Flags Affected
None.

Protected Mode Exceptions
#GP(0)                   If the current privilege level is not 0.
#UD                      Operand is a register.
                         If the LOCK prefix is used.



1. If the paging structures map the linear address using a page larger than 4 KBytes and there are multiple TLB entries for that page
   (see Section 4.10.2.3, "Details of TLB Use," in the Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3A), the
   instruction invalidates all of them.



Real-Address Mode Exceptions
#UD                 Operand is a register.
                    If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
#GP(0)              The INVLPG instruction cannot be executed at the virtual-8086 mode.

64-Bit Mode Exceptions
#GP(0)              If the current privilege level is not 0.
#UD                 Operand is a register.
                    If the LOCK prefix is used.






platform: x86_64
mnem: INVPCID
description:
INVPCID-Invalidate Process-Context Identifier
 Opcode/Instruction                                  Op/     64/32-   CPUID        Description
                                                     En      bit      Feature
                                                             Mode     Flag
 66 0F 38 82 /r                                      RM      NE/V     INVPCID      Invalidates entries in the TLBs and paging-structure
 INVPCID r32, m128                                                                 caches based on invalidation type in r32 and descrip-
                                                                                   tor in m128.

 66 0F 38 82 /r                                      RM      V/NE     INVPCID      Invalidates entries in the TLBs and paging-structure
 INVPCID r64, m128                                                                 caches based on invalidation type in r64 and descrip-
                                                                                   tor in m128.



                                                    Instruction Operand Encoding
    Op/En               Operand 1                     Operand 2                       Operand 3                     Operand 4
     RM               ModRM:reg (R)                 ModRM:r/m (R)                        NA                             NA

Description
Invalidates mappings in the translation lookaside buffers (TLBs) and paging-structure caches based on process-
context identifier (PCID). (See Section 4.10, "Caching Translation Information," in Intel 64 and IA-32 Architecture
Software Developer's Manual, Volume 3A.) Invalidation is based on the INVPCID type specified in the register
operand and the INVPCID descriptor specified in the memory operand.
Outside 64-bit mode, the register operand is always 32 bits, regardless of the value of CS.D. In 64-bit mode the
register operand has 64 bits.
There are four INVPCID types currently defined:
.    Individual-address invalidation: If the INVPCID type is 0, the logical processor invalidates mappings-except
     global translations-for the linear address and PCID specified in the INVPCID descriptor.1 In some cases, the
     instruction may invalidate global translations or mappings for other linear addresses (or other PCIDs) as well.
.    Single-context invalidation: If the INVPCID type is 1, the logical processor invalidates all mappings-except
     global translations-associated with the PCID specified in the INVPCID descriptor. In some cases, the
     instruction may invalidate global translations or mappings for other PCIDs as well.
.    All-context invalidation, including global translations: If the INVPCID type is 2, the logical processor invalidates
     all mappings-including global translations-associated with any PCID.
.    All-context invalidation: If the INVPCID type is 3, the logical processor invalidates all mappings-except global
     translations-associated with any PCID. In some case, the instruction may invalidate global translations as
     well.
The INVPCID descriptor comprises 128 bits and consists of a PCID and a linear address as shown in Figure 3-24.
For INVPCID type 0, the processor uses the full 64 bits of the linear address even outside 64-bit mode; the linear
address is not used for other INVPCID types.




                             127                                    64 63                             12 11     0
                                            Linear Address                  Reserved (must be zero)      PCID




                                                  Figure 3-24. INVPCID Descriptor

1. If the paging structures map the linear address using a page larger than 4 KBytes and there are multiple TLB entries for that page
   (see Section 4.10.2.3, "Details of TLB Use," in the Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3A), the
   instruction invalidates all of them.



If CR4.PCIDE = 0, a logical processor does not cache information for any PCID other than 000H. In this case,
executions with INVPCID types 0 and 1 are allowed only if the PCID specified in the INVPCID descriptor is 000H;
executions with INVPCID types 2 and 3 invalidate mappings only for PCID 000H. Note that CR4.PCIDE must be 0
outside 64-bit mode (see Chapter 4.10.1, "Process-Context Identifiers (PCIDs)" of the Intel 64 and IA-32 Archi-
tectures Software Developer's Manual, Volume 3A).

Operation
INVPCID_TYPE <- value of register operand;              // must be in the range of 0-3
INVPCID_DESC <- value of memory operand;
CASE INVPCID_TYPE OF
   0:                  // individual-address invalidation
       PCID <- INVPCID_DESC[11:0];
       L_ADDR <- INVPCID_DESC[127:64];
       Invalidate mappings for L_ADDR associated with PCID except global translations;
       BREAK;
   1:                  // single PCID invalidation
       PCID <- INVPCID_DESC[11:0];
       Invalidate all mappings associated with PCID except global translations;
       BREAK;
   2:                  // all PCID invalidation including global translations
       Invalidate all mappings for all PCIDs, including global translations;
       BREAK;
   3:                  // all PCID invalidation retaining global translations
       Invalidate all mappings for all PCIDs except global translations;
       BREAK;
ESAC;

Intel C/C++ Compiler Intrinsic Equivalent
INVPCID:    void _invpcid(unsigned __int32 type, void * descriptor);

SIMD Floating-Point Exceptions
None

Protected Mode Exceptions
#GP(0)                  If the current privilege level is not 0.
                        If the memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                        If the DS, ES, FS, or GS register contains an unusable segment.
                        If the source operand is located in an execute-only code segment.
                        If an invalid type is specified in the register operand, i.e., INVPCID_TYPE > 3.
                        If bits 63:12 of INVPCID_DESC are not all zero.
                        If INVPCID_TYPE is either 0 or 1 and INVPCID_DESC[11:0] is not zero.
                        If INVPCID_TYPE is 0 and the linear address in INVPCID_DESC[127:64] is not canonical.
#PF(fault-code)         If a page fault occurs in accessing the memory operand.
#SS(0)                  If the memory operand effective address is outside the SS segment limit.
                        If the SS register contains an unusable segment.
#UD                     If if CPUID.(EAX=07H, ECX=0H):EBX.INVPCID (bit 10) = 0.
                        If the LOCK prefix is used.





Real-Address Mode Exceptions
#GP                       If an invalid type is specified in the register operand, i.e., INVPCID_TYPE > 3.
                          If bits 63:12 of INVPCID_DESC are not all zero.
                          If INVPCID_TYPE is either 0 or 1 and INVPCID_DESC[11:0] is not zero.
                          If INVPCID_TYPE is 0 and the linear address in INVPCID_DESC[127:64] is not canonical.
#UD                       If CPUID.(EAX=07H, ECX=0H):EBX.INVPCID (bit 10) = 0.
                          If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
#GP(0)                    The INVPCID instruction is not recognized in virtual-8086 mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#GP(0)                    If the current privilege level is not 0.
                          If the memory operand is in the CS, DS, ES, FS, or GS segments and the memory address is
                          in a non-canonical form.
                          If an invalid type is specified in the register operand, i.e., INVPCID_TYPE > 3.
                          If bits 63:12 of INVPCID_DESC are not all zero.
                          If CR4.PCIDE=0, INVPCID_TYPE is either 0 or 1, and INVPCID_DESC[11:0] is not zero.
                          If INVPCID_TYPE is 0 and the linear address in INVPCID_DESC[127:64] is not canonical.
#PF(fault-code)           If a page fault occurs in accessing the memory operand.
#SS(0)                    If the memory destination operand is in the SS segment and the memory address is in a non-
                          canonical form.
#UD                       If the LOCK prefix is used.
                          If CPUID.(EAX=07H, ECX=0H):EBX.INVPCID (bit 10) = 0.






platform: x86_64
mnem: IRET
description:
IRET/IRETD-Interrupt Return
Opcode                   Instruction              Op/     64-Bit   Compat/ Description
                                                  En      Mode     Leg Mode
CF                       IRET                     NP      Valid    Valid        Interrupt return (16-bit operand size).
CF                       IRETD                    NP      Valid    Valid        Interrupt return (32-bit operand size).
REX.W + CF               IRETQ                    NP      Valid    N.E.         Interrupt return (64-bit operand size).



                                            Instruction Operand Encoding
    Op/En          Operand 1                  Operand 2                    Operand 3                      Operand 4
     NP               NA                         NA                           NA                              NA

Description
Returns program control from an exception or interrupt handler to a program or procedure that was interrupted by
an exception, an external interrupt, or a software-generated interrupt. These instructions are also used to perform
a return from a nested task. (A nested task is created when a CALL instruction is used to initiate a task switch or
when an interrupt or exception causes a task switch to an interrupt or exception handler.) See the section titled
"Task Linking" in Chapter 7 of the Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3A.
IRET and IRETD are mnemonics for the same opcode. The IRETD mnemonic (interrupt return double) is intended
for use when returning from an interrupt when using the 32-bit operand size; however, most assemblers use the
IRET mnemonic interchangeably for both operand sizes.
In Real-Address Mode, the IRET instruction preforms a far return to the interrupted program or procedure. During
this operation, the processor pops the return instruction pointer, return code segment selector, and EFLAGS image
from the stack to the EIP, CS, and EFLAGS registers, respectively, and then resumes execution of the interrupted
program or procedure.
In Protected Mode, the action of the IRET instruction depends on the settings of the NT (nested task) and VM flags
in the EFLAGS register and the VM flag in the EFLAGS image stored on the current stack. Depending on the setting
of these flags, the processor performs the following types of interrupt returns:
.    Return from virtual-8086 mode.
.    Return to virtual-8086 mode.
.    Intra-privilege level return.
.    Inter-privilege level return.
.    Return from nested task (task switch).
If the NT flag (EFLAGS register) is cleared, the IRET instruction performs a far return from the interrupt procedure,
without a task switch. The code segment being returned to must be equally or less privileged than the interrupt
handler routine (as indicated by the RPL field of the code segment selector popped from the stack).
As with a real-address mode interrupt return, the IRET instruction pops the return instruction pointer, return code
segment selector, and EFLAGS image from the stack to the EIP, CS, and EFLAGS registers, respectively, and then
resumes execution of the interrupted program or procedure. If the return is to another privilege level, the IRET
instruction also pops the stack pointer and SS from the stack, before resuming program execution. If the return is
to virtual-8086 mode, the processor also pops the data segment registers from the stack.
If the NT flag is set, the IRET instruction performs a task switch (return) from a nested task (a task called with a
CALL instruction, an interrupt, or an exception) back to the calling or interrupted task. The updated state of the
task executing the IRET instruction is saved in its TSS. If the task is re-entered later, the code that follows the IRET
instruction is executed.
If the NT flag is set and the processor is in IA-32e mode, the IRET instruction causes a general protection excep-
tion.
If nonmaskable interrupts (NMIs) are blocked (see Section 6.7.1, "Handling Multiple NMIs" in the Intel 64 and
IA-32 Architectures Software Developer's Manual, Volume 3A), execution of the IRET instruction unblocks NMIs.




This unblocking occurs even if the instruction causes a fault. In such a case, NMIs are unmasked before the excep-
tion handler is invoked.
In 64-bit mode, the instruction's default operation size is 32 bits. Use of the REX.W prefix promotes operation to 64
bits (IRETQ). See the summary chart at the beginning of this section for encoding data and limits.
See "Changes to Instruction Behavior in VMX Non-Root Operation" in Chapter 25 of the Intel 64 and IA-32 Archi-
tectures Software Developer's Manual, Volume 3C, for more information about the behavior of this instruction in
VMX non-root operation.

Operation
IF PE = 0
    THEN GOTO REAL-ADDRESS-MODE;
ELSIF (IA32_EFER.LMA = 0)
    THEN
         IF (EFLAGS.VM = 1)
              THEN GOTO RETURN-FROM-VIRTUAL-8086-MODE;
              ELSE GOTO PROTECTED-MODE;
         FI;
    ELSE GOTO IA-32e-MODE;
FI;

REAL-ADDRESS-MODE;
   IF OperandSize = 32
        THEN
            EIP <- Pop();
            CS <- Pop(); (* 32-bit pop, high-order 16 bits discarded *)
            tempEFLAGS <- Pop();
            EFLAGS <- (tempEFLAGS AND 257FD5H) OR (EFLAGS AND 1A0000H);
        ELSE (* OperandSize = 16 *)
            EIP <- Pop(); (* 16-bit pop; clear upper 16 bits *)
            CS <- Pop(); (* 16-bit pop *)
            EFLAGS[15:0] <- Pop();
   FI;
   END;

RETURN-FROM-VIRTUAL-8086-MODE:
(* Processor is in virtual-8086 mode when IRET is executed and stays in virtual-8086 mode *)
    IF IOPL = 3 (* Virtual mode: PE = 1, VM = 1, IOPL = 3 *)
         THEN IF OperandSize = 32
             THEN
                   EIP <- Pop();
                   CS <- Pop(); (* 32-bit pop, high-order 16 bits discarded *)
                   EFLAGS <- Pop();
                   (* VM, IOPL,VIP and VIF EFLAG bits not modified by pop *)
                   IF EIP not within CS limit
                        THEN #GP(0); FI;
             ELSE (* OperandSize = 16 *)
                   EIP <- Pop(); (* 16-bit pop; clear upper 16 bits *)
                   CS <- Pop(); (* 16-bit pop *)
                   EFLAGS[15:0] <- Pop(); (* IOPL in EFLAGS not modified by pop *)
                   IF EIP not within CS limit
                        THEN #GP(0); FI;
             FI;
         ELSE



             #GP(0); (* Trap to virtual-8086 monitor: PE   = 1, VM = 1, IOPL < 3 *)
   FI;
END;

PROTECTED-MODE:
   IF NT = 1
        THEN GOTO TASK-RETURN; (* PE = 1, VM = 0, NT = 1 *)
   FI;
   IF OperandSize = 32
        THEN
             EIP <- Pop();
             CS <- Pop(); (* 32-bit pop, high-order 16 bits discarded *)
             tempEFLAGS <- Pop();
        ELSE (* OperandSize = 16 *)
             EIP <- Pop(); (* 16-bit pop; clear upper bits *)
             CS <- Pop(); (* 16-bit pop *)
             tempEFLAGS <- Pop(); (* 16-bit pop; clear upper bits *)
   FI;
   IF tempEFLAGS(VM) = 1 and CPL = 0
        THEN GOTO RETURN-TO-VIRTUAL-8086-MODE;
        ELSE GOTO PROTECTED-MODE-RETURN;
   FI;

TASK-RETURN: (* PE = 1, VM = 0, NT = 1 *)
   SWITCH-TASKS (without nesting) to TSS specified in link field of current TSS;
   Mark the task just abandoned as NOT BUSY;
   IF EIP is not within CS limit
        THEN #GP(0); FI;
END;

RETURN-TO-VIRTUAL-8086-MODE:
   (* Interrupted procedure was in virtual-8086 mode: PE = 1, CPL=0, VM      = 1 in flag image *)
   IF EIP not within CS limit
         THEN #GP(0); FI;
   EFLAGS <- tempEFLAGS;
   ESP <- Pop();
   SS <- Pop(); (* Pop 2 words; throw away high-order word *)
   ES <- Pop(); (* Pop 2 words; throw away high-order word *)
   DS <- Pop(); (* Pop 2 words; throw away high-order word *)
   FS <- Pop(); (* Pop 2 words; throw away high-order word *)
   GS <- Pop(); (* Pop 2 words; throw away high-order word *)
   CPL <- 3;
   (* Resume execution in Virtual-8086 mode *)
END;

PROTECTED-MODE-RETURN: (* PE = 1 *)
   IF CS(RPL) > CPL
        THEN GOTO RETURN-TO-OUTER-PRIVILEGE-LEVEL;
        ELSE GOTO RETURN-TO-SAME-PRIVILEGE-LEVEL; FI;
END;

RETURN-TO-OUTER-PRIVILEGE-LEVEL:
   IF OperandSize = 32
        THEN



             ESP <- Pop();
             SS <- Pop(); (* 32-bit pop, high-order 16 bits discarded *)
   ELSE IF OperandSize = 16
        THEN
             ESP <- Pop(); (* 16-bit pop; clear upper bits *)
             SS <- Pop(); (* 16-bit pop *)
        ELSE (* OperandSize = 64 *)
             RSP <- Pop();
             SS <- Pop(); (* 64-bit pop, high-order 48 bits discarded *)
   FI;
   IF new mode != 64-Bit Mode
        THEN
             IF EIP is not within CS limit
                  THEN #GP(0); FI;
        ELSE (* new mode = 64-bit mode *)
             IF RIP is non-canonical
                        THEN #GP(0); FI;
   FI;
   EFLAGS (CF, PF, AF, ZF, SF, TF, DF, OF, NT) <- tempEFLAGS;
   IF OperandSize = 32
        THEN EFLAGS(RF, AC, ID) <- tempEFLAGS; FI;
   IF CPL <= IOPL
        THEN EFLAGS(IF) <- tempEFLAGS; FI;
   IF CPL = 0
        THEN
             EFLAGS(IOPL) <- tempEFLAGS;
             IF OperandSize = 32
                  THEN EFLAGS(VM, VIF, VIP) <- tempEFLAGS; FI;
             IF OperandSize = 64
                  THEN EFLAGS(VIF, VIP) <- tempEFLAGS; FI;
   FI;
   CPL <- CS(RPL);
   FOR each SegReg in (ES, FS, GS, and DS)
        DO
             tempDesc <- descriptor cache for SegReg (* hidden part of segment register *)
             IF tempDesc(DPL) < CPL AND tempDesc(Type) is data or non-conforming code
                  THEN (* Segment register invalid *)
                        SegReg <- NULL;
             FI;
        OD;
END;

RETURN-TO-SAME-PRIVILEGE-LEVEL: (* PE = 1, RPL = CPL *)
   IF new mode != 64-Bit Mode
        THEN
            IF EIP is not within CS limit
                 THEN #GP(0); FI;
        ELSE (* new mode = 64-bit mode *)
            IF RIP is non-canonical
                       THEN #GP(0); FI;
   FI;
   EFLAGS (CF, PF, AF, ZF, SF, TF, DF, OF, NT) <- tempEFLAGS;
   IF OperandSize = 32 or OperandSize = 64
        THEN EFLAGS(RF, AC, ID) <- tempEFLAGS; FI;



   IF CPL <= IOPL
        THEN EFLAGS(IF) <- tempEFLAGS; FI;
   IF CPL = 0
        THEN (* VM = 0 in flags image *)
              EFLAGS(IOPL) <- tempEFLAGS;
              IF OperandSize = 32 or OperandSize = 64
                  THEN EFLAGS(VIF, VIP) <- tempEFLAGS; FI;
   FI;
END;

IA-32e-MODE:
    IF NT = 1
         THEN #GP(0);
    ELSE IF OperandSize = 32
         THEN
              EIP <- Pop();
              CS <- Pop();
              tempEFLAGS <- Pop();
         ELSE IF OperandSize = 16
              THEN
                    EIP <- Pop(); (* 16-bit pop; clear upper bits *)
                    CS <- Pop(); (* 16-bit pop *)
                    tempEFLAGS <- Pop(); (* 16-bit pop; clear upper bits *)
              FI;
         ELSE (* OperandSize = 64 *)
              THEN
                        RIP <- Pop();
                        CS <- Pop(); (* 64-bit pop, high-order 48 bits discarded *)
                        tempRFLAGS <- Pop();
    FI;
    IF tempCS.RPL > CPL
         THEN GOTO RETURN-TO-OUTER-PRIVILEGE-LEVEL;
         ELSE
              IF instruction began in 64-Bit Mode
                    THEN
                        IF OperandSize = 32
                             THEN
                                   ESP <- Pop();
                                   SS <- Pop(); (* 32-bit pop, high-order 16 bits discarded *)
                        ELSE IF OperandSize = 16
                             THEN
                                   ESP <- Pop(); (* 16-bit pop; clear upper bits *)
                                   SS <- Pop(); (* 16-bit pop *)
                             ELSE (* OperandSize = 64 *)
                                   RSP <- Pop();
                                   SS <- Pop(); (* 64-bit pop, high-order 48 bits discarded *)
                        FI;
              FI;
              GOTO RETURN-TO-SAME-PRIVILEGE-LEVEL; FI;
END;





Flags Affected
All the flags and fields in the EFLAGS register are potentially modified, depending on the mode of operation of the
processor. If performing a return from a nested task to a previous task, the EFLAGS register will be modified
according to the EFLAGS image stored in the previous task's TSS.

Protected Mode Exceptions
#GP(0)                  If the return code or stack segment selector is NULL.
                        If the return instruction pointer is not within the return code segment limit.
#GP(selector)           If a segment selector index is outside its descriptor table limits.
                        If the return code segment selector RPL is less than the CPL.
                        If the DPL of a conforming-code segment is greater than the return code segment selector
                        RPL.
                        If the DPL for a nonconforming-code segment is not equal to the RPL of the code segment
                        selector.
                        If the stack segment descriptor DPL is not equal to the RPL of the return code segment
                        selector.
                        If the stack segment is not a writable data segment.
                        If the stack segment selector RPL is not equal to the RPL of the return code segment selector.
                        If the segment descriptor for a code segment does not indicate it is a code segment.
                        If the segment selector for a TSS has its local/global bit set for local.
                        If a TSS segment descriptor specifies that the TSS is not busy.
                        If a TSS segment descriptor specifies that the TSS is not available.
#SS(0)                  If the top bytes of stack are not within stack limits.
#NP(selector)           If the return code or stack segment is not present.
#PF(fault-code)         If a page fault occurs.
#AC(0)                  If an unaligned memory reference occurs when the CPL is 3 and alignment checking is
                        enabled.
#UD                     If the LOCK prefix is used.

Real-Address Mode Exceptions
#GP                     If the return instruction pointer is not within the return code segment limit.
#SS                     If the top bytes of stack are not within stack limits.

Virtual-8086 Mode Exceptions
#GP(0)                  If the return instruction pointer is not within the return code segment limit.
                        IF IOPL not equal to 3.
#PF(fault-code)         If a page fault occurs.
#SS(0)                  If the top bytes of stack are not within stack limits.
#AC(0)                  If an unaligned memory reference occurs and alignment checking is enabled.
#UD                     If the LOCK prefix is used.

Compatibility Mode Exceptions
#GP(0)                  If EFLAGS.NT[bit 14] = 1.
Other exceptions same as in Protected Mode.





64-Bit Mode Exceptions
#GP(0)              If EFLAGS.NT[bit 14] = 1.
                    If the return code segment selector is NULL.
                    If the stack segment selector is NULL going back to compatibility mode.
                    If the stack segment selector is NULL going back to CPL3 64-bit mode.
                    If a NULL stack segment selector RPL is not equal to CPL going back to non-CPL3 64-bit mode.
                    If the return instruction pointer is not within the return code segment limit.
                    If the return instruction pointer is non-canonical.
#GP(Selector)       If a segment selector index is outside its descriptor table limits.
                    If a segment descriptor memory address is non-canonical.
                    If the segment descriptor for a code segment does not indicate it is a code segment.
                    If the proposed new code segment descriptor has both the D-bit and L-bit set.
                    If the DPL for a nonconforming-code segment is not equal to the RPL of the code segment
                    selector.
                    If CPL is greater than the RPL of the code segment selector.
                    If the DPL of a conforming-code segment is greater than the return code segment selector
                    RPL.
                    If the stack segment is not a writable data segment.
                    If the stack segment descriptor DPL is not equal to the RPL of the return code segment
                    selector.
                    If the stack segment selector RPL is not equal to the RPL of the return code segment selector.
#SS(0)              If an attempt to pop a value off the stack violates the SS limit.
                    If an attempt to pop a value off the stack causes a non-canonical address to be referenced.
#NP(selector)       If the return code or stack segment is not present.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If an unaligned memory reference occurs when the CPL is 3 and alignment checking is
                    enabled.
#UD                 If the LOCK prefix is used.






platform: x86_64
mnem: Jcc
description:
Jcc-Jump if Condition Is Met
 Opcode                        Instruction   Op/   64-Bit   Compat/ Description
                                             En    Mode     Leg Mode
 77 cb                         JA rel8       D     Valid    Valid    Jump short if above (CF=0 and ZF=0).
 73 cb                         JAE rel8      D     Valid    Valid    Jump short if above or equal (CF=0).
 72 cb                         JB rel8       D     Valid    Valid    Jump short if below (CF=1).
 76 cb                         JBE rel8      D     Valid    Valid    Jump short if below or equal (CF=1 or ZF=1).
 72 cb                         JC rel8       D     Valid    Valid    Jump short if carry (CF=1).
 E3 cb                         JCXZ rel8     D     N.E.     Valid    Jump short if CX register is 0.
 E3 cb                         JECXZ rel8    D     Valid    Valid    Jump short if ECX register is 0.
 E3 cb                         JRCXZ rel8    D     Valid    N.E.     Jump short if RCX register is 0.
 74 cb                         JE rel8       D     Valid    Valid    Jump short if equal (ZF=1).
 7F cb                         JG rel8       D     Valid    Valid    Jump short if greater (ZF=0 and SF=OF).
 7D cb                         JGE rel8      D     Valid    Valid    Jump short if greater or equal (SF=OF).
 7C cb                         JL rel8       D     Valid    Valid    Jump short if less (SF!= OF).
 7E cb                         JLE rel8      D     Valid    Valid    Jump short if less or equal (ZF=1 or SF!= OF).
 76 cb                         JNA rel8      D     Valid    Valid    Jump short if not above (CF=1 or ZF=1).
 72 cb                         JNAE rel8     D     Valid    Valid    Jump short if not above or equal (CF=1).
 73 cb                         JNB rel8      D     Valid    Valid    Jump short if not below (CF=0).
 77 cb                         JNBE rel8     D     Valid    Valid    Jump short if not below or equal (CF=0 and
                                                                     ZF=0).
 73 cb                         JNC rel8      D     Valid    Valid    Jump short if not carry (CF=0).
 75 cb                         JNE rel8      D     Valid    Valid    Jump short if not equal (ZF=0).
 7E cb                         JNG rel8      D     Valid    Valid    Jump short if not greater (ZF=1 or SF!= OF).
 7C cb                         JNGE rel8     D     Valid    Valid    Jump short if not greater or equal (SF!= OF).
 7D cb                         JNL rel8      D     Valid    Valid    Jump short if not less (SF=OF).
 7F cb                         JNLE rel8     D     Valid    Valid    Jump short if not less or equal (ZF=0 and
                                                                     SF=OF).
 71 cb                         JNO rel8      D     Valid    Valid    Jump short if not overflow (OF=0).
 7B cb                         JNP rel8      D     Valid    Valid    Jump short if not parity (PF=0).
 79 cb                         JNS rel8      D     Valid    Valid    Jump short if not sign (SF=0).


 75 cb                         JNZ rel8      D     Valid    Valid    Jump short if not zero (ZF=0).
 70 cb                         JO rel8       D     Valid    Valid    Jump short if overflow (OF=1).
 7A cb                         JP rel8       D     Valid    Valid    Jump short if parity (PF=1).
 7A cb                         JPE rel8      D     Valid    Valid    Jump short if parity even (PF=1).
 7B cb                         JPO rel8      D     Valid    Valid    Jump short if parity odd (PF=0).
 78 cb                         JS rel8       D     Valid    Valid    Jump short if sign (SF=1).
 74 cb                         JZ rel8       D     Valid    Valid    Jump short if zero (ZF = 1).
 0F 87 cw                      JA rel16      D     N.S.     Valid    Jump near if above (CF=0 and ZF=0). Not
                                                                     supported in 64-bit mode.
 0F 87 cd                      JA rel32      D     Valid    Valid    Jump near if above (CF=0 and ZF=0).
 0F 83 cw                      JAE rel16     D     N.S.     Valid    Jump near if above or equal (CF=0). Not
                                                                     supported in 64-bit mode.



Opcode                 Instruction   Op/   64-Bit   Compat/ Description
                                     En    Mode     Leg Mode
0F 83 cd               JAE rel32     D     Valid    Valid    Jump near if above or equal (CF=0).
0F 82 cw               JB rel16      D     N.S.     Valid    Jump near if below (CF=1). Not supported in
                                                             64-bit mode.
0F 82 cd               JB rel32      D     Valid    Valid    Jump near if below (CF=1).
0F 86 cw               JBE rel16     D     N.S.     Valid    Jump near if below or equal (CF=1 or ZF=1).
                                                             Not supported in 64-bit mode.
0F 86 cd               JBE rel32     D     Valid    Valid    Jump near if below or equal (CF=1 or ZF=1).
0F 82 cw               JC rel16      D     N.S.     Valid    Jump near if carry (CF=1). Not supported in
                                                             64-bit mode.
0F 82 cd               JC rel32      D     Valid    Valid    Jump near if carry (CF=1).
0F 84 cw               JE rel16      D     N.S.     Valid    Jump near if equal (ZF=1). Not supported in
                                                             64-bit mode.
0F 84 cd               JE rel32      D     Valid    Valid    Jump near if equal (ZF=1).
0F 84 cw               JZ rel16      D     N.S.     Valid    Jump near if 0 (ZF=1). Not supported in 64-bit
                                                             mode.
0F 84 cd               JZ rel32      D     Valid    Valid    Jump near if 0 (ZF=1).
0F 8F cw               JG rel16      D     N.S.     Valid    Jump near if greater (ZF=0 and SF=OF). Not
                                                             supported in 64-bit mode.
0F 8F cd               JG rel32      D     Valid    Valid    Jump near if greater (ZF=0 and SF=OF).
0F 8D cw               JGE rel16     D     N.S.     Valid    Jump near if greater or equal (SF=OF). Not
                                                             supported in 64-bit mode.
0F 8D cd               JGE rel32     D     Valid    Valid    Jump near if greater or equal (SF=OF).
0F 8C cw               JL rel16      D     N.S.     Valid    Jump near if less (SF!= OF). Not supported in
                                                             64-bit mode.
0F 8C cd               JL rel32      D     Valid    Valid    Jump near if less (SF!= OF).
0F 8E cw               JLE rel16     D     N.S.     Valid    Jump near if less or equal (ZF=1 or SF!= OF).
                                                             Not supported in 64-bit mode.
0F 8E cd               JLE rel32     D     Valid    Valid    Jump near if less or equal (ZF=1 or SF!= OF).
0F 86 cw               JNA rel16     D     N.S.     Valid    Jump near if not above (CF=1 or ZF=1). Not
                                                             supported in 64-bit mode.
0F 86 cd               JNA rel32     D     Valid    Valid    Jump near if not above (CF=1 or ZF=1).
0F 82 cw               JNAE rel16    D     N.S.     Valid    Jump near if not above or equal (CF=1). Not
                                                             supported in 64-bit mode.
0F 82 cd               JNAE rel32    D     Valid    Valid    Jump near if not above or equal (CF=1).
0F 83 cw               JNB rel16     D     N.S.     Valid    Jump near if not below (CF=0). Not supported
                                                             in 64-bit mode.
0F 83 cd               JNB rel32     D     Valid    Valid    Jump near if not below (CF=0).
0F 87 cw               JNBE rel16    D     N.S.     Valid    Jump near if not below or equal (CF=0 and
                                                             ZF=0). Not supported in 64-bit mode.
0F 87 cd               JNBE rel32    D     Valid    Valid    Jump near if not below or equal (CF=0 and
                                                             ZF=0).


0F 83 cw               JNC rel16     D     N.S.     Valid    Jump near if not carry (CF=0). Not supported
                                                             in 64-bit mode.
0F 83 cd               JNC rel32     D     Valid    Valid    Jump near if not carry (CF=0).



 Opcode                        Instruction   Op/   64-Bit   Compat/ Description
                                             En    Mode     Leg Mode
 0F 85 cw                      JNE rel16     D     N.S.     Valid    Jump near if not equal (ZF=0). Not supported
                                                                     in 64-bit mode.
 0F 85 cd                      JNE rel32     D     Valid    Valid    Jump near if not equal (ZF=0).
 0F 8E cw                      JNG rel16     D     N.S.     Valid    Jump near if not greater (ZF=1 or SF!= OF).
                                                                     Not supported in 64-bit mode.
 0F 8E cd                      JNG rel32     D     Valid    Valid    Jump near if not greater (ZF=1 or SF!= OF).
 0F 8C cw                      JNGE rel16    D     N.S.     Valid    Jump near if not greater or equal (SF!= OF).
                                                                     Not supported in 64-bit mode.
 0F 8C cd                      JNGE rel32    D     Valid    Valid    Jump near if not greater or equal (SF!= OF).
 0F 8D cw                      JNL rel16     D     N.S.     Valid    Jump near if not less (SF=OF). Not supported
                                                                     in 64-bit mode.
 0F 8D cd                      JNL rel32     D     Valid    Valid    Jump near if not less (SF=OF).
 0F 8F cw                      JNLE rel16    D     N.S.     Valid    Jump near if not less or equal (ZF=0 and
                                                                     SF=OF). Not supported in 64-bit mode.
 0F 8F cd                      JNLE rel32    D     Valid    Valid    Jump near if not less or equal (ZF=0 and
                                                                     SF=OF).
 0F 81 cw                      JNO rel16     D     N.S.     Valid    Jump near if not overflow (OF=0). Not
                                                                     supported in 64-bit mode.
 0F 81 cd                      JNO rel32     D     Valid    Valid    Jump near if not overflow (OF=0).
 0F 8B cw                      JNP rel16     D     N.S.     Valid    Jump near if not parity (PF=0). Not supported
                                                                     in 64-bit mode.
 0F 8B cd                      JNP rel32     D     Valid    Valid    Jump near if not parity (PF=0).
 0F 89 cw                      JNS rel16     D     N.S.     Valid    Jump near if not sign (SF=0). Not supported in
                                                                     64-bit mode.
 0F 89 cd                      JNS rel32     D     Valid    Valid    Jump near if not sign (SF=0).
 0F 85 cw                      JNZ rel16     D     N.S.     Valid    Jump near if not zero (ZF=0). Not supported in
                                                                     64-bit mode.
 0F 85 cd                      JNZ rel32     D     Valid    Valid    Jump near if not zero (ZF=0).
 0F 80 cw                      JO rel16      D     N.S.     Valid    Jump near if overflow (OF=1). Not supported
                                                                     in 64-bit mode.
 0F 80 cd                      JO rel32      D     Valid    Valid    Jump near if overflow (OF=1).
 0F 8A cw                      JP rel16      D     N.S.     Valid    Jump near if parity (PF=1). Not supported in
                                                                     64-bit mode.
 0F 8A cd                      JP rel32      D     Valid    Valid    Jump near if parity (PF=1).
 0F 8A cw                      JPE rel16     D     N.S.     Valid    Jump near if parity even (PF=1). Not
                                                                     supported in 64-bit mode.
 0F 8A cd                      JPE rel32     D     Valid    Valid    Jump near if parity even (PF=1).
 0F 8B cw                      JPO rel16     D     N.S.     Valid    Jump near if parity odd (PF=0). Not supported
                                                                     in 64-bit mode.
 0F 8B cd                      JPO rel32     D     Valid    Valid    Jump near if parity odd (PF=0).
 0F 88 cw                      JS rel16      D     N.S.     Valid    Jump near if sign (SF=1). Not supported in 64-
                                                                     bit mode.




Opcode                  Instruction                Op/     64-Bit   Compat/ Description
                                                   En      Mode     Leg Mode
0F 88 cd                JS rel32                   D       Valid    Valid       Jump near if sign (SF=1).
0F 84 cw                JZ rel16                   D       N.S.     Valid       Jump near if 0 (ZF=1). Not supported in 64-bit
                                                                                mode.
0F 84 cd                JZ rel32                   D       Valid    Valid       Jump near if 0 (ZF=1).



                                             Instruction Operand Encoding
   Op/En            Operand 1                  Operand 2                    Operand 3                        Operand 4
     D                Offset                      NA                           NA                                NA

Description
Checks the state of one or more of the status flags in the EFLAGS register (CF, OF, PF, SF, and ZF) and, if the flags
are in the specified state (condition), performs a jump to the target instruction specified by the destination
operand. A condition code (cc) is associated with each instruction to indicate the condition being tested for. If the
condition is not satisfied, the jump is not performed and execution continues with the instruction following the Jcc
instruction.
The target instruction is specified with a relative offset (a signed offset relative to the current value of the instruc-
tion pointer in the EIP register). A relative offset (rel8, rel16, or rel32) is generally specified as a label in assembly
code, but at the machine code level, it is encoded as a signed, 8-bit or 32-bit immediate value, which is added to
the instruction pointer. Instruction coding is most efficient for offsets of -128 to +127. If the operand-size attribute
is 16, the upper two bytes of the EIP register are cleared, resulting in a maximum instruction pointer size of 16 bits.
The conditions for each Jcc mnemonic are given in the "Description" column of the table on the preceding page. The
terms "less" and "greater" are used for comparisons of signed integers and the terms "above" and "below" are used
for unsigned integers.
Because a particular state of the status flags can sometimes be interpreted in two ways, two mnemonics are
defined for some opcodes. For example, the JA (jump if above) instruction and the JNBE (jump if not below or
equal) instruction are alternate mnemonics for the opcode 77H.
The Jcc instruction does not support far jumps (jumps to other code segments). When the target for the conditional
jump is in a different segment, use the opposite condition from the condition being tested for the Jcc instruction,
and then access the target with an unconditional far jump (JMP instruction) to the other segment. For example, the
following conditional far jump is illegal:
   JZ FARLABEL;
To accomplish this far jump, use the following two instructions:
   JNZ BEYOND;
   JMP FARLABEL;
   BEYOND:
The JRCXZ, JECXZ and JCXZ instructions differ from other Jcc instructions because they do not check status flags.
Instead, they check RCX, ECX or CX for 0. The register checked is determined by the address-size attribute. These
instructions are useful when used at the beginning of a loop that terminates with a conditional loop instruction
(such as LOOPNE). They can be used to prevent an instruction sequence from entering a loop when RCX, ECX or CX
is 0. This would cause the loop to execute 264, 232 or 64K times (not zero times).
All conditional jumps are converted to code fetches of one or two cache lines, regardless of jump address or cache-
ability.
In 64-bit mode, operand size is fixed at 64 bits. JMP Short is RIP = RIP + 8-bit offset sign extended to 64 bits. JMP
Near is RIP = RIP + 32-bit offset sign extended to 64-bits.





Operation
IF condition
    THEN
         tempEIP <- EIP + SignExtend(DEST);
         IF OperandSize = 16
              THEN tempEIP <- tempEIP AND 0000FFFFH;
         FI;
    IF tempEIP is not within code segment limit
         THEN #GP(0);
         ELSE EIP <- tempEIP
    FI;
FI;

Flags Affected
None

Protected Mode Exceptions
#GP(0)                     If the offset being jumped to is beyond the limits of the CS segment.
#UD                        If the LOCK prefix is used.

Real-Address Mode Exceptions
#GP                        If the offset being jumped to is beyond the limits of the CS segment or is outside of the effec-
                           tive address space from 0 to FFFFH. This condition can occur if a 32-bit address size override
                           prefix is used.
#UD                        If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
Same exceptions as in real address mode.

Compatibility Mode Exceptions
Same exceptions as in protected mode.

64-Bit Mode Exceptions
#GP(0)                     If the memory address is in a non-canonical form.
#UD                        If the LOCK prefix is used.






platform: x86_64
mnem: JMP
description:
JMP-Jump
 Opcode                 Instruction              Op/     64-Bit   Compat/ Description
                                                 En      Mode     Leg Mode
 EB cb                  JMP rel8                 D       Valid    Valid       Jump short, RIP = RIP + 8-bit displacement sign
                                                                              extended to 64-bits
 E9 cw                  JMP rel16                D       N.S.     Valid       Jump near, relative, displacement relative to
                                                                              next instruction. Not supported in 64-bit
                                                                              mode.
 E9 cd                  JMP rel32                D       Valid    Valid       Jump near, relative, RIP = RIP + 32-bit
                                                                              displacement sign extended to 64-bits
 FF /4                  JMP r/m16                M       N.S.     Valid       Jump near, absolute indirect, address = zero-
                                                                              extended r/m16. Not supported in 64-bit
                                                                              mode.
 FF /4                  JMP r/m32                M       N.S.     Valid       Jump near, absolute indirect, address given in
                                                                              r/m32. Not supported in 64-bit mode.
 FF /4                  JMP r/m64                M       Valid    N.E.        Jump near, absolute indirect, RIP = 64-Bit
                                                                              offset from register or memory
 EA cd                  JMP ptr16:16             D       Inv.     Valid       Jump far, absolute, address given in operand
 EA cp                  JMP ptr16:32             D       Inv.     Valid       Jump far, absolute, address given in operand
 FF /5                  JMP m16:16               D       Valid    Valid       Jump far, absolute indirect, address given in
                                                                              m16:16
 FF /5                  JMP m16:32               D       Valid    Valid       Jump far, absolute indirect, address given in
                                                                              m16:32.
 REX.W + FF /5          JMP m16:64               D       Valid    N.E.        Jump far, absolute indirect, address given in
                                                                              m16:64.



                                           Instruction Operand Encoding
    Op/En          Operand 1                 Operand 2                    Operand 3                     Operand 4
     D               Offset                     NA                           NA                             NA
     M           ModRM:r/m (r)                  NA                           NA                             NA

Description
Transfers program control to a different point in the instruction stream without recording return information. The
destination (target) operand specifies the address of the instruction being jumped to. This operand can be an
immediate value, a general-purpose register, or a memory location.
This instruction can be used to execute four different types of jumps:
.    Near jump-A jump to an instruction within the current code segment (the segment currently pointed to by the
     CS register), sometimes referred to as an intrasegment jump.
.    Short jump-A near jump where the jump range is limited to -128 to +127 from the current EIP value.
.    Far jump-A jump to an instruction located in a different segment than the current code segment but at the
     same privilege level, sometimes referred to as an intersegment jump.
.    Task switch-A jump to an instruction located in a different task.
A task switch can only be executed in protected mode (see Chapter 7, in the Intel 64 and IA-32 Architectures
Software Developer's Manual, Volume 3A, for information on performing task switches with the JMP instruction).
Near and Short Jumps. When executing a near jump, the processor jumps to the address (within the current code
segment) that is specified with the target operand. The target operand specifies either an absolute offset (that is
an offset from the base of the code segment) or a relative offset (a signed displacement relative to the current





value of the instruction pointer in the EIP register). A near jump to a relative offset of 8-bits (rel8) is referred to as
a short jump. The CS register is not changed on near and short jumps.
An absolute offset is specified indirectly in a general-purpose register or a memory location (r/m16 or r/m32). The
operand-size attribute determines the size of the target operand (16 or 32 bits). Absolute offsets are loaded
directly into the EIP register. If the operand-size attribute is 16, the upper two bytes of the EIP register are cleared,
resulting in a maximum instruction pointer size of 16 bits.
A relative offset (rel8, rel16, or rel32) is generally specified as a label in assembly code, but at the machine code
level, it is encoded as a signed 8-, 16-, or 32-bit immediate value. This value is added to the value in the EIP
register. (Here, the EIP register contains the address of the instruction following the JMP instruction). When using
relative offsets, the opcode (for short vs. near jumps) and the operand-size attribute (for near relative jumps)
determines the size of the target operand (8, 16, or 32 bits).
Far Jumps in Real-Address or Virtual-8086 Mode. When executing a far jump in real-address or virtual-8086 mode,
the processor jumps to the code segment and offset specified with the target operand. Here the target operand
specifies an absolute far address either directly with a pointer (ptr16:16 or ptr16:32) or indirectly with a memory
location (m16:16 or m16:32). With the pointer method, the segment and address of the called procedure is
encoded in the instruction, using a 4-byte (16-bit operand size) or 6-byte (32-bit operand size) far address imme-
diate. With the indirect method, the target operand specifies a memory location that contains a 4-byte (16-bit
operand size) or 6-byte (32-bit operand size) far address. The far address is loaded directly into the CS and EIP
registers. If the operand-size attribute is 16, the upper two bytes of the EIP register are cleared.
Far Jumps in Protected Mode. When the processor is operating in protected mode, the JMP instruction can be used
to perform the following three types of far jumps:
.   A far jump to a conforming or non-conforming code segment.
.   A far jump through a call gate.
.   A task switch.
(The JMP instruction cannot be used to perform inter-privilege-level far jumps.)
In protected mode, the processor always uses the segment selector part of the far address to access the corre-
sponding descriptor in the GDT or LDT. The descriptor type (code segment, call gate, task gate, or TSS) and access
rights determine the type of jump to be performed.
If the selected descriptor is for a code segment, a far jump to a code segment at the same privilege level is
performed. (If the selected code segment is at a different privilege level and the code segment is non-conforming,
a general-protection exception is generated.) A far jump to the same privilege level in protected mode is very
similar to one carried out in real-address or virtual-8086 mode. The target operand specifies an absolute far
address either directly with a pointer (ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or
m16:32). The operand-size attribute determines the size of the offset (16 or 32 bits) in the far address. The new
code segment selector and its descriptor are loaded into CS register, and the offset from the instruction is loaded
into the EIP register. Note that a call gate (described in the next paragraph) can also be used to perform far call to
a code segment at the same privilege level. Using this mechanism provides an extra level of indirection and is the
preferred method of making jumps between 16-bit and 32-bit code segments.
When executing a far jump through a call gate, the segment selector specified by the target operand identifies the
call gate. (The offset part of the target operand is ignored.) The processor then jumps to the code segment speci-
fied in the call gate descriptor and begins executing the instruction at the offset specified in the call gate. No stack
switch occurs. Here again, the target operand can specify the far address of the call gate either directly with a
pointer (ptr16:16 or ptr16:32) or indirectly with a memory location (m16:16 or m16:32).
Executing a task switch with the JMP instruction is somewhat similar to executing a jump through a call gate. Here
the target operand specifies the segment selector of the task gate for the task being switched to (and the offset
part of the target operand is ignored). The task gate in turn points to the TSS for the task, which contains the
segment selectors for the task's code and stack segments. The TSS also contains the EIP value for the next instruc-
tion that was to be executed before the task was suspended. This instruction pointer value is loaded into the EIP
register so that the task begins executing again at this next instruction.
The JMP instruction can also specify the segment selector of the TSS directly, which eliminates the indirection of the
task gate. See Chapter 7 in Intel 64 and IA-32 Architectures Software Developer's Manual, Volume 3A, for
detailed information on the mechanics of a task switch.




Note that when you execute at task switch with a JMP instruction, the nested task flag (NT) is not set in the EFLAGS
register and the new TSS's previous task link field is not loaded with the old task's TSS selector. A return to the
previous task can thus not be carried out by executing the IRET instruction. Switching tasks with the JMP instruc-
tion differs in this regard from the CALL instruction which does set the NT flag and save the previous task link infor-
mation, allowing a return to the calling task with an IRET instruction.
In 64-Bit Mode - The instruction's operation size is fixed at 64 bits. If a selector points to a gate, then RIP equals
the 64-bit displacement taken from gate; else RIP equals the zero-extended offset from the far pointer referenced
in the instruction.
See the summary chart at the beginning of this section for encoding data and limits.

Operation
IF near jump
    IF 64-bit Mode
          THEN
               IF near relative jump
                THEN
                    tempRIP <- RIP + DEST; (* RIP is instruction following JMP instruction*)
                ELSE (* Near absolute jump *)
                    tempRIP <- DEST;
               FI;
          ELSE
               IF near relative jump
                THEN
                    tempEIP <- EIP + DEST; (* EIP is instruction following JMP instruction*)
                ELSE (* Near absolute jump *)
                    tempEIP <- DEST;
               FI;
    FI;
    IF (IA32_EFER.LMA = 0 or target mode = Compatibility mode)
    and tempEIP outside code segment limit
          THEN #GP(0); FI
    IF 64-bit mode and tempRIP is not canonical
          THEN #GP(0);
    FI;
    IF OperandSize = 32
          THEN
               EIP <- tempEIP;
          ELSE
               IF OperandSize = 16
                    THEN (* OperandSize = 16 *)
                         EIP <- tempEIP AND 0000FFFFH;
                     ELSE (* OperandSize = 64)
                         RIP <- tempRIP;
               FI;
     FI;
FI;
IF far jump and (PE = 0 or (PE = 1 AND VM = 1)) (* Real-address or virtual-8086 mode *)
     THEN
          tempEIP <- DEST(Offset); (* DEST is ptr16:32 or [m16:32] *)
          IF tempEIP is beyond code segment limit
               THEN #GP(0); FI;
          CS <- DEST(segment selector); (* DEST is ptr16:32 or [m16:32] *)
          IF OperandSize = 32



             THEN
                EIP <- tempEIP; (* DEST is ptr16:32 or [m16:32] *)
             ELSE (* OperandSize = 16 *)
                EIP <- tempEIP AND 0000FFFFH; (* Clear upper 16 bits *)
           FI;
FI;
IF far jump and (PE = 1 and VM = 0)
(* IA-32e mode or protected mode, not virtual-8086 mode *)
     THEN
           IF effective address in the CS, DS, ES, FS, GS, or SS segment is illegal
          or segment selector in target operand NULL
                     THEN #GP(0); FI;
           IF segment selector index not within descriptor table limits
                THEN #GP(new selector); FI;
          Read type and access rights of segment descriptor;
          IF (EFER.LMA = 0)
                THEN
                     IF segment type is not a conforming or nonconforming code
                     segment, call gate, task gate, or TSS
                           THEN #GP(segment selector); FI;
                ELSE
                     IF segment type is not a conforming or nonconforming code segment
                     call gate
                           THEN #GP(segment selector); FI;
          FI;
          Depending on type and access rights:
                GO TO CONFORMING-CODE-SEGMENT;
                GO TO NONCONFORMING-CODE-SEGMENT;
                GO TO CALL-GATE;
                GO TO TASK-GATE;
                GO TO TASK-STATE-SEGMENT;
     ELSE
           #GP(segment selector);
FI;
CONFORMING-CODE-SEGMENT:
    IF L-Bit = 1 and D-BIT = 1 and IA32_EFER.LMA = 1
          THEN GP(new code segment selector); FI;
     IF DPL > CPL
          THEN #GP(segment selector); FI;
     IF segment not present
          THEN #NP(segment selector); FI;
    tempEIP <- DEST(Offset);
    IF OperandSize = 16
           THEN tempEIP <- tempEIP AND 0000FFFFH;
    FI;
    IF (IA32_EFER.LMA = 0 or target mode = Compatibility mode) and
    tempEIP outside code segment limit
          THEN #GP(0); FI
    IF tempEIP is non-canonical
          THEN #GP(0); FI;
    CS <- DEST[segment selector]; (* Segment descriptor information also loaded *)
    CS(RPL) <- CPL
    EIP <- tempEIP;
END;



NONCONFORMING-CODE-SEGMENT:
   IF L-Bit = 1 and D-BIT = 1 and IA32_EFER.LMA = 1
         THEN GP(new code segment selector); FI;
   IF (RPL > CPL) OR (DPL != CPL)
         THEN #GP(code segment selector); FI;
   IF segment not present
         THEN #NP(segment selector); FI;
   tempEIP <- DEST(Offset);
   IF OperandSize = 16
         THEN tempEIP <- tempEIP AND 0000FFFFH; FI;
   IF (IA32_EFER.LMA = 0 OR target mode = Compatibility mode)
   and tempEIP outside code segment limit
         THEN #GP(0); FI
   IF tempEIP is non-canonical THEN #GP(0); FI;
   CS <- DEST[segment selector]; (* Segment descriptor information also loaded *)
   CS(RPL) <- CPL;
   EIP <- tempEIP;
END;

CALL-GATE:
   IF call gate DPL < CPL
   or call gate DPL < call gate segment-selector RPL
              THEN #GP(call gate selector); FI;
   IF call gate not present
         THEN #NP(call gate selector); FI;
   IF call gate code-segment selector is NULL
         THEN #GP(0); FI;
   IF call gate code-segment selector index outside descriptor table limits
         THEN #GP(code segment selector); FI;
   Read code segment descriptor;
   IF code-segment segment descriptor does not indicate a code segment
   or code-segment segment descriptor is conforming and DPL > CPL
   or code-segment segment descriptor is non-conforming and DPL != CPL
              THEN #GP(code segment selector); FI;
   IF IA32_EFER.LMA = 1 and (code-segment descriptor is not a 64-bit code segment
   or code-segment segment descriptor has both L-Bit and D-bit set)
              THEN #GP(code segment selector); FI;
   IF code segment is not present
         THEN #NP(code-segment selector); FI;
    IF instruction pointer is not within code-segment limit
         THEN #GP(0); FI;
    tempEIP <- DEST(Offset);
    IF GateSize = 16
          THEN tempEIP <- tempEIP AND 0000FFFFH; FI;
   IF (IA32_EFER.LMA = 0 OR target mode = Compatibility mode) AND tempEIP
   outside code segment limit
         THEN #GP(0); FI
   CS <- DEST[SegmentSelector); (* Segment descriptor information also loaded *)
   CS(RPL) <- CPL;
   EIP <- tempEIP;
END;
TASK-GATE:
   IF task gate DPL < CPL
   or task gate DPL < task gate segment-selector RPL



         THEN #GP(task gate selector); FI;
   IF task gate not present
         THEN #NP(gate selector); FI;
   Read the TSS segment selector in the task-gate descriptor;
   IF TSS segment selector local/global bit is set to local
   or index not within GDT limits
   or TSS descriptor specifies that the TSS is busy
         THEN #GP(TSS selector); FI;
    IF TSS not present
         THEN #NP(TSS selector); FI;
    SWITCH-TASKS to TSS;
    IF EIP not within code segment limit
         THEN #GP(0); FI;
END;
TASK-STATE-SEGMENT:
   IF TSS DPL < CPL
   or TSS DPL < TSS segment-selector RPL
   or TSS descriptor indicates TSS not available
         THEN #GP(TSS selector); FI;
   IF TSS is not present
         THEN #NP(TSS selector); FI;
   SWITCH-TASKS to TSS;
   IF EIP not within code segment limit
         THEN #GP(0); FI;
END;

Flags Affected
All flags are affected if a task switch occurs; no flags are affected if a task switch does not occur.

Protected Mode Exceptions
#GP(0)                 If offset in target operand, call gate, or TSS is beyond the code segment limits.
                       If the segment selector in the destination operand, call gate, task gate, or TSS is NULL.
                       If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                       If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment
                       selector.
#GP(selector)          If the segment selector index is outside descriptor table limits.
                       If the segment descriptor pointed to by the segment selector in the destination operand is not
                       for a conforming-code segment, nonconforming-code segment, call gate, task gate, or task
                       state segment.
                       If the DPL for a nonconforming-code segment is not equal to the CPL
                       (When not using a call gate.) If the RPL for the segment's segment selector is greater than the
                       CPL.
                       If the DPL for a conforming-code segment is greater than the CPL.
                       If the DPL from a call-gate, task-gate, or TSS segment descriptor is less than the CPL or than
                       the RPL of the call-gate, task-gate, or TSS's segment selector.
                       If the segment descriptor for selector in a call gate does not indicate it is a code segment.
                       If the segment descriptor for the segment selector in a task gate does not indicate an available
                       TSS.
                       If the segment selector for a TSS has its local/global bit set for local.
                       If a TSS segment descriptor specifies that the TSS is busy or not available.
#SS(0)                 If a memory operand effective address is outside the SS segment limit.




#NP (selector)      If the code segment being accessed is not present.
                    If call gate, task gate, or TSS not present.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made while the
                    current privilege level is 3. (Only occurs when fetching target from memory.)
#UD                 If the LOCK prefix is used.

Real-Address Mode Exceptions
#GP                 If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
                    If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS                 If a memory operand effective address is outside the SS segment limit.
#UD                 If the LOCK prefix is used.

Virtual-8086 Mode Exceptions
#GP(0)              If the target operand is beyond the code segment limits.
                    If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)              If a memory operand effective address is outside the SS segment limit.
#PF(fault-code)     If a page fault occurs.
#AC(0)              If alignment checking is enabled and an unaligned memory reference is made. (Only occurs
                    when fetching target from memory.)
#UD                 If the LOCK prefix is used.

Compatibility Mode Exceptions
Same as 64-bit mode exceptions.

64-Bit Mode Exceptions
#GP(0)              If a memory address is non-canonical.
                    If target offset in destination operand is non-canonical.
                    If target offset in destination operand is beyond the new code segment limit.
                    If the segment selector in the destination operand is NULL.
                    If the code segment selector in the 64-bit gate is NULL.
#GP(selector)       If the code segment or 64-bit call gate is outside descriptor table limits.
                    If the code segment or 64-bit call gate overlaps non-canonical space.
                    If the segment descriptor from a 64-bit call gate is in non-canonical space.
                    If the segment descriptor pointed to by the segment selector in the destination operand is not
                    for a conforming-code segment, nonconforming-code segment, 64-bit call gate.
                    If the segment descriptor pointed to by the segment selector in the destination operand is a
                    code segment, and has both the D-bit and the L-bit set.
                    If the DPL for a nonconforming-code segment is not equal to the CPL, or the RPL for the
                    segment's segment selector is greater than the CPL.
                    If the DPL for a conforming-code segment is greater than the CPL.
                    If the DPL from a 64-bit call-gate is less than the CPL or than the RPL of the 64-bit call-gate.
                    If the upper type field of a 64-bit call gate is not 0x0.
                    If the segment selector from a 64-bit call gate is beyond the descriptor table limits.
                    If the code segment descriptor pointed to by the selector in the 64-bit gate doesn't have the L-
                    bit set and the D-bit clear.
                    If the segment descriptor for a segment selector from the 64-bit call gate does not indicate it
                    is a code segment.
                    If the code segment is non-conforming and CPL != DPL.



                  If the code segment is confirming and CPL < DPL.
#NP(selector)     If a code segment or 64-bit call gate is not present.
#UD               (64-bit mode only) If a far jump is direct to an absolute address in memory.
                  If the LOCK prefix is used.
#PF(fault-code)   If a page fault occurs.
#AC(0)            If alignment checking is enabled and an unaligned memory reference is made while the
                  current privilege level is 3.






platform: x86_64
mnem: KADDW
description:
KADDW/KADDB/KADDQ/KADDD-ADD Two Masks
 Opcode/                               Op/En    64/32      CPUID      Description
 Instruction                                    bit Mode   Feature
                                                Support    Flag
 VEX.L1.0F.W0 4A /r                    RVR      V/V        AVX512DQ   Add 16 bits masks in k2 and k3 and place result in k1.
 KADDW k1, k2, k3
 VEX.L1.66.0F.W0 4A /r                 RVR      V/V        AVX512DQ   Add 8 bits masks in k2 and k3 and place result in k1.
 KADDB k1, k2, k3
 VEX.L1.0F.W1 4A /r                    RVR      V/V        AVX512BW   Add 64 bits masks in k2 and k3 and place result in k1.
 KADDQ k1, k2, k3
 VEX.L1.66.0F.W1 4A /r                 RVR      V/V        AVX512BW   Add 32 bits masks in k2 and k3 and place result in k1.
 KADDD k1, k2, k3



                                               Instruction Operand Encoding
        Op/En             Operand 1                Operand 2                                Operand 3
        RVR              ModRM:reg (w)            VEX.1vvv (r)                ModRM:r/m (r, ModRM:[7:6] must be 11b)

Description
Adds the vector mask k2 and the vector mask k3, and writes the result into vector mask k1.

Operation
KADDW
DEST[15:0] <- SRC1[15:0] + SRC2[15:0]
DEST[MAX_KL-1:16] <- 0

KADDB
DEST[7:0] <- SRC1[7:0] + SRC2[7:0]
DEST[MAX_KL-1:8] <- 0

KADDQ
DEST[63:0] <- SRC1[63:0] + SRC2[63:0]
DEST[MAX_KL-1:64] <- 0

KADDD
DEST[31:0] <- SRC1[31:0] + SRC2[31:0]
DEST[MAX_KL-1:32] <- 0

Intel C/C++ Compiler Intrinsic Equivalent

SIMD Floating-Point Exceptions
None

Other Exceptions
See Exceptions Type K20.






platform: x86_64
mnem: KANDW
description:
KANDW/KANDB/KANDQ/KANDD-Bitwise Logical AND Masks
 Opcode/                        Op/En     64/32       CPUID        Description
 Instruction                              bit Mode    Feature
                                          Support     Flag
 VEX.NDS.L1.0F.W0 41 /r         RVR       V/V         AVX512F      Bitwise AND 16 bits masks k2 and k3 and place result in k1.
 KANDW k1, k2, k3
 VEX.L1.66.0F.W0 41 /r          RVR       V/V         AVX512DQ     Bitwise AND 8 bits masks k2 and k3 and place result in k1.
 KANDB k1, k2, k3
 VEX.L1.0F.W1 41 /r             RVR       V/V         AVX512BW     Bitwise AND 64 bits masks k2 and k3 and place result in k1.
 KANDQ k1, k2, k3
 VEX.L1.66.0F.W1 41 /r          RVR       V/V         AVX512BW     Bitwise AND 32 bits masks k2 and k3 and place result in k1.
 KANDD k1, k2, k3



                                                Instruction Operand Encoding
    Op/En                  Operand 1                         Operand 2                               Operand 3
     RVR                  ModRM:reg (w)                     VEX.1vvv (r)             ModRM:r/m (r, ModRM:[7:6] must be 11b)

Description
Performs a bitwise AND between the vector mask k2 and the vector mask k3, and writes the result into vector mask
k1.

Operation
KANDW
DEST[15:0] <- SRC1[15:0] BITWISE AND SRC2[15:0]
DEST[MAX_KL-1:16] <- 0

KANDB
DEST[7:0] <- SRC1[7:0] BITWISE AND SRC2[7:0]
DEST[MAX_KL-1:8] <- 0


KANDQ
DEST[63:0] <- SRC1[63:0] BITWISE AND SRC2[63:0]
DEST[MAX_KL-1:64] <- 0

KANDD
DEST[31:0] <- SRC1[31:0] BITWISE AND SRC2[31:0]
DEST[MAX_KL-1:32] <- 0

Intel C/C++ Compiler Intrinsic Equivalent
KANDW __mmask16 _mm512_kand(__mmask16 a, __mmask16 b);

Flags Affected
None

SIMD Floating-Point Exceptions
None

Other Exceptions
See Exceptions Type K20.






platform: x86_64
mnem: KANDNW
description:
KANDNW/KANDNB/KANDNQ/KANDND-Bitwise Logical AND NOT Masks
 Opcode/                      Op/En       64/32      CPUID        Description
 Instruction                              bit Mode   Feature
                                          Support    Flag
 VEX.NDS.L1.0F.W0 42 /r       RVR         V/V        AVX512F      Bitwise AND NOT 16 bits masks k2 and k3 and place result in
 KANDNW k1, k2, k3                                                k1.
 VEX.L1.66.0F.W0 42 /r        RVR         V/V        AVX512DQ     Bitwise AND NOT 8 bits masks k1 and k2 and place result in k1.
 KANDNB k1, k2, k3
 VEX.L1.0F.W1 42 /r           RVR         V/V        AVX512BW     Bitwise AND NOT 64 bits masks k2 and k3 and place result in
 KANDNQ k1, k2, k3                                                k1.
 VEX.L1.66.0F.W1 42 /r        RVR         V/V        AVX512BW     Bitwise AND NOT 32 bits masks k2 and k3 and place result in
 KANDND k1, k2, k3                                                k1.



                                                 Instruction Operand Encoding
    Op/En                  Operand 1                            Operand 2                              Operand 3
     RVR                  ModRM:reg (w)                        VEX.1vvv (r)             ModRM:r/m (r, ModRM:[7:6] must be 11b)

Description
Performs a bitwise AND NOT between the vector mask k2 and the vector mask k3, and writes the result into vector
mask k1.

Operation
KANDNW
DEST[15:0] <- (BITWISE NOT SRC1[15:0]) BITWISE AND SRC2[15:0]
DEST[MAX_KL-1:16] <- 0

KANDNB
DEST[7:0] <- (BITWISE NOT SRC1[7:0]) BITWISE AND SRC2[7:0]
DEST[MAX_KL-1:8] <- 0

KANDNQ
DEST[63:0] <- (BITWISE NOT SRC1[63:0]) BITWISE AND SRC2[63:0]
DEST[MAX_KL-1:64] <- 0

KANDND
DEST[31:0] <- (BITWISE NOT SRC1[31:0]) BITWISE AND SRC2[31:0]
DEST[MAX_KL-1:32] <- 0

Intel C/C++ Compiler Intrinsic Equivalent
KANDNW __mmask16 _mm512_kandn(__mmask16 a, __mmask16 b);

Flags Affected
None

SIMD Floating-Point Exceptions
None

Other Exceptions
See Exceptions Type K20.






platform: x86_64
mnem: KMOVW
description:
KMOVW/KMOVB/KMOVQ/KMOVD-Move from and to Mask Registers
 Opcode/                        Op/En     64/32        CPUID       Description
 Instruction                              bit Mode     Feature
                                          Support      Flag
 VEX.L0.0F.W0 90 /r             RM        V/V          AVX512F     Move 16 bits mask from k2/m16 and store the result in k1.
 KMOVW k1, k2/m16
 VEX.L0.66.0F.W0 90 /r          RM        V/V          AVX512DQ    Move 8 bits mask from k2/m8 and store the result in k1.
 KMOVB k1, k2/m8
 VEX.L0.0F.W1 90 /r             RM        V/V          AVX512BW    Move 64 bits mask from k2/m64 and store the result in k1.
 KMOVQ k1, k2/m64
 VEX.L0.66.0F.W1 90 /r          RM        V/V          AVX512BW    Move 32 bits mask from k2/m32 and store the result in k1.
 KMOVD k1, k2/m32
 VEX.L0.0F.W0 91 /r             MR        V/V          AVX512F     Move 16 bits mask from k1 and store the result in m16.
 KMOVW m16, k1
 VEX.L0.66.0F.W0 91 /r          MR        V/V          AVX512DQ    Move 8 bits mask from k1 and store the result in m8.
 KMOVB m8, k1
 VEX.L0.0F.W1 91 /r             MR        V/V          AVX512BW    Move 64 bits mask from k1 and store the result in m64.
 KMOVQ m64, k1
 VEX.L0.66.0F.W1 91 /r          MR        V/V          AVX512BW    Move 32 bits mask from k1 and store the result in m32.
 KMOVD m32, k1
 VEX.L0.0F.W0 92 /r             RR        V/V          AVX512F     Move 16 bits mask from r32 to k1.
 KMOVW k1, r32
 VEX.L0.66.0F.W0 92 /r          RR        V/V          AVX512DQ    Move 8 bits mask from r32 to k1.
 KMOVB k1, r32
 VEX.L0.F2.0F.W1 92 /r          RR        V/I          AVX512BW    Move 64 bits mask from r64 to k1.
 KMOVQ k1, r64
 VEX.L0.F2.0F.W0 92 /r          RR        V/V          AVX512BW    Move 32 bits mask from r32 to k1.
 KMOVD k1, r32
 VEX.L0.0F.W0 93 /r             RR        V/V          AVX512F     Move 16 bits mask from k1 to r32.
 KMOVW r32, k1
 VEX.L0.66.0F.W0 93 /r          RR        V/V          AVX512DQ    Move 8 bits mask from k1 to r32.
 KMOVB r32, k1
 VEX.L0.F2.0F.W1 93 /r          RR        V/I          AVX512BW    Move 64 bits mask from k1 to r64.
 KMOVQ r64, k1
 VEX.L0.F2.0F.W0 93 /r          RR        V/V          AVX512BW    Move 32 bits mask from k1 to r32.
 KMOVD r32, k1



                                                Instruction Operand Encoding
     Op/En                           Operand 1                                            Operand 2
      RM                          ModRM:reg (w)                                          ModRM:r/m (r)
      MR            ModRM:r/m (w, ModRM:[7:6] must not be 11b)                           ModRM:reg (r)
      RR                          ModRM:reg (w)                            ModRM:r/m (r, ModRM:[7:6] must be 11b)

Description
Copies values from the source operand (second operand) to the destination operand (first operand). The source
and destination operands can be mask registers, memory location or general purpose. The instruction cannot be
used to transfer data between general purpose registers and or memory locations.
When moving to a mask register, the result is zero extended to MAX_KL size (i.e., 64 bits currently). When moving
to a general-purpose register (GPR), the result is zero-extended to the size of the destination. In 32-bit mode, the
default GPR destination's size is 32 bits. In 64-bit mode, the default GPR destination's size is 64 bits. Note that
REX.W cannot be used to modify the size of the general-purpose destination.




Operation
KMOVW
IF *destination is a memory location*
    DEST[15:0] <- SRC[15:0]
IF *destination is a mask register or a GPR *
    DEST <- ZeroExtension(SRC[15:0])

KMOVB
IF *destination is a memory location*
    DEST[7:0] <- SRC[7:0]
IF *destination is a mask register or a GPR *
    DEST <- ZeroExtension(SRC[7:0])

KMOVQ
IF *destination is a memory location or a GPR*
    DEST[63:0] <- SRC[63:0]
IF *destination is a mask register*
    DEST <- ZeroExtension(SRC[63:0])

KMOVD
IF *destination is a memory location*
    DEST[31:0] <- SRC[31:0]
IF *destination is a mask register or a GPR *
    DEST <- ZeroExtension(SRC[31:0])

Intel C/C++ Compiler Intrinsic Equivalent
KMOVW __mmask16 _mm512_kmov(__mmask16 a);

Flags Affected
None

SIMD Floating-Point Exceptions
None

Other Exceptions
Instructions with RR operand encoding See Exceptions Type K20.
Instructions with RM or MR operand encoding See Exceptions Type K21.






platform: x86_64
mnem: KNOTW
description:
KNOTW/KNOTB/KNOTQ/KNOTD-NOT Mask Register
 Opcode/                              Op/En      64/32      CPUID          Description
 Instruction                                     bit Mode   Feature Flag
                                                 Support
 VEX.L0.0F.W0 44 /r                   RR         V/V        AVX512F        Bitwise NOT of 16 bits mask k2.
 KNOTW k1, k2
 VEX.L0.66.0F.W0 44 /r                RR         V/V        AVX512DQ       Bitwise NOT of 8 bits mask k2.
 KNOTB k1, k2
 VEX.L0.0F.W1 44 /r                   RR         V/V        AVX512BW       Bitwise NOT of 64 bits mask k2.
 KNOTQ k1, k2
 VEX.L0.66.0F.W1 44 /r                RR         V/V        AVX512BW       Bitwise NOT of 32 bits mask k2.
 KNOTD k1, k2



                                              Instruction Operand Encoding
    Op/En                            Operand 1                                              Operand 2
       RR                          ModRM:reg (w)                             ModRM:r/m (r, ModRM:[7:6] must be 11b)

Description
Performs a bitwise NOT of vector mask k2 and writes the result into vector mask k1.

Operation
KNOTW
DEST[15:0] <- BITWISE NOT SRC[15:0]
DEST[MAX_KL-1:16] <- 0

KNOTB
DEST[7:0] <- BITWISE NOT SRC[7:0]
DEST[MAX_KL-1:8] <- 0

KNOTQ
DEST[63:0] <- BITWISE NOT SRC[63:0]
DEST[MAX_KL-1:64] <- 0

KNOTD
DEST[31:0] <- BITWISE NOT SRC[31:0]
DEST[MAX_KL-1:32] <- 0

Intel C/C++ Compiler Intrinsic Equivalent
KNOTW __mmask16 _mm512_knot(__mmask16 a);

Flags Affected
None

SIMD Floating-Point Exceptions
None

Other Exceptions
See Exceptions Type K20.






platform: x86_64
mnem: KORW
description:
KORW/KORB/KORQ/KORD-Bitwise Logical OR Masks
 Opcode/                         Op/En       64/32      CPUID        Description
 Instruction                                 bit Mode   Feature
                                             Support    Flag
 VEX.NDS.L1.0F.W0 45 /r          RVR         V/V        AVX512F      Bitwise OR 16 bits masks k2 and k3 and place result in k1.
 KORW k1, k2, k3
 VEX.L1.66.0F.W0 45 /r           RVR         V/V        AVX512DQ     Bitwise OR 8 bits masks k2 and k3 and place result in k1.
 KORB k1, k2, k3
 VEX.L1.0F.W1 45 /r              RVR         V/V        AVX512BW     Bitwise OR 64 bits masks k2 and k3 and place result in k1.
 KORQ k1, k2, k3
 VEX.L1.66.0F.W1 45 /r           RVR         V/V        AVX512BW     Bitwise OR 32 bits masks k2 and k3 and place result in k1.
 KORD k1, k2, k3



                                               Instruction Operand Encoding
    Op/En                  Operand 1                         Operand 2                               Operand 3
     RVR                  ModRM:reg (w)                     VEX.1vvv (r)               ModRM:r/m (r, ModRM:[7:6] must be 11b)

Description
Performs a bitwise OR between the vector mask k2 and the vector mask k3, and writes the result into vector mask
k1 (three-operand form).

Operation
KORW
DEST[15:0] <- SRC1[15:0] BITWISE OR SRC2[15:0]
DEST[MAX_KL-1:16] <- 0

KORB
DEST[7:0] <- SRC1[7:0] BITWISE OR SRC2[7:0]
DEST[MAX_KL-1:8] <- 0

KORQ
DEST[63:0] <- SRC1[63:0] BITWISE OR SRC2[63:0]
DEST[MAX_KL-1:64] <- 0

KORD
DEST[31:0] <- SRC1[31:0] BITWISE OR SRC2[31:0]
DEST[MAX_KL-1:32] <- 0

Intel C/C++ Compiler Intrinsic Equivalent
KORW __mmask16 _mm512_kor(__mmask16 a, __mmask16 b);

Flags Affected
None

SIMD Floating-Point Exceptions
None

Other Exceptions
See Exceptions Type K20.






platform: x86_64
mnem: KORTESTW
description:
KORTESTW/KORTESTB/KORTESTQ/KORTESTD-OR Masks And Set Flags
  Opcode/                 Op/   64/32         CPUID       Description
  Instruction             En    bit Mode      Feature
                                Support       Flag
  VEX.L0.0F.W0 98 /r      RR    V/V           AVX512F     Bitwise OR 16 bits masks k1 and k2 and update ZF and CF accordingly.
  KORTESTW k1, k2
  VEX.L0.66.0F.W0 98 /r   RR    V/V           AVX512DQ    Bitwise OR 8 bits masks k1 and k2 and update ZF and CF accordingly.
  KORTESTB k1, k2
  VEX.L0.0F.W1 98 /r      RR    V/V           AVX512BW    Bitwise OR 64 bits masks k1 and k2 and update ZF and CF accordingly.
  KORTESTQ k1, k2
  VEX.L0.66.0F.W1 98 /r   RR    V/V           AVX512BW    Bitwise OR 32 bits masks k1 and k2 and update ZF and CF accordingly.
  KORTESTD k1, k2



                                               Instruction Operand Encoding
      Op/En                        Operand 1                                                Operand 2
       RR                        ModRM:reg (w)                               ModRM:r/m (r, ModRM:[7:6] must be 11b)

Description
Performs a bitwise OR between the vector mask register k2, and the vector mask register k1, and sets CF and ZF
based on the operation result.
ZF flag is set if both sources are 0x0. CF is set if, after the OR operation is done, the operation result is all 1's.

Operation
KORTESTW
TMP[15:0] <- DEST[15:0] BITWISE OR SRC[15:0]
IF(TMP[15:0]=0)
    THEN ZF <- 1
    ELSE ZF <- 0
FI;
IF(TMP[15:0]=FFFFh)
    THEN CF <- 1
    ELSE CF <- 0
FI;

KORTESTB
TMP[7:0] <- DEST[7:0] BITWISE OR SRC[7:0]
IF(TMP[7:0]=0)
    THEN ZF <- 1
    ELSE ZF <- 0
FI;
IF(TMP[7:0]==FFh)
    THEN CF <- 1
    ELSE CF <- 0

FI;





KORTESTQ
TMP[63:0] <- DEST[63:0] BITWISE OR SRC[63:0]
IF(TMP[63:0]=0)
    THEN ZF <- 1
    ELSE ZF <- 0
FI;
IF(TMP[63:0]==FFFFFFFF_FFFFFFFFh)
    THEN CF <- 1
    ELSE CF <- 0
FI;

KORTESTD
TMP[31:0] <- DEST[31:0] BITWISE OR SRC[31:0]
IF(TMP[31:0]=0)
    THEN ZF <- 1
    ELSE ZF <- 0
FI;
IF(TMP[31:0]=FFFFFFFFh)
    THEN CF <- 1
    ELSE CF <- 0
FI;

Intel C/C++ Compiler Intrinsic Equivalent
KORTESTW __mmask16 _mm512_kortest[cz](__mmask16 a, __mmask16 b);

Flags Affected
The ZF flag is set if the result of OR-ing both sources is all 0s.
The CF flag is set if the result of OR-ing both sources is all 1s.
The OF, SF, AF, and PF flags are set to 0.

Other Exceptions
See Exceptions Type K20.






platform: x86_64
mnem: KSHIFTLW
description:
KSHIFTLW/KSHIFTLB/KSHIFTLQ/KSHIFTLD-Shift Left Mask Registers
  Opcode/                         Op/En      64/32        CPUID         Description
  Instruction                                bit Mode     Feature
                                             Support      Flag
  VEX.L0.66.0F3A.W1 32 /r         RRI        V/V          AVX512F       Shift left 16 bits in k2 by immediate and write result in k1.
  KSHIFTLW k1, k2, imm8
  VEX.L0.66.0F3A.W0 32 /r         RRI        V/V          AVX512DQ      Shift left 8 bits in k2 by immediate and write result in k1.
  KSHIFTLB k1, k2, imm8
  VEX.L0.66.0F3A.W1 33 /r         RRI        V/V          AVX512BW      Shift left 64 bits in k2 by immediate and write result in k1.
  KSHIFTLQ k1, k2, imm8
  VEX.L0.66.0F3A.W0 33 /r         RRI        V/V          AVX512BW      Shift left 32 bits in k2 by immediate and write result in k1.
  KSHIFTLD k1, k2, imm8



                                                 Instruction Operand Encoding
      Op/En                 Operand 1                             Operand 2                                  Operand 3
       RRI               ModRM:reg (w)              ModRM:r/m (r, ModRM:[7:6] must be 11b)                     Imm8

Description
Shifts 8/16/32/64 bits in the second operand (source operand) left by the count specified in immediate byte and
place the least significant 8/16/32/64 bits of the result in the destination operand. The higher bits of the destina-
tion are zero-extended. The destination is set to zero if the count value is greater than 7 (for byte shift), 15 (for
word shift), 31 (for doubleword shift) or 63 (for quadword shift).

Operation
KSHIFTLW
COUNT <- imm8[7:0]
DEST[MAX_KL-1:0] <- 0
IF COUNT <=15
    THEN DEST[15:0] <- SRC1[15:0] << COUNT;
FI;

KSHIFTLB
COUNT <- imm8[7:0]
DEST[MAX_KL-1:0] <- 0
IF COUNT <=7
        THEN    DEST[7:0] <- SRC1[7:0] << COUNT;
FI;

KSHIFTLQ
COUNT <- imm8[7:0]
DEST[MAX_KL-1:0] <- 0
IF COUNT <=63
        THEN    DEST[63:0] <- SRC1[63:0] << COUNT;
FI;





KSHIFTLD
COUNT <- imm8[7:0]
DEST[MAX_KL-1:0] <- 0
IF COUNT <=31
        THEN    DEST[31:0] <- SRC1[31:0] << COUNT;
FI;

Intel C/C++ Compiler Intrinsic Equivalent
Compiler auto generates KSHIFTLW when needed.

Flags Affected
None

SIMD Floating-Point Exceptions
None

Other Exceptions
See Exceptions Type K20.






platform: x86_64
mnem: KSHIFTRW
description:
KSHIFTRW/KSHIFTRB/KSHIFTRQ/KSHIFTRD-Shift Right Mask Registers
 Opcode/                          Op/En    64/32         CPUID         Description
 Instruction                               bit Mode      Feature
                                           Support       Flag
 VEX.L0.66.0F3A.W1 30 /r          RRI      V/V           AVX512F       Shift right 16 bits in k2 by immediate and write result in k1.
 KSHIFTRW k1, k2, imm8
 VEX.L0.66.0F3A.W0 30 /r          RRI      V/V           AVX512DQ      Shift right 8 bits in k2 by immediate and write result in k1.
 KSHIFTRB k1, k2, imm8
 VEX.L0.66.0F3A.W1 31 /r          RRI      V/V           AVX512BW      Shift right 64 bits in k2 by immediate and write result in k1.
 KSHIFTRQ k1, k2, imm8
 VEX.L0.66.0F3A.W0 31 /r          RRI      V/V           AVX512BW      Shift right 32 bits in k2 by immediate and write result in k1.
 KSHIFTRD k1, k2, imm8



                                                 Instruction Operand Encoding
    Op/En                  Operand 1                                Operand 2                                 Operand 3
     RRI                 ModRM:reg (w)                ModRM:r/m (r, ModRM:[7:6] must be 11b)                     Imm8

Description
Shifts 8/16/32/64 bits in the second operand (source operand) right by the count specified in immediate and place
the least significant 8/16/32/64 bits of the result in the destination operand. The higher bits of the destination are
zero-extended. The destination is set to zero if the count value is greater than 7 (for byte shift), 15 (for word shift),
31 (for doubleword shift) or 63 (for quadword shift).

Operation
KSHIFTRW
COUNT <- imm8[7:0]
DEST[MAX_KL-1:0] <- 0
IF COUNT <=15
    THEN DEST[15:0] <- SRC1[15:0] >> COUNT;
FI;

KSHIFTRB
COUNT <- imm8[7:0]
DEST[MAX_KL-1:0] <- 0
IF COUNT <=7
        THEN    DEST[7:0] <- SRC1[7:0] >> COUNT;
FI;

KSHIFTRQ
COUNT <- imm8[7:0]
DEST[MAX_KL-1:0] <- 0
IF COUNT <=63
        THEN    DEST[63:0] <- SRC1[63:0] >> COUNT;
FI;





KSHIFTRD
COUNT <- imm8[7:0]
DEST[MAX_KL-1:0] <- 0
IF COUNT <=31
        THEN    DEST[31:0] <- SRC1[31:0] >> COUNT;
FI;

Intel C/C++ Compiler Intrinsic Equivalent
Compiler auto generates KSHIFTRW when needed.

Flags Affected
None

SIMD Floating-Point Exceptions
None

Other Exceptions
See Exceptions Type K20.






