|
|
Operation
IF SRC = 0
THEN #DE; FI; (* Divide Error *)
IF OperandSize = 8 (* Word/Byte Operation *)
THEN
temp := AX / SRC;
IF temp > FFH
THEN #DE; (* Divide error *)
ELSE
AL := temp;
AH := AX MOD SRC;
FI;
ELSE IF OperandSize = 16 (* Doubleword/word operation *)
THEN
temp := DX:AX / SRC;
IF temp > FFFFH
THEN #DE; (* Divide error *)
ELSE
AX := temp;
DX := DX:AX MOD SRC;
FI;
FI;
ELSE IF Operandsize = 32 (* Quadword/doubleword operation *)
THEN
temp := EDX:EAX / SRC;
IF temp > FFFFFFFFH
THEN #DE; (* Divide error *)
ELSE
EAX := temp;
EDX := EDX:EAX MOD SRC;
FI;
FI;
ELSE IF 64-Bit Mode and Operandsize = 64 (* Doublequadword/quadword operation *)
THEN
temp := RDX:RAX / SRC;
IF temp > FFFFFFFFFFFFFFFFH
THEN #DE; (* Divide error *)
ELSE
RAX := temp;
RDX := RDX:RAX MOD SRC;
FI;
FI;
FI;
Flags Affected
The CF, OF, SF, ZF, AF, and PF flags are undefined.
DIV-Unsigned Divide
Vol. 2A
3-265
Protected Mode Exceptions
#DE
If the source operand (divisor) is 0
If the quotient is too large for the designated register.
#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.
#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.
If the quotient is too large for the designated register.
#GP
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.
#UD
If the LOCK prefix is used.
Virtual-8086 Mode Exceptions
#DE
If the source operand (divisor) is 0.
If the quotient is too large for the designated register.
#GP(0)
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.
#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.
DIV-Unsigned Divide
Vol. 2A
3-266
DIVPD-Divide Packed Double Precision Floating-Point Values
Opcode/
Op /
64/32 bit
CPUID Feature
Description
Instruction
En
Mode
Flag
Support
66 0F 5E /r
A
V/V
SSE2
Divide packed double precision floating-point
DIVPD xmm1, xmm2/m128
values in xmm1 by packed double precision
floating-point values in xmm2/mem.
VEX.128.66.0F.WIG 5E /r
B
V/V
AVX
Divide packed double precision floating-point
VDIVPD xmm1, xmm2, xmm3/m128
values in xmm2 by packed double precision
floating-point values in xmm3/mem.
VEX.256.66.0F.WIG 5E /r
B
V/V
AVX
Divide packed double precision floating-point
VDIVPD ymm1, ymm2, ymm3/m256
values in ymm2 by packed double precision
floating-point values in ymm3/mem.
EVEX.128.66.0F.W1 5E /r
C
V/V
(AVX512VL AND
Divide packed double precision floating-point
VDIVPD xmm1 {k1}{z}, xmm2,
AVX512F) OR
values in xmm2 by packed double precision
xmm3/m128/m64bcst
AVX10.1
floating-point values in xmm3/m128/m64bcst and
write results to xmm1 subject to writemask k1.
EVEX.256.66.0F.W1 5E /r
C
V/V
(AVX512VL AND
Divide packed double precision floating-point
VDIVPD ymm1 {k1}{z}, ymm2,
AVX512F) OR
values in ymm2 by packed double precision
ymm3/m256/m64bcst
AVX10.1
floating-point values in ymm3/m256/m64bcst and
write results to ymm1 subject to writemask k1.
EVEX.512.66.0F.W1 5E /r
C
V/V
AVX512F
Divide packed double precision floating-point
VDIVPD zmm1 {k1}{z}, zmm2,
OR AVX10.1
values in zmm2 by packed double precision
zmm3/m512/m64bcst{er}
floating-point values in zmm3/m512/m64bcst and
write results to zmm1 subject to writemask k1.
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:reg (r, w)
ModRM:r/m (r)
N/A
N/A
B
N/A
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
C
Full
ModRM:reg (w)
EVEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
Performs a SIMD divide of the double precision floating-point values in the first source operand by the floating-
point values in the second source operand (the third operand). Results are written to the destination operand (the
first operand).
EVEX encoded versions: The first source operand (the second operand) is a ZMM/YMM/XMM register. The second
source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector
broadcasted from a 64-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally
updated with writemask k1.
VEX.256 encoded version: The first source operand (the second 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. The upper
bits (MAXVL-1:256) of the corresponding destination are zeroed.
VEX.128 encoded version: The first source operand (the second operand) is a XMM register. The second source
operand can be a XMM register or a 128-bit memory location. The destination operand is a XMM register. The upper
bits (MAXVL-1:128) of the corresponding destination are zeroed.
128-bit Legacy SSE version: The second source operand (the second operand) can be an XMM register or an 128-
bit memory location. The destination is the same as the first source operand. The upper bits (MAXVL-1:128) of the
corresponding destination are unmodified.
DIVPD-Divide Packed Double Precision Floating-Point Values
Vol. 2A
3-267
Operation
VDIVPD (EVEX Encoded Versions)
(KL, VL) = (2, 128), (4, 256), (8, 512)
IF (VL = 512) AND (EVEX.b = 1) AND SRC2 *is a register*
THEN
SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC); ; refer to Table 15-4 in the Intel® 64 and IA-32 Architectures
Software Developer’s Manual, Volume 1
ELSE
SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);
FI;
FOR j := 0 TO KL-1
i := j * 64
IF k1[j] OR *no writemask*
THEN
IF (EVEX.b = 1) AND (SRC2 *is memory*)
THEN
DEST[i+63:i] := SRC1[i+63:i] / SRC2[63:0]
ELSE
DEST[i+63:i] := SRC1[i+63:i] / SRC2[i+63:i]
FI;
ELSE
IF *merging-masking*
; merging-masking
THEN *DEST[i+63:i] remains unchanged*
ELSE
; zeroing-masking
DEST[i+63:i] := 0
FI
FI;
ENDFOR
DEST[MAXVL-1:VL] := 0
VDIVPD (VEX.256 Encoded Version)
DEST[63:0] := SRC1[63:0] / SRC2[63:0]
DEST[127:64] := SRC1[127:64] / SRC2[127:64]
DEST[191:128] := SRC1[191:128] / SRC2[191:128]
DEST[255:192] := SRC1[255:192] / SRC2[255:192]
DEST[MAXVL-1:256] := 0;
VDIVPD (VEX.128 Encoded Version)
DEST[63:0] := SRC1[63:0] / SRC2[63:0]
DEST[127:64] := SRC1[127:64] / SRC2[127:64]
DEST[MAXVL-1:128] := 0;
DIVPD (128-bit Legacy SSE Version)
DEST[63:0] := SRC1[63:0] / SRC2[63:0]
DEST[127:64] := SRC1[127:64] / SRC2[127:64]
DEST[MAXVL-1:128] (Unmodified)
DIVPD-Divide Packed Double Precision Floating-Point Values
Vol. 2A
3-268
Intel C/C++ Compiler Intrinsic Equivalent
VDIVPD __m512d _mm512_div_pd( __m512d a, __m512d b);
VDIVPD __m512d _mm512_mask_div_pd(__m512d s, __mmask8 k, __m512d a, __m512d b);
VDIVPD __m512d _mm512_maskz_div_pd( __mmask8 k, __m512d a, __m512d b);
VDIVPD __m256d _mm256_mask_div_pd(__m256d s, __mmask8 k, __m256d a, __m256d b);
VDIVPD __m256d _mm256_maskz_div_pd( __mmask8 k, __m256d a, __m256d b);
VDIVPD __m128d _mm_mask_div_pd(__m128d s, __mmask8 k, __m128d a, __m128d b);
VDIVPD __m128d _mm_maskz_div_pd( __mmask8 k, __m128d a, __m128d b);
VDIVPD __m512d _mm512_div_round_pd( __m512d a, __m512d b, int);
VDIVPD __m512d _mm512_mask_div_round_pd(__m512d s, __mmask8 k, __m512d a, __m512d b, int);
VDIVPD __m512d _mm512_maskz_div_round_pd( __mmask8 k, __m512d a, __m512d b, int);
VDIVPD __m256d _mm256_div_pd (__m256d a, __m256d b);
DIVPD __m128d _mm_div_pd (__m128d a, __m128d b);
SIMD Floating-Point Exceptions
Overflow, Underflow, Invalid, Divide-by-Zero, Precision, Denormal.
Other Exceptions
VEX-encoded instructions, see Table 2-19, “Type 2 Class Exception Conditions.”
EVEX-encoded instructions, see Table 2-48, “Type E2 Class Exception Conditions.”
DIVPD-Divide Packed Double Precision Floating-Point Values
Vol. 2A
3-269
DIVPS-Divide Packed Single Precision Floating-Point Values
Opcode/
Op /
64/32 bit
CPUID Feature
Description
Instruction
En
Mode
Flag
Support
NP 0F 5E /r
A
V/V
SSE
Divide packed single precision floating-point values
DIVPS xmm1, xmm2/m128
in xmm1 by packed single precision floating-point
values in xmm2/mem.
VEX.128.0F.WIG 5E /r
B
V/V
AVX
Divide packed single precision floating-point values
VDIVPS xmm1, xmm2, xmm3/m128
in xmm2 by packed single precision floating-point
values in xmm3/mem.
VEX.256.0F.WIG 5E /r
B
V/V
AVX
Divide packed single precision floating-point values
VDIVPS ymm1, ymm2, ymm3/m256
in ymm2 by packed single precision floating-point
values in ymm3/mem.
EVEX.128.0F.W0 5E /r
C
V/V
(AVX512VL AND
Divide packed single precision floating-point values
VDIVPS xmm1 {k1}{z}, xmm2,
AVX512F) OR
in xmm2 by packed single precision floating-point
xmm3/m128/m32bcst
AVX10.1
values in xmm3/m128/m32bcst and write results
to xmm1 subject to writemask k1.
EVEX.256.0F.W0 5E /r
C
V/V
(AVX512VL AND
Divide packed single precision floating-point values
VDIVPS ymm1 {k1}{z}, ymm2,
AVX512F) OR
in ymm2 by packed single precision floating-point
ymm3/m256/m32bcst
AVX10.1
values in ymm3/m256/m32bcst and write results
to ymm1 subject to writemask k1.
EVEX.512.0F.W0 5E /r
C
V/V
AVX512F
Divide packed single precision floating-point values
VDIVPS zmm1 {k1}{z}, zmm2,
OR AVX10.1
in zmm2 by packed single precision floating-point
zmm3/m512/m32bcst{er}
values in zmm3/m512/m32bcst and write results to
zmm1 subject to writemask k1.
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:reg (r, w)
ModRM:r/m (r)
N/A
N/A
B
N/A
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
C
Full
ModRM:reg (w)
EVEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
Performs a SIMD divide of the four, eight or sixteen packed single precision floating-point values in the first source
operand (the second operand) by the four, eight or sixteen packed single precision floating-point values in the
second source operand (the third operand). Results are written to the destination operand (the first operand).
EVEX encoded versions: The first source operand (the second operand) is a ZMM/YMM/XMM register. The second
source operand can be a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector
broadcasted from a 32-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally
updated with writemask k1.
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.
VEX.128 encoded version: The first source operand is a XMM register. The second source operand can be a XMM
register or a 128-bit memory location. The destination operand is a XMM register. The upper bits (MAXVL-1:128) of
the corresponding ZMM register destination are zeroed.
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 (MAXVL-1:128) of the corresponding
ZMM register destination are unmodified.
Operation
VDIVPS (EVEX Encoded Versions)
DIVPS-Divide Packed Single Precision Floating-Point Values
Vol. 2A
3-270
(KL, VL) = (4, 128), (8, 256), (16, 512)
IF (VL = 512) AND (EVEX.b = 1) AND SRC2 *is a register*
THEN
SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);
ELSE
SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);
FI;
FOR j := 0 TO KL-1
i := j * 32
IF k1[j] OR *no writemask*
THEN
IF (EVEX.b = 1) AND (SRC2 *is memory*)
THEN
DEST[i+31:i] := SRC1[i+31:i] / SRC2[31:0]
ELSE
DEST[i+31:i] := SRC1[i+31:i] / SRC2[i+31:i]
FI;
ELSE
IF *merging-masking*
; merging-masking
THEN *DEST[i+31:i] remains unchanged*
ELSE
; zeroing-masking
DEST[i+31:i] := 0
FI
FI;
ENDFOR
DEST[MAXVL-1:VL] := 0
VDIVPS (VEX.256 Encoded Version)
DEST[31:0] := SRC1[31:0] / SRC2[31:0]
DEST[63:32] := SRC1[63:32] / SRC2[63:32]
DEST[95:64] := SRC1[95:64] / SRC2[95:64]
DEST[127:96] := SRC1[127:96] / SRC2[127:96]
DEST[159:128] := SRC1[159:128] / SRC2[159:128]
DEST[191:160] := SRC1[191:160] / SRC2[191:160]
DEST[223:192] := SRC1[223:192] / SRC2[223:192]
DEST[255:224] := SRC1[255:224] / SRC2[255:224].
DEST[MAXVL-1:256] := 0;
VDIVPS (VEX.128 Encoded Version)
DEST[31:0] := SRC1[31:0] / SRC2[31:0]
DEST[63:32] := SRC1[63:32] / SRC2[63:32]
DEST[95:64] := SRC1[95:64] / SRC2[95:64]
DEST[127:96] := SRC1[127:96] / SRC2[127:96]
DEST[MAXVL-1:128] := 0
DIVPS-Divide Packed Single Precision Floating-Point Values
Vol. 2A
3-271
DIVPS (128-bit Legacy SSE Version)
DEST[31:0] := SRC1[31:0] / SRC2[31:0]
DEST[63:32] := SRC1[63:32] / SRC2[63:32]
DEST[95:64] := SRC1[95:64] / SRC2[95:64]
DEST[127:96] := SRC1[127:96] / SRC2[127:96]
DEST[MAXVL-1:128] (Unmodified)
Intel C/C++ Compiler Intrinsic Equivalent
VDIVPS __m512 _mm512_div_ps( __m512 a, __m512 b);
VDIVPS __m512 _mm512_mask_div_ps(__m512 s, __mmask16 k, __m512 a, __m512 b);
VDIVPS __m512 _mm512_maskz_div_ps(__mmask16 k, __m512 a, __m512 b);
VDIVPD __m256d _mm256_mask_div_pd(__m256d s, __mmask8 k, __m256d a, __m256d b);
VDIVPD __m256d _mm256_maskz_div_pd( __mmask8 k, __m256d a, __m256d b);
VDIVPD __m128d _mm_mask_div_pd(__m128d s, __mmask8 k, __m128d a, __m128d b);
VDIVPD __m128d _mm_maskz_div_pd( __mmask8 k, __m128d a, __m128d b);
VDIVPS __m512 _mm512_div_round_ps( __m512 a, __m512 b, int);
VDIVPS __m512 _mm512_mask_div_round_ps(__m512 s, __mmask16 k, __m512 a, __m512 b, int);
VDIVPS __m512 _mm512_maskz_div_round_ps(__mmask16 k, __m512 a, __m512 b, int);
VDIVPS __m256 _mm256_div_ps (__m256 a, __m256 b);
DIVPS __m128 _mm_div_ps (__m128 a, __m128 b);
SIMD Floating-Point Exceptions
Overflow, Underflow, Invalid, Divide-by-Zero, Precision, Denormal.
Other Exceptions
VEX-encoded instructions, see Table 2-19, “Type 2 Class Exception Conditions.”
EVEX-encoded instructions, see Table 2-48, “Type E2 Class Exception Conditions.”
DIVPS-Divide Packed Single Precision Floating-Point Values
Vol. 2A
3-272
DIVSD-Divide Scalar Double Precision Floating-Point Value
Opcode/
Op /
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature Flag
Support
F2 0F 5E /r
A
V/V
SSE2
Divide low double precision floating-point value in
DIVSD xmm1, xmm2/m64
xmm1 by low double precision floating-point value
in xmm2/m64.
VEX.LIG.F2.0F.WIG 5E /r
B
V/V
AVX
Divide low double precision floating-point value in
VDIVSD xmm1, xmm2, xmm3/m64
xmm2 by low double precision floating-point value
in xmm3/m64.
EVEX.LLIG.F2.0F.W1 5E /r
C
V/V
AVX512F
Divide low double precision floating-point value in
VDIVSD xmm1 {k1}{z}, xmm2,
OR AVX10.1
xmm2 by low double precision floating-point value
xmm3/m64{er}
in xmm3/m64.
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:reg (r, w)
ModRM:r/m (r)
N/A
N/A
B
N/A
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
C
Tuple1 Scalar
ModRM:reg (w)
EVEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
Divides the low double precision floating-point value in the first source operand by the low double precision
floating-point value in the second source operand, and stores the double precision floating-point result in the desti-
nation operand. The second source operand can be an XMM register or a 64-bit memory location. The first source
and destination are XMM registers.
128-bit Legacy SSE version: The first source operand and the destination operand are the same. Bits (MAXVL-
1:64) of the corresponding ZMM destination register remain unchanged.
VEX.128 encoded version: The first source operand is an xmm register encoded by VEX.vvvv. The quadword at bits
127:64 of the destination operand is copied from the corresponding quadword of the first source operand. Bits
(MAXVL-1:128) of the destination register are zeroed.
EVEX.128 encoded version: The first source operand is an xmm register encoded by EVEX.vvvv. The quadword
element of the destination operand at bits 127:64 are copied from the first source operand. Bits (MAXVL-1:128) of
the destination register are zeroed.
EVEX version: The low quadword element of the destination is updated according to the writemask.
Software should ensure VDIVSD is encoded with VEX.L=0. Encoding VDIVSD with VEX.L=1 may encounter unpre-
dictable behavior across different processor generations.
DIVSD-Divide Scalar Double Precision Floating-Point Value
Vol. 2A
3-273
Operation
VDIVSD (EVEX Encoded Version)
IF (EVEX.b = 1) AND SRC2 *is a register*
THEN
SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);
ELSE
SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);
FI;
IF k1[0] or *no writemask*
THEN
DEST[63:0] := SRC1[63:0] / SRC2[63:0]
ELSE
IF *merging-masking*
; merging-masking
THEN *DEST[63:0] remains unchanged*
ELSE
; zeroing-masking
THEN DEST[63:0] := 0
FI;
FI;
DEST[127:64] := SRC1[127:64]
DEST[MAXVL-1:128] := 0
VDIVSD (VEX.128 Encoded Version)
DEST[63:0] := SRC1[63:0] / SRC2[63:0]
DEST[127:64] := SRC1[127:64]
DEST[MAXVL-1:128] := 0
DIVSD (128-bit Legacy SSE Version)
DEST[63:0] := DEST[63:0] / SRC[63:0]
DEST[MAXVL-1:64] (Unmodified)
Intel C/C++ Compiler Intrinsic Equivalent
VDIVSD __m128d _mm_mask_div_sd(__m128d s, __mmask8 k, __m128d a, __m128d b);
VDIVSD __m128d _mm_maskz_div_sd( __mmask8 k, __m128d a, __m128d b);
VDIVSD __m128d _mm_div_round_sd( __m128d a, __m128d b, int);
VDIVSD __m128d _mm_mask_div_round_sd(__m128d s, __mmask8 k, __m128d a, __m128d b, int);
VDIVSD __m128d _mm_maskz_div_round_sd( __mmask8 k, __m128d a, __m128d b, int);
DIVSD __m128d _mm_div_sd (__m128d a, __m128d b);
SIMD Floating-Point Exceptions
Overflow, Underflow, Invalid, Divide-by-Zero, Precision, Denormal.
Other Exceptions
VEX-encoded instructions, see Table 2-20, “Type 3 Class Exception Conditions.”
EVEX-encoded instructions, see Table 2-49, “Type E3 Class Exception Conditions.”
DIVSD-Divide Scalar Double Precision Floating-Point Value
Vol. 2A
3-274
DIVSS-Divide Scalar Single Precision Floating-Point Values
Opcode/
Op /
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature Flag
Support
F3 0F 5E /r
A
V/V
SSE
Divide low single precision floating-point value in
DIVSS xmm1, xmm2/m32
xmm1 by low single precision floating-point value in
xmm2/m32.
VEX.LIG.F3.0F.WIG 5E /r
B
V/V
AVX
Divide low single precision floating-point value in
VDIVSS xmm1, xmm2, xmm3/m32
xmm2 by low single precision floating-point value in
xmm3/m32.
EVEX.LLIG.F3.0F.W0 5E /r
C
V/V
AVX512F
Divide low single precision floating-point value in
VDIVSS xmm1 {k1}{z}, xmm2,
OR AVX10.1
xmm2 by low single precision floating-point value in
xmm3/m32{er}
xmm3/m32.
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:reg (r, w)
ModRM:r/m (r)
N/A
N/A
B
N/A
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
C
Tuple1 Scalar
ModRM:reg (w)
EVEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
Divides the low single precision floating-point value in the first source operand by the low single precision floating-
point value in the second source operand, and stores the single precision floating-point result in the destination
operand. The second source operand can be an XMM register or a 32-bit memory location.
128-bit Legacy SSE version: The first source operand and the destination operand are the same. Bits (MAXVL-
1:32) of the corresponding YMM destination register remain unchanged.
VEX.128 encoded version: The first source operand is an xmm register encoded by VEX.vvvv. The three high-order
doublewords of the destination operand are copied from the first source operand. Bits (MAXVL-1:128) of the desti-
nation register are zeroed.
EVEX.128 encoded version: The first source operand is an xmm register encoded by EVEX.vvvv. The doubleword
elements of the destination operand at bits 127:32 are copied from the first source operand. Bits (MAXVL-1:128)
of the destination register are zeroed.
EVEX version: The low doubleword element of the destination is updated according to the writemask.
Software should ensure VDIVSS is encoded with VEX.L=0. Encoding VDIVSS with VEX.L=1 may encounter unpre-
dictable behavior across different processor generations.
DIVSS-Divide Scalar Single Precision Floating-Point Values
Vol. 2A
3-275
Operation
VDIVSS (EVEX Encoded Version)
IF (EVEX.b = 1) AND SRC2 *is a register*
THEN
SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);
ELSE
SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(MXCSR.RC);
FI;
IF k1[0] or *no writemask*
THEN
DEST[31:0] := SRC1[31:0] / SRC2[31:0]
ELSE
IF *merging-masking*
; merging-masking
THEN *DEST[31:0] remains unchanged*
ELSE
; zeroing-masking
THEN DEST[31:0] := 0
FI;
FI;
DEST[127:32] := SRC1[127:32]
DEST[MAXVL-1:128] := 0
VDIVSS (VEX.128 Encoded Version)
DEST[31:0] := SRC1[31:0] / SRC2[31:0]
DEST[127:32] := SRC1[127:32]
DEST[MAXVL-1:128] := 0
DIVSS (128-bit Legacy SSE Version)
DEST[31:0] := DEST[31:0] / SRC[31:0]
DEST[MAXVL-1:32] (Unmodified)
Intel C/C++ Compiler Intrinsic Equivalent
VDIVSS __m128 _mm_mask_div_ss(__m128 s, __mmask8 k, __m128 a, __m128 b);
VDIVSS __m128 _mm_maskz_div_ss( __mmask8 k, __m128 a, __m128 b);
VDIVSS __m128 _mm_div_round_ss( __m128 a, __m128 b, int);
VDIVSS __m128 _mm_mask_div_round_ss(__m128 s, __mmask8 k, __m128 a, __m128 b, int);
VDIVSS __m128 _mm_maskz_div_round_ss( __mmask8 k, __m128 a, __m128 b, int);
DIVSS __m128 _mm_div_ss(__m128 a, __m128 b);
SIMD Floating-Point Exceptions
Overflow, Underflow, Invalid, Divide-by-Zero, Precision, Denormal.
Other Exceptions
VEX-encoded instructions, see Table 2-20, “Type 3 Class Exception Conditions.”
EVEX-encoded instructions, see Table 2-49, “Type E3 Class Exception Conditions.”
DIVSS-Divide Scalar Single Precision Floating-Point Values
Vol. 2A
3-276
DPPD-Dot Product of Packed Double Precision Floating-Point Values
Opcode/
Op/
64/32-bit
CPUID
Description
Instruction
En
Mode
Feature
Flag
66 0F 3A 41 /r ib
RMI
V/V
SSE4_1
Selectively multiply packed double precision
floating-point values from xmm1 with packed
DPPD xmm1, xmm2/m128, imm8
double precision floating-point values from
xmm2, add and selectively store the packed
double precision floating-point values to
xmm1.
VEX.128.66.0F3A.WIG 41 /r ib
RVMI
V/V
AVX
Selectively multiply packed double precision
floating-point values from xmm2 with packed
VDPPD xmm1,xmm2, xmm3/m128, imm8
double precision floating-point values from
xmm3, add and selectively store the packed
double precision floating-point values to
xmm1.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RMI
ModRM:reg (r, w)
ModRM:r/m (r)
imm8
N/A
RVMI
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
imm8
Description
Conditionally multiplies the packed double precision floating-point values in the destination operand (first operand)
with the packed double precision floating-point values in the source (second operand) depending on a mask
extracted from bits [5:4] of the immediate operand (third operand). If a condition mask bit is zero, the corre-
sponding multiplication is replaced by a value of 0.0 in the manner described by Section 12.8.4 of Intel® 64 and
IA-32 Architectures Software Developer’s Manual, Volume 1.
The two resulting double precision values are summed into an intermediate result. The intermediate result is condi-
tionally broadcasted to the destination using a broadcast mask specified by bits [1:0] of the immediate byte.
If a broadcast mask bit is “1”, the intermediate result is copied to the corresponding qword element in the destina-
tion operand. If a broadcast mask bit is zero, the corresponding element in the destination is set to zero.
DPPD follows the NaN forwarding rules stated in the Software Developer’s Manual, vol. 1, table 4.7. These rules do
not cover horizontal prioritization of NaNs. Horizontal propagation of NaNs to the destination and the positioning of
those NaNs in the destination is implementation dependent. NaNs on the input sources or computationally gener-
ated NaNs will have at least one NaN propagated to the destination.
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 (MAXVL-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 (MAXVL-1:128) of the corresponding YMM register destination are
zeroed.
If VDPPD is encoded with VEX.L= 1, an attempt to execute the instruction encoded with VEX.L= 1 will cause an
#UD exception.
DPPD-Dot Product of Packed Double Precision Floating-Point Values
Vol. 2A
3-277
Operation
DP_primitive (SRC1, SRC2)
IF (imm8[4] = 1)
THEN Temp1[63:0] := DEST[63:0] * SRC[63:0]; // update SIMD exception flags
ELSE Temp1[63:0] := +0.0; FI;
IF (imm8[5] = 1)
THEN Temp1[127:64] := DEST[127:64] * SRC[127:64]; // update SIMD exception flags
ELSE Temp1[127:64] := +0.0; FI;
/* if unmasked exception reported, execute exception handler*/
Temp2[63:0] := Temp1[63:0] + Temp1[127:64]; // update SIMD exception flags
/* if unmasked exception reported, execute exception handler*/
IF (imm8[0] = 1)
THEN DEST[63:0] := Temp2[63:0];
ELSE DEST[63:0] := +0.0; FI;
IF (imm8[1] = 1)
THEN DEST[127:64] := Temp2[63:0];
ELSE DEST[127:64] := +0.0; FI;
DPPD (128-bit Legacy SSE Version)
DEST[127:0] := DP_Primitive(SRC1[127:0], SRC2[127:0]);
DEST[MAXVL-1:128] (Unmodified)
VDPPD (VEX.128 Encoded Version)
DEST[127:0] := DP_Primitive(SRC1[127:0], SRC2[127:0]);
DEST[MAXVL-1:128] := 0
Flags Affected
None.
Intel C/C++ Compiler Intrinsic Equivalent
DPPD __m128d _mm_dp_pd ( __m128d a, __m128d b, const int mask);
SIMD Floating-Point Exceptions
Overflow, Underflow, Invalid, Precision, Denormal.
Exceptions are determined separately for each add and multiply operation. Unmasked exceptions will leave the
destination untouched.
Other Exceptions
See Table 2-19, “Type 2 Class Exception Conditions,” additionally:
#UD
If VEX.L= 1.
DPPD-Dot Product of Packed Double Precision Floating-Point Values
Vol. 2A
3-278
DPPS-Dot Product of Packed Single Precision Floating-Point Values
Opcode/
Op/
64/32-bit
CPUID
Description
Instruction
En
Mode
Feature
Flag
66 0F 3A 40 /r ib
RMI
V/V
SSE4_1
Selectively multiply packed single precision floating-
point values from xmm1 with packed single precision
DPPS xmm1, xmm2/m128, imm8
floating-point values from xmm2, add and selectively
store the packed single precision floating-point values
or zero values to xmm1.
VEX.128.66.0F3A.WIG 40 /r ib
RVMI
V/V
AVX
Multiply packed single precision floating-point values
from xmm1 with packed single precision floating-point
VDPPS xmm1,xmm2, xmm3/m128, imm8
values from xmm2/mem selectively add and store to
xmm1.
VEX.256.66.0F3A.WIG 40 /r ib
RVMI
V/V
AVX
Multiply packed single precision floating-point values
from ymm2 with packed single precision floating-point
VDPPS ymm1, ymm2, ymm3/m256, imm8
values from ymm3/mem, selectively add pairs of
elements and store to ymm1.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RMI
ModRM:reg (r, w)
ModRM:r/m (r)
imm8
N/A
RVMI
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
imm8
Description
Conditionally multiplies the packed single precision floating-point values in the destination operand (first operand)
with the packed single precision floats in the source (second operand) depending on a mask extracted from the
high 4 bits of the immediate byte (third operand). If a condition mask bit in imm8[7:4] is zero, the corresponding
multiplication is replaced by a value of 0.0 in the manner described by Section 12.8.4 of Intel® 64 and IA-32 Archi-
tectures Software Developer’s Manual, Volume 1.
The four resulting single precision values are summed into an intermediate result. The intermediate result is condi-
tionally broadcasted to the destination using a broadcast mask specified by bits [3:0] of the immediate byte.
If a broadcast mask bit is “1”, the intermediate result is copied to the corresponding dword element in the destina-
tion operand. If a broadcast mask bit is zero, the corresponding element in the destination is set to zero.
DPPS follows the NaN forwarding rules stated in the Software Developer’s Manual, vol. 1, table 4.7. These rules do
not cover horizontal prioritization of NaNs. Horizontal propagation of NaNs to the destination and the positioning of
those NaNs in the destination is implementation dependent. NaNs on the input sources or computationally gener-
ated NaNs will have at least one NaN propagated to the destination.
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 (MAXVL-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 (MAXVL-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.
DPPS-Dot Product of Packed Single Precision Floating-Point Values
Vol. 2A
3-279
Operation
DP_primitive (SRC1, SRC2)
IF (imm8[4] = 1)
THEN Temp1[31:0] := DEST[31:0] * SRC[31:0]; // update SIMD exception flags
ELSE Temp1[31:0] := +0.0; FI;
IF (imm8[5] = 1)
THEN Temp1[63:32] := DEST[63:32] * SRC[63:32]; // update SIMD exception flags
ELSE Temp1[63:32] := +0.0; FI;
IF (imm8[6] = 1)
THEN Temp1[95:64] := DEST[95:64] * SRC[95:64]; // update SIMD exception flags
ELSE Temp1[95:64] := +0.0; FI;
IF (imm8[7] = 1)
THEN Temp1[127:96] := DEST[127:96] * SRC[127:96]; // update SIMD exception flags
ELSE Temp1[127:96] := +0.0; FI;
Temp2[31:0] := Temp1[31:0] + Temp1[63:32]; // update SIMD exception flags
/* if unmasked exception reported, execute exception handler*/
Temp3[31:0] := Temp1[95:64] + Temp1[127:96]; // update SIMD exception flags
/* if unmasked exception reported, execute exception handler*/
Temp4[31:0] := Temp2[31:0] + Temp3[31:0]; // update SIMD exception flags
/* if unmasked exception reported, execute exception handler*/
IF (imm8[0] = 1)
THEN DEST[31:0] := Temp4[31:0];
ELSE DEST[31:0] := +0.0; FI;
IF (imm8[1] = 1)
THEN DEST[63:32] := Temp4[31:0];
ELSE DEST[63:32] := +0.0; FI;
IF (imm8[2] = 1)
THEN DEST[95:64] := Temp4[31:0];
ELSE DEST[95:64] := +0.0; FI;
IF (imm8[3] = 1)
THEN DEST[127:96] := Temp4[31:0];
ELSE DEST[127:96] := +0.0; FI;
DPPS (128-bit Legacy SSE Version)
DEST[127:0] := DP_Primitive(SRC1[127:0], SRC2[127:0]);
DEST[MAXVL-1:128] (Unmodified)
VDPPS (VEX.128 Encoded Version)
DEST[127:0] := DP_Primitive(SRC1[127:0], SRC2[127:0]);
DEST[MAXVL-1:128] := 0
VDPPS (VEX.256 Encoded Version)
DEST[127:0] := DP_Primitive(SRC1[127:0], SRC2[127:0]);
DEST[255:128] := DP_Primitive(SRC1[255:128], SRC2[255:128]);
Flags Affected
None.
DPPS-Dot Product of Packed Single Precision Floating-Point Values
Vol. 2A
3-280
Intel C/C++ Compiler Intrinsic Equivalent
(V)DPPS __m128 _mm_dp_ps ( __m128 a, __m128 b, const int mask);
VDPPS __m256 _mm256_dp_ps ( __m256 a, __m256 b, const int mask);
SIMD Floating-Point Exceptions
Overflow, Underflow, Invalid, Precision, Denormal.
Exceptions are determined separately for each add and multiply operation, in the order of their execution.
Unmasked exceptions will leave the destination operands unchanged.
Other Exceptions
See Table 2-19, “Type 2 Class Exception Conditions.”
DPPS-Dot Product of Packed Single Precision Floating-Point Values
Vol. 2A
3-281
EMMS-Empty MMX Technology State
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
NP 0F 77
EMMS
ZO
Valid
Valid
Set the x87 FPU tag word to empty.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Sets the values of all the tags in the x87 FPU tag word to empty (all 1s). This operation marks the x87 FPU data
registers (which are aliased to the MMX technology registers) as available for use by x87 FPU floating-point instruc-
tions. (See Figure 8-7 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1, for the
format of the x87 FPU tag word.) All other MMX instructions (other than the EMMS instruction) set all the tags in
x87 FPU tag word to valid (all 0s).
The EMMS instruction must be used to clear the MMX technology state at the end of all MMX technology procedures
or subroutines and before calling other procedures or subroutines that may execute x87 floating-point instructions.
If a floating-point instruction loads one of the registers in the x87 FPU data register stack before the x87 FPU tag
word has been reset by the EMMS instruction, an x87 floating-point register stack overflow can occur that will
result in an x87 floating-point exception or incorrect result.
EMMS operation is the same in non-64-bit modes and 64-bit mode.
Operation
x87FPUTagWord := FFFFH;
Intel C/C++ Compiler Intrinsic Equivalent
void _mm_empty()
Flags Affected
None
Protected Mode Exceptions
#UD
If CR0.EM[bit 2] = 1.
#NM
If CR0.TS[bit 3] = 1.
#MF
If there is a pending 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.
EMMS-Empty MMX Technology State
Vol. 2A
3-282
ENCODEKEY128-Encode 128-Bit Key With Key Locker
Opcode/
Op/
64/32-bit
CPUID
Description
Instruction
En
Mode
Feature
Flag
F3 0F 38 FA 11:rrr:bbb
A
V/V
AESKLE
Wrap a 128-bit AES key from XMM0 into a key handle
ENCODEKEY128 r32, r32, <XMM0-2>,
and output handle in XMM0-2.
<XMM4-6>
Instruction Operand Encoding
Op/En
Tuple
Operand 1
Operand 2
Operand 3
Operands 4-5
Operands 6-7
A
N/A
ModRM:reg (w)
ModRM:r/m (r)
Implicit XMM0 (r, w)
Implicit XMM1-2 (w)
Implicit XMM4-6 (w)
Description
The ENCODEKEY1281 instruction wraps a 128-bit AES key from the implicit operand XMM0 into a key handle that
is then stored in the implicit destination operands XMM0-2.
The explicit source operand specifies handle restrictions, if any.
The explicit destination operand is populated with information on the source of the key and its attributes. XMM4
through XMM6 are reserved for future usages and software should not rely upon them being zeroed.
Operation
ENCODEKEY128
#GP (0) if a reserved bit2 in SRC[31:0] is set
InputKey[127:0] := XMM0;
KeyMetadata[2:0] = SRC[2:0];
KeyMetadata[23:3] = 0;
// Reserved for future usage
KeyMetadata[27:24] = 0;
// KeyType is AES-128 (value of 0)
KeyMetadata[127:28] = 0;
// Reserved for future usage
// KeyMetadata is the AAD input and InputKey is the Plaintext input for WrapKey128
Handle[383:0] := WrapKey128(InputKey[127:0], KeyMetadata[127:0], IWKey.Integrity Key[127:0], IWKey.Encryption Key[255:0]);
DEST[0] := IWKey.NoBackup;
DEST[4:1] := IWKey.KeySource[3:0];
DEST[31:5] = 0;
XMM0 := Handle[127:0];
// AAD
XMM1 := Handle[255:128]; // Integrity Tag
XMM2 := Handle[383:256]; // CipherText
XMM4 := 0;
// Reserved for future usage
XMM5 := 0;
// Reserved for future usage
XMM6 := 0;
// Reserved for future usage
RFLAGS.OF, SF, ZF, AF, PF, CF := 0;
Flags Affected
All arithmetic flags (OF, SF, ZF, AF, PF, CF) are cleared to 0. Although they are cleared for the currently defined oper-
ations, future extensions may report information in the flags.
1. Further details on Key Locker and usage of this instruction can be found here:
https://software.intel.com/content/www/us/en/develop/download/intel-key-locker-specification.html.
2. SRC[31:3] are currently reserved for future usages. SRC[2], which indicates a no-decrypt restriction, is reserved if
CPUID.19H:EAX[2] is 0. SRC[1], which indicates a no-encrypt restriction, is reserved if CPUID.19H:EAX[1] is 0. SRC[0], which indicates
a CPL0-only restriction, is reserved if CPUID.19H:EAX[0] is 0.
ENCODEKEY128-Encode 128-Bit Key With Key Locker
Vol. 2A
3-283
Intel C/C++ Compiler Intrinsic Equivalent
ENCODEKEY128 unsigned int _mm_encodekey128_u32(unsigned int htype, __m128i key, void* h);
Exceptions (All Operating Modes)
#GP
If reserved bit is set in source register value.
#UD
If the LOCK prefix is used.
If CPUID.07H.00H:ECX.KEY_LOCKER[23] = 0.
If CR4.KL = 0.
If CPUID.19H:EBX.AESKLE[0] = 0.
If CR0.EM = 1.
If CR4.OSFXSR = 0.
#NM
If CR0.TS = 1.
ENCODEKEY128-Encode 128-Bit Key With Key Locker
Vol. 2A
3-284
ENCODEKEY256-Encode 256-Bit Key With Key Locker
Opcode/
Op/
64/32-bit
CPUID
Description
Instruction
En
Mode
Feature
Flag
F3 0F 38 FB 11:rrr:bbb
A
V/V
AESKLE
Wrap a 256-bit AES key from XMM1:XMM0 into a key
ENCODEKEY256 r32, r32 <XMM0-6>
handle and store it in XMM0-3.
Instruction Operand Encoding
Op/En
Tuple
Operand 1
Operand 2
Operands 3-4
Operands 5-9
A
N/A
ModRM:reg (w)
ModRM:r/m (r)
Implicit XMM0-1 (r, w)
Implicit XMM2-6 (w)
Description
The ENCODEKEY2561 instruction wraps a 256-bit AES key from the implicit operand XMM1:XMM0 into a key handle
that is then stored in the implicit destination operands XMM0-3.
The explicit source operand is a general-purpose register and specifies what handle restrictions should be built into
the handle.
The explicit destination operand is populated with information on the source of the key and its attributes. XMM4
through XMM6 are reserved for future usages and software should not rely upon them being zeroed.
Operation
ENCODEKEY256
#GP (0) if a reserved bit2 in SRC[31:0] is set
InputKey[255:0] := XMM1:XMM0;
KeyMetadata[2:0] = SRC[2:0];
KeyMetadata[23:3] = 0;
// Reserved for future usage
KeyMetadata[27:24] = 1;
// KeyType is AES-256 (value of 1)
KeyMetadata[127:28] = 0; // Reserved for future usage
// KeyMetadata is the AAD input and InputKey is the Plaintext input for WrapKey256
Handle[511:0] := WrapKey256(InputKey[255:0], KeyMetadata[127:0], IWKey.Integrity Key[127:0], IWKey.Encryption Key[255:0]);
DEST[0] := IWKey.NoBackup;
DEST[4:1] := IWKey.KeySource[3:0];
DEST[31:5] = 0;
XMM0 := Handle[127:0];
// AAD
XMM1 := Handle[255:128]; // Integrity Tag
XMM2 := Handle[383:256]; // CipherText[127:0]
XMM3 := Handle[511:384]; // CipherText[255:128]
XMM4 := 0;
// Reserved for future usage
XMM5 := 0;
// Reserved for future usage
XMM6 := 0;
// Reserved for future usage
RFLAGS.OF, SF, ZF, AF, PF, CF := 0;
1. Further details on Key Locker and usage of this instruction can be found here:
https://software.intel.com/content/www/us/en/develop/download/intel-key-locker-specification.html.
2. SRC[31:3] are currently reserved for future usages. SRC[2], which indicates a no-decrypt restriction, is reserved if
CPUID.19H:EAX[2] is 0. SRC[1], which indicates a no-encrypt restriction, is reserved if CPUID.19H:EAX[1] is 0. SRC[0], which indicates
a CPL0-only restriction, is reserved if CPUID.19H:EAX[0] is 0.
ENCODEKEY256-Encode 256-Bit Key With Key Locker
Vol. 2A
3-285
Flags Affected
All arithmetic flags (OF, SF, ZF, AF, PF, CF) are cleared to 0. Although they are cleared for the currently defined oper-
ations, future extensions may report information in the flags.
Intel C/C++ Compiler Intrinsic Equivalent
ENCODEKEY256 unsigned int _mm_encodekey256_u32(unsigned int htype, __m128i key_lo, __m128i key_hi, void* h);
Exceptions (All Operating Modes)
#GP
If reserved bit is set in source register value.
#UD
If the LOCK prefix is used.
If CPUID.07H.00H:ECX.KEY_LOCKER[23] = 0.
If CR4.KL = 0.
If CPUID.19H:EBX.AESKLE[0] = 0.
If CR0.EM = 1.
If CR4.OSFXSR = 0.
#NM
If CR0.TS = 1.
ENCODEKEY256-Encode 256-Bit Key With Key Locker
Vol. 2A
3-286
ENDBR32-Terminate an Indirect Branch in 32-bit and Compatibility Mode
Opcode/
Op /
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
F3 0F 1E FB
ZO
V/V
CET_IBT
Terminate indirect branch in 32-bit and compatibility
ENDBR32
mode.
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
N/A
Description
Terminate an indirect branch in 32 bit and compatibility mode. This opcode is a NOP when CET indirect branch
tracking is not enabled, on processors that do not support CET, and in 64-bit mode.
Operation
IF EndbranchEnabled(CPL) & (IA32_EFER.LMA = 0 | (IA32_EFER.LMA=1 & CS.L = 0)
IF CPL = 3
THEN
IA32_U_CET.TRACKER = IDLE
IA32_U_CET.SUPPRESS = 0
ELSE
IA32_S_CET.TRACKER = IDLE
IA32_S_CET.SUPPRESS = 0
FI;
FI;
Flags Affected
None.
Exceptions
#UD
If the LOCK prefix is used.
ENDBR32-Terminate an Indirect Branch in 32-bit and Compatibility Mode
Vol. 2A
3-287
ENDBR64-Terminate an Indirect Branch in 64-bit Mode
Opcode/
Op /
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
F3 0F 1E FA
ZO
V/V
CET_IBT
Terminate indirect branch in 64-bit mode.
ENDBR64
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
N/A
Description
Terminate an indirect branch in 64 bit mode. This opcode is a NOP when CET indirect branch tracking is not
enabled, on processors that do not support CET, and outside 64-bit mode.
Operation
IF EndbranchEnabled(CPL) & IA32_EFER.LMA = 1 & CS.L = 1
IF CPL = 3
THEN
IA32_U_CET.TRACKER = IDLE
IA32_U_CET.SUPPRESS = 0
ELSE
IA32_S_CET.TRACKER = IDLE
IA32_S_CET.SUPPRESS = 0
FI;
FI;
Flags Affected
None.
Exceptions
#UD
If the LOCK prefix is used.
ENDBR64-Terminate an Indirect Branch in 64-bit Mode
Vol. 2A
3-288
ENQCMD-Enqueue Command
Opcode/
Op/
64/32 bit
CPUID Feature
Description
Instruction
En
Mode
Flag
Support
F2 0F 38 F8 !(11):rrr:bbb
A
V/V
ENQCMD
Atomically enqueue 64-byte user command from
ENQCMD r32/r64, m512
source memory operand to destination offset in
ES segment specified in register operand as
offset in ES segment.
Instruction Operand Encoding
Op/En
Tuple
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:reg (w)
ModRM:r/m (r)
N/A
N/A
Description
The ENQCMD instruction allows software to write commands to enqueue registers, which are special device
registers accessed using memory-mapped I/O (MMIO).
Enqueue registers expect writes to have the following format:
511
32
31
30
20 19
DEVICE SPECIFIC COMMAND
PRIV
RESERVED
PASID
Figure 3-11. 64-Byte Data Written to Enqueue Registers
Bits 19:0 convey the process address space identifier (PASID), a value which system software may assign to indi-
vidual software threads. Bit 31 contains privilege identification (0 = user; 1 = supervisor). Devices implementing
enqueue registers may use these two values along with a device-specific command in the upper 60 bytes.
The ENQCMD instruction begins by reading 64 bytes of command data from its source memory operand. This is an
ordinary load with cacheability and memory ordering implied normally by the memory type. The source operand
need not be aligned, and there is no guarantee that all 64 bytes are loaded atomically. Bits 31:0 of the source
operand must be zero.
The instruction then formats those 64 bytes into command data with a format consistent with that given in
Figure 3-11:
• Command[19:0] get IA32_PASID[19:0].1
• Command[30:20] are zero.
• Command[31] is 0 (indicating user; this value is used regardless of CPL).
• Command[511:32] get bits 511:32 of the source operand that was read from memory.
The ENQCMD instruction uses an enqueue store (defined below) to write this command data to the destination
operand. The address of the destination operand is specified in a general-purpose register as an offset into the ES
segment (the segment cannot be overridden).2 The destination linear address must be 64-byte aligned. The oper-
ation of an enqueue store disregards the memory type of the destination memory address.
1. It is expected that system software will load the IA32_PASID MSR so that bits 19:0 contain the PASID of the current soft-
ware thread. The MSR’s valid bit, IA32_PASID[31], must be 1. For additional details on the IA32_PASID MSR, see the
Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 4.
2. In 64-bit mode, the width of the register operand is 64 bits (32 bits with a 67H prefix). Outside 64-bit mode when CS.D =
1, the width is 32 bits (16 bits with a 67H prefix). Outside 64-bit mode when CS.D=0, the width is 16 bits (32 bits with a
67H prefix).
ENQCMD-Enqueue Command
Vol. 2A
3-289
An enqueue store is not ordered relative to older stores to WB or WC memory (including non-temporal stores) or
to executions of the CLFLUSHOPT or CLWB (when applied to addresses other than that of the enqueue store). Soft-
ware can enforce such ordering by executing a fencing instruction such as SFENCE or MFENCE before the enqueue
store.
An enqueue store does not write the data into the cache hierarchy, nor does it fetch any data into the cache hier-
archy. An enqueue store’s command data is never combined with that of any other store to the same address.
Unlike other stores, an enqueue store returns a status, which the ENQCMD instruction loads into the ZF flag in the
RFLAGS register:
• ZF = 0 (success) reports that the 64-byte command data was written atomically to a device’s enqueue register
and has been accepted by the device. (It does not guarantee that the device has acted on the command; it may
have queued it for later execution.)
• ZF = 1 (retry) reports that the command data was not accepted. This status is returned if the destination
address is an enqueue register but the command was not accepted due to capacity or other temporal reasons.
This status is also returned if the destination address was not an enqueue register (including the case of a
memory address); in these cases, the store is dropped and is written neither to MMIO nor to memory.
Availability of the ENQCMD instruction is indicated by the presence of the CPUID feature flag ENQCMD
(CPUID.07H.00H:ECX[29]).
Operation
IF IA32_PASID[31] = 0
THEN #GP;
ELSE
COMMAND := (SRC & ~FFFFFFFFH) | (IA32_PASID & FFFFFH);
DEST := COMMAND;
FI;
Intel C/C++ Compiler Intrinsic Equivalent
ENQCMD int_enqcmd(void *dst, const void *src)
Flags Affected
The ZF flag is set if the enqueue-store completion returns the retry status; otherwise it is cleared. All other flags
are cleared.
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 destination linear address is not aligned to a 64-byte boundary.
If the PASID Valid field (bit 31) is 0 in IA32_PASID MSR.
If bits 31:0 of the source operand are not all zero.
#SS(0)
For an illegal address in the SS segment.
#PF(fault-code)
For a page fault.
#UD
If CPUID.07H.00H:ECX.ENQCMD[29] = 0.
If the LOCK prefix is used.
ENQCMD-Enqueue Command
Vol. 2A
3-290
Real-Address Mode Exceptions
#GP
If any part of the operand lies outside the effective address space from 0 to FFFFH.
If destination linear address is not aligned to a 64-byte boundary.
If the PASID Valid field (bit 31) is 0 in IA32_PASID MSR.
If bits 31:0 of the source operand are not all zero.
#UD
If CPUID.07H.00H:ECX.ENQCMD[29] = 0.
If the LOCK prefix is used.
Virtual-8086 Mode Exceptions
Same exceptions as in real-address mode. Additionally:
#PF(fault-code)
For a page fault.
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 non-canonical form.
#GP(0)
If the memory address is in non-canonical form.
If destination linear address is not aligned to a 64-byte boundary.
If the PASID Valid field (bit 31) is 0 in IA32_PASID MSR.
If bits 31:0 of the source operand are not all zero.
#PF(fault-code)
For a page fault.
#UD
If CPUID.07H.00H:ECX.ENQCMD[29].
If the LOCK prefix is used.
ENQCMD-Enqueue Command
Vol. 2A
3-291
ENQCMDS-Enqueue Command Supervisor
Opcode/
Op/
64/32 bit
CPUID Feature
Description
Instruction
En
Mode
Flag
Support
F3 0F 38 F8 !(11):rrr:bbb
A
V/V
ENQCMD
Atomically enqueue 64-byte command with
ENQCMDS r32/r64, m512
PASID from source memory operand to
destination offset in ES segment specified in
register operand as offset in ES segment.
Instruction Operand Encoding
Op/En
Tuple
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:reg (w)
ModRM:r/m (r)
N/A
N/A
Description
The ENQCMDS instruction allows system software to write commands to enqueue registers, which are special
device registers accessed using memory-mapped I/O (MMIO).
Enqueue registers expect writes to have the format given in Figure 3-11 and explained in the section on
“ENQCMD-Enqueue Command.”
The ENQCMDS instruction begins by reading 64 bytes of command data from its source memory operand. This is
an ordinary load with cacheability and memory ordering implied normally by the memory type. The source operand
need not be aligned, and there is no guarantee that all 64 bytes are loaded atomically. Bits 30:20 of the source
operand must be zero.
ENQCMDS formats its source data differently from ENQCMD. Specifically, it formats them into command data as
follows:
• Command[19:0] get bits 19:0 of the source operand that was read from memory. These 20 bits communicate
a process address-space identifier (PASID).
• Command[30:20] are zero.
• Command[511:31] get bits 511:31 of the source operand that was read from memory. Bit 31 communicates a
privilege identification (0 = user; 1 = supervisor).
The ENQCMDS instruction then uses an enqueue store (defined below) to write this command data to the desti-
nation operand. The address of the destination operand is specified in a general-purpose register as an offset into
the ES segment (the segment cannot be overridden).1 The destination linear address must be 64-byte aligned. The
operation of an enqueue store disregards the memory type of the destination memory address.
An enqueue store is not ordered relative to older stores to WB or WC memory (including non-temporal stores) or
to executions of the CLFLUSHOPT or CLWB (when applied to addresses other than that of the enqueue store). Soft-
ware can enforce such ordering by executing a fencing instruction such as SFENCE or MFENCE before the enqueue
store.
An enqueue store does not write the data into the cache hierarchy, nor does it fetch any data into the cache hier-
archy. An enqueue store’s command data is never combined with that of any other store to the same address.
Unlike other stores, an enqueue store returns a status, which the ENQCMDS instruction loads into the ZF flag in the
RFLAGS register:
• ZF = 0 (success) reports that the 64-byte command data was written atomically to a device’s enqueue register
and has been accepted by the device. (It does not guarantee that the device has acted on the command; it may
have queued it for later execution.)
• ZF = 1 (retry) reports that the command data was not accepted. This status is returned if the destination
address is an enqueue register but the command was not accepted due to capacity or other temporal reasons.
1. In 64-bit mode, the width of the register operand is 64 bits (32 bits with a 67H prefix). Outside 64-bit mode when CS.D =
1, the width is 32 bits (16 bits with a 67H prefix). Outside 64-bit mode when CS.D=0, the width is 16 bits (32 bits with a
67H prefix).
ENQCMDS-Enqueue Command Supervisor
Vol. 2A
3-292
This status is also returned if the destination address was not an enqueue register (including the case of a
memory address); in these cases, the store is dropped and is written neither to MMIO nor to memory.
The ENQCMDS instruction may be executed only if CPL= 0. Availability of the ENQCMDS instruction is indicated by
the presence of the CPUID feature flag ENQCMD (CPUID.07H.00H:ECX[29]).
Operation
DEST := SRC;
Intel C/C++ Compiler Intrinsic Equivalent
ENQCMDS int_enqcmds(void *dst, const void *src)
Flags Affected
The ZF flag is set if the enqueue-store completion returns the retry status; otherwise it is cleared. All other flags
are cleared.
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 destination linear address is not aligned to a 64-byte boundary.
If the current privilege level is not 0.
If bits 30:20 of the source operand are not all zero.
#SS(0)
For an illegal address in the SS segment.
#PF(fault-code)
For a page fault.
#UD
If CPUID.07H.00H:ECX.ENQCMD[29] = 0.
If the LOCK prefix is used.
Real-Address Mode Exceptions
#GP
If any part of the operand lies outside the effective address space from 0 to FFFFH.
If destination linear address is not aligned to a 64-byte boundary.
If bits 30:20 of the source operand are not all zero.
#UD
If CPUID.07H.00H:ECX.ENQCMD[29] = 0.
If the LOCK prefix is used.
Virtual-8086 Mode Exceptions
#GP(0)
The ENQCMDS instruction is not recognized in virtual-8086 mode.
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 non-canonical form.
#GP(0)
If the memory address is in non-canonical form.
If destination linear address is not aligned to a 64-byte boundary.
If the current privilege level is not 0.
If bits 30:20 of the source operand are not all zero.
#PF(fault-code)
For a page fault.
ENQCMDS-Enqueue Command Supervisor
Vol. 2A
3-293
#UD
If CPUID.07H.00H:ECX.ENQCMD[29].
If the LOCK prefix is used.
ENQCMDS-Enqueue Command Supervisor
Vol. 2A
3-294
ENTER-Make Stack Frame for Procedure Parameters
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
C8 iw 00
ENTER imm16, 0
II
Valid
Valid
Create a stack frame for a procedure.
C8 iw 01
ENTER imm16,1
II
Valid
Valid
Create a stack frame with a nested pointer for
a procedure.
C8 iw ib
ENTER imm16, imm8
II
Valid
Valid
Create a stack frame with nested pointers for
a procedure.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
II
iw
imm8
N/A
N/A
Description
Creates a stack frame (comprising of space for dynamic storage and 1-32 frame pointer storage) for a procedure.
The first operand (imm16) specifies the size of the dynamic storage in the stack frame (that is, the number of bytes
of dynamically allocated on the stack for the procedure). The second operand (imm8) gives the lexical nesting level
(0 to 31) of the procedure. The nesting level (imm8 mod 32) and the OperandSize attribute determine the size in
bytes of the storage space for frame pointers.
The nesting level determines the number of frame pointers that are copied into the “display area” of the new stack
frame from the preceding frame. The default size of the frame pointer is the StackAddrSize attribute, but can be
overridden using the 66H prefix. Thus, the OperandSize attribute determines the size of each frame pointer that
will be copied into the stack frame and the data being transferred from SP/ESP/RSP register into the BP/EBP/RBP
register.
The ENTER and companion LEAVE instructions are provided to support block structured languages. The ENTER
instruction (when used) is typically the first instruction in a procedure and is used to set up a new stack frame for
a procedure. The LEAVE instruction is then used at the end of the procedure (just before the RET instruction) to
release the stack frame.
If the nesting level is 0, the processor pushes the frame pointer from the BP/EBP/RBP register onto the stack,
copies the current stack pointer from the SP/ESP/RSP register into the BP/EBP/RBP register, and loads the
SP/ESP/RSP register with the current stack-pointer value minus the value in the size operand. For nesting levels of
1 or greater, the processor pushes additional frame pointers on the stack before adjusting the stack pointer. These
additional frame pointers provide the called procedure with access points to other nested frames on the stack. See
“Procedure Calls for Block-Structured Languages” in Chapter 6 of the Intel® 64 and IA-32 Architectures Software
Developer’s Manual, Volume 1, for more information about the actions of the ENTER instruction.
The ENTER instruction causes a page fault whenever a write using the final value of the stack pointer (within the
current stack segment) would do so.
In 64-bit mode, default operation size is 64 bits; 32-bit operation size cannot be encoded. Use of 66H prefix
changes frame pointer operand size to 16 bits.
When the 66H prefix is used and causing the OperandSize attribute to be less than the StackAddrSize, software is
responsible for the following:
• The companion LEAVE instruction must also use the 66H prefix,
• The value in the RBP/EBP register prior to executing “66H ENTER” must be within the same 16KByte region of
the current stack pointer (RSP/ESP), such that the value of RBP/EBP after “66H ENTER” remains a valid address
in the stack. This ensures “66H LEAVE” can restore 16-bits of data from the stack.
ENTER-Make Stack Frame for Procedure Parameters
Vol. 2A
3-295
Operation
AllocSize := imm16;
NestingLevel := imm8 MOD 32;
IF (OperandSize = 64)
THEN
Push(RBP); (* RSP decrements by 8 *)
FrameTemp := RSP;
ELSE IF OperandSize = 32
THEN
Push(EBP); (* (E)SP decrements by 4 *)
FrameTemp := ESP; FI;
ELSE (* OperandSize = 16 *)
Push(BP); (* RSP or (E)SP decrements by 2 *)
FrameTemp := SP;
FI;
IF NestingLevel = 0
THEN GOTO CONTINUE;
FI;
IF (NestingLevel > 1)
THEN FOR i := 1 to (NestingLevel - 1)
DO
IF (OperandSize = 64)
THEN
RBP := RBP - 8;
Push([RBP]); (* Quadword push *)
ELSE IF OperandSize = 32
THEN
IF StackSize = 32
EBP := EBP - 4;
Push([EBP]); (* Doubleword push *)
ELSE (* StackSize = 16 *)
BP := BP - 4;
Push([BP]); (* Doubleword push *)
FI;
FI;
ELSE (* OperandSize = 16 *)
IF StackSize = 64
THEN
RBP := RBP - 2;
Push([RBP]); (* Word push *)
ELSE IF StackSize = 32
THEN
EBP := EBP - 2;
Push([EBP]); (* Word push *)
ELSE (* StackSize = 16 *)
BP := BP - 2;
Push([BP]); (* Word push *)
FI;
FI;
OD;
FI;
IF (OperandSize = 64) (* nestinglevel 1 *)
ENTER-Make Stack Frame for Procedure Parameters
Vol. 2A
3-296
THEN
Push(FrameTemp); (* Quadword push and RSP decrements by 8 *)
ELSE IF OperandSize = 32
THEN
Push(FrameTemp); FI; (* Doubleword push and (E)SP decrements by 4 *)
ELSE (* OperandSize = 16 *)
Push(FrameTemp); (* Word push and RSP|ESP|SP decrements by 2 *)
FI;
CONTINUE:
IF 64-Bit Mode (StackSize = 64)
THEN
RBP := FrameTemp;
RSP := RSP - AllocSize;
ELSE IF OperandSize = 32
THEN
EBP := FrameTemp;
ESP := ESP - AllocSize; FI;
ELSE (* OperandSize = 16 *)
BP := FrameTemp[15:1]; (* Bits 16 and above of applicable RBP/EBP are unmodified *)
SP := SP - AllocSize;
FI;
END;
Flags Affected
None.
Protected Mode Exceptions
#SS(0)
If the new value of the SP or ESP register is outside the stack segment limit.
#PF(fault-code)
If a page fault occurs or if a write using the final value of the stack pointer (within the current
stack segment) would cause a page fault.
#UD
If the LOCK prefix is used.
Real-Address Mode Exceptions
#SS
If the new value of the SP or ESP register is outside the stack segment limit.
#UD
If the LOCK prefix is used.
Virtual-8086 Mode Exceptions
#SS(0)
If the new value of the SP or ESP register is outside the stack segment limit.
#PF(fault-code)
If a page fault occurs or if a write using the final value of the stack pointer (within the current
stack segment) would cause a page fault.
#UD
If the LOCK prefix is used.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
#SS(0)
If the stack address is in a non-canonical form.
#PF(fault-code)
If a page fault occurs or if a write using the final value of the stack pointer (within the current
stack segment) would cause a page fault.
#UD
If the LOCK prefix is used.
ENTER-Make Stack Frame for Procedure Parameters
Vol. 2A
3-297
ERETS-Event Return to Supervisor
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
F2 0F 01 CA
ERETS
ZO
Valid
Invalid
Event return for events occurring in ring 0.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
ERETS returns from an event handler, establishing the state based on the contents of the stack (typically, that
which was in effect before FRED event delivery). ERETS can be executed only if CPL = 0, and it does not change
CPL. For this reason, ERETS is used to return from handling events that occurred while CPL = 0.
ERETS takes no explicit arguments; its operation depends on the contents of the regular stack and (when enabled)
the shadow stack.
Execution of ERETS causes an invalid-opcode exception (#UD) if FRED transitions are not enabled or if CPL > 0. For
this reason, ERETS can be executed only in 64-bit mode.
Section 8.4.1, “ERETS (Event Return to Supervisor),” of the Intel® 64 and IA-32 Architectures software devel-
oper’s Manual, Volume 3 includes a detailed discussion of ERETS.
Instruction ordering. Instructions following execution of ERETS may be fetched from memory before earlier
instructions complete execution, but they will not execute (even speculatively) until all instructions prior to ERETS
have completed execution (the later instructions may execute before data stored by the earlier instructions have
become globally visible).
Operation
IF CR4.FRED = 0 OR CPL > 0
THEN #UD;
FI;
// CR4.FRED = 1 and CPL = 0 implies IA32_EFER.LMA = CS.L = 1
// pop old state from regular stack and check it
RSP := RSP + 8;
// skip over error code so that RSP references the return state
pop8B newRIP;
pop8B tempCS;
// not used to load CS
pop8B newRFLAGS;
pop8B newRSP;
pop8B tempSS;
// not used to load SS
IF newRIP is not paging canonical OR
tempCS & FFFFFFFF_FFF8FFFFH ≠ current CS selector OR
newRFLAGS & FFFFFFFF_FFC2802AH ≠ 2 OR
// enforce bit 1 set; VM, reserved bits clear
tempSS & FFF8FFFFH ≠ current SS selector OR
// do not check bits 63:32
THEN #GP(0);
FI;
// ERETS will not numerically increase stack level
newCSL := min{CSL,tempCS[17:16]};
IBT_restore := tempCS[18];
STI_block := tempSS[16];
pend_DB := tempSS[17];
NMI_unblock := tempSS[18];
ERETS-Event Return to Supervisor
Vol. 2A
3-298
// If supervisor shadow stacks are enabled, pop and check values from the shadow stack
IF CR4.CET = 1 AND IA32_S_CET.SH_STK_EN = 1
THEN
IF SSP & 7 ≠ 0
// require 8-byte alignment
THEN #CP(FAR-RET/IRET);
FI;
popSS_8B newSSP;
popSS_8B checkSSLIP;
popSS_8B checkSSCS;
IF checkSSCS ≠ tempCS
// 64-bit compare
OR checkSSLIP ≠ newRIP
OR newSSP & 3H ≠ 0
THEN #CP(FAR-RET/IRET);
FI;
IF newSSP not CPU canonical
THEN #GP(0);
FI;
// If the stack level is changing, compare SSP to the FRED SSP MSR for the old stack level
IF newCSL < CSL AND IA32_FRED_SSPi ≠ SSP
// where i = CSL
THEN #CP(FAR-RET/IRET);
FI;
FI;
// update registers for return state
RIP := newRIP;
RFLAGS := newRFLAGS;
// ERETS can set RFLAGS.RF to 1
RSP := newRSP;
CSL := newCSL;
// reflect in IA32_FRED_CONFIG[1:0]
IF CR4.CET = 1 AND IA32_S_CET.SH_STK_EN = 1
THEN SSP := newSSP;
FI;
IF CR4.CET = 1 AND IA32_S_CET.ENDBR_EN = 1 AND IA32_S_CET.SUPPRESS = 0 AND IBT_restore = 1
THEN IA32_S_CET.TRACKER := 1;
FI;
// update event-related state
IF STI_block = 1 AND RFLAGS.IF = 1 AND STI blocking was not in effect prior to ERETS
THEN establish STI blocking after ERETS;
FI;
IF pend_DB = 1 AND RFLAGS.TF =1
THEN pend a single-step debug exception (#DB) to be delivered after ERETS;
FI;
IF NMI_unblock = 1
THEN unblock NMIs;
FI;
Flags Affected
All defined flags and fields in the RFLAGS register are potentially modified except for the VM flag.
Protected Mode Exceptions
#UD
The ERETS instruction is not recognized in protected mode.
ERETS-Event Return to Supervisor
Vol. 2A
3-299
Real-Address Mode Exceptions
#UD
The ERETS instruction is not recognized in real-address mode.
Virtual-8086 Mode Exceptions
#UD
The ERETS instruction is not recognized in virtual-8086 mode.
Compatibility Mode Exceptions
#UD
The ERETS instruction is not recognized in compatibility mode.
64-Bit Mode Exceptions
#UD
If CR4.FRED = 0.
If CPL > 0.
If the LOCK prefix is used.
#GP(0)
If the RIP image on the stack is a not paging canonical.
If the RFLAGS image on the stack sets reserved bits or the VM bit (or fails to set bit 1).
If bits 15:0 of the CS image on the stack differs from the value of the current CS selector.
If the CS image on the stack sets undefined bits (bits 63:19).
If bits 15:0 of the SS image on the stack differs from the value of the current SS selector.
If the SS image on the stack sets undefined bits (bits 31:19).
If the SSP image on the shadow stack is not CPU canonical.
If a shadow-stack access would use an address that is not paging canonical or would cause a
LASS violation.
#SS(0)
If an ordinary stack access would use an address that is not paging canonical or would cause
a LASS violation.
#CP(FAR-RET/IRET) If the address in SSP is not 8-byte aligned.
If the 64-bit CS image on the shadow stack differs from that on the regular stack.
If the SSLIP image on the shadow stack differs from the RIP image on the regular stack.
If the SSP image on the shadow stack is not 4-byte aligned.
If the CSL is i, the stack level is changing, and SSP differs from the value of IA32_FRED_SSPi.
ERETS-Event Return to Supervisor
Vol. 2A
3-300
ERETU-Event Return to User
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
F3 0F 01 CA
ERETU
ZO
Valid
Valid
Event return for events occurring in ring 3.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
ERETU returns from an event handler, establishing the state based on the contents of the stack (typically, that
which was in effect before FRED event delivery). ERETU can be executed only if CPL = 0, and it changes CPL to 3.
For this reason, ERETU is used to return from handling events that occurred while CPL = 3.
ERETU takes no explicit arguments; its operation depends on the contents of the regular stack.
Execution of ERETU causes an invalid-opcode exception (#UD) if FRED transitions are not enabled or if CPL > 0. For
this reason, ERETU can be executed only in 64-bit mode.
ERETU establishes new values of CS and SS in one of three different ways:
• If the values popped from the stack correspond to the values of IA32_STAR[63:48] + 16 and
IA32_STAR[63:48] + 8, respectively, CS and SS are loaded with standard values for operation in 64-bit mode
(similar those established by the 64-bit form of SYSCALL).
• If the values popped from the stack correspond to the values of IA32_STAR[63:48] and IA32_STAR[63:48] +
8, respectively, CS and SS are loaded with standard values for operation in compatibility mode (similar those
established by the 32-bit form of SYSCALL).
• Otherwise, CS and SS are loaded from the GDT or LDT using the selectors popped from the stack (similar to the
manner used by the 64-bit form of IRET).
For further details see the Operation section below and Section 8.4.2, “ERETU (Event Return to User),” in the
Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3.
Instruction ordering. Instructions following execution of ERETU may be fetched from memory before earlier
instructions complete execution, but they will not execute (even speculatively) until all instructions prior to ERETU
have completed execution (the later instructions may execute before data stored by the earlier instructions have
become globally visible).
Operation
IF CR4.FRED = 0 OR CS.L = 0 OR CPL > 0
THEN #UD;
FI;
IF CSL > 0
THEN #GP(0);
FI;
// pop old state from regular stack and check it
RSP := RSP + 8;
// skip over error code so that RSP references the return state
pop8B newRIP;
pop8B tempCS;
pop8B newRFLAGS;
pop8B newRSP;
pop8B tempSS;
IF tempCS & FFFFFFFF_FFFF0003H ≠ 3 OR
// enforce return to ring 3
newRFLAGS & FFFFFFFF_FFC2B02AH ≠ 2 OR // enforce bit 1 set; IOPL, VM, reserved bits clear
tempSS & FFF80003H ≠ 3
// do not check bits 63:32
THEN #GP(0);
ERETU-Event Return to User
Vol. 2A
3-301
FI;
pend_DB := tempSS[17];
NMI_unblock := tempSS[18];
IF tempCS[15:0] = IA32_STAR[63:48] + 16 AND tempSS[15:0] = IA32_STAR[63:48] + 8
THEN
// Return to ring 3 in standard 64-bit configuration
// set newCS to standard values used ring 3 in 64-bit mode
newCS.selector := tempCS[15:0];
newCS.base := 0;
newCS.limit := FFFFFH;
newCS.type := 11;
newCS.S := 1;
newCS.DPL := 3;
newCS.P := 1;
newCS.L := 1;
newCS.D := 0;
newCS.G := 1;
newCS.unusable := 0;
// set newSS to standard values for ring 3
newSS.selector := tempSS[15:0];
newSS.base := 0;
newSS.limit := FFFFFH;
newSS.type := 3;
newSS.S := 1;
newSS.DPL := 3;
newSS.P := 1;
newSS.B := 1;
newSS.G := 1;
newSS.unusable := 0;
ELSIF tempCS[15:0] = IA32_STAR[63:48] AND tempSS[15:0] = IA32_STAR[63:48] + 8
THEN
// set newCS to standard values used ring 3 in compatibility mode
newCS.selector := tempCS[15:0];
newCS.base := 0;
newCS.limit := FFFFFH;
newCS.type := 11;
newCS.S := 1;
newCS.DPL := 3;
newCS.P := 1;
newCS.L := 0;
newCS.D := 1;
newCS.G := 1;
newCS.unusable := 0;
// set newSS to standard values for ring 3
newSS.selector := tempSS[15:0];
newSS.base := 0;
newSS.limit := FFFFFH;
newSS.type := 3;
newSS.S := 1;
newSS.DPL := 3;
newSS.P := 1;
newSS.B := 1;
newSS.G := 1;
newSS.unusable := 0;
ELSE
ERETU-Event Return to User
Vol. 2A
3-302
load newCS using tempCS[15:0];
// load each as is done by IRET, including
load newSS using tempSS[15:0];
// checks that may lead to a fault
FI;
IF newCS.L = 1
THEN
// return to 64-bit mode
IF newRIP is not paging canonical
THEN #GP(0);
FI;
ELSE
// return to compatibility mode
newRIP[63:32] := 0;
IF newRIP is not within newCS’s limit (based on limit field and G bit)
// newRIP is always within the limit with standard values for ring 3 in compatibility mode
THEN #GP(0);
FI;
newRSP[63:32] := 0;
FI;
// If user shadow stacks are enabled, check new SSP value on return to compatibility mode
IF CR4.CET = 1 AND IA32_U_CET.SH_STK_EN = 1 AND newCS.L = 0 AND IA32_PL3_SSP[63:32] ≠ 0
THEN #GP(0);
FI;
// If supervisor shadow stacks are enabled, compare SSP to the FRED SSP MSR for stack level 0
IF CR4.CET = 1 AND IA32_S_CET.SH_STK_EN = 1 AND IA32_FRED_SSP0 ≠ SSP
THEN #CP(FAR-RET/IRET);
FI;
// update registers for return state
RIP := newRIP;
RFLAGS := newRFLAGS;
// ERETU can set RFLAGS.RF to 1
RSP := newRSP;
// load all 64 bits regardless of new mode
CS := newCS;
// selector and descriptor
SS := newSS;
// selector and descriptor
CPL := 3;
// swap GS.base and IA32_KERNEL_GS_BASE
tempGSB := GS.base;
GS.base := IA32_KERNEL_GS_BASE;
IA32_KERNEL_GS_BASE := tempGSB;
IF CR4.CET = 1 AND IA32_U_CET.SH_STK_EN = 1
THEN SSP := IA32_PL3_SSP;
FI;
// update event-related state
IF NMI_unblock = 1
THEN unblock NMIs;
FI;
IF pend_DB = 1 AND RFLAGS.TF =1
THEN pend a single-step debug exception (#DB) to be delivered after ERETU;
FI;
Flags Affected
All defined flags and fields in the RFLAGS register are potentially modified except for the VM flag.
Protected Mode Exceptions
#UD
The ERETU instruction is not recognized in protected mode.
ERETU-Event Return to User
Vol. 2A
3-303
Real-Address Mode Exceptions
#UD
The ERETU instruction is not recognized in real-address mode.
Virtual-8086 Mode Exceptions
#UD
The ERETU instruction is not recognized in virtual-8086 mode.
Compatibility Mode Exceptions
#UD
The ERETU instruction is not recognized in compatibility mode.
64-Bit Mode Exceptions
#UD
If CR4.FRED = 0.
If CPL > 0.
If the LOCK prefix is used.
#GP(0)
If CSL > 0.
If the return is to 64-bit mode and the RIP image on the stack is not paging canonical.
If the return is to compatibility mode and the low 32 bits of the RIP image on the stack is not
within the CS.limit being established.
If the RFLAGS image on the stack sets reserved bits or the VM bit (or fails to set bit 1).
If bits 13:12 of the RFLAGS image on the stack (corresponding to IOPL) are not zero.
If the value of bits 1:0 of the CS image on the stack (the target CPL) is not 3.
If the value of bits 63:16 of the CS image on the stack is not zero.
If the value of bits 1:0 of the SS image on the stack (the target CPL) is not 3.
If the SS image on the stack sets undefined bits (bits 31:19).
If the return is to compatibility mode and would load SSP with a value that sets any of bits
63:32.
If ERETU is loading CS and SS from descriptor tables (see Operation section) and either of the
following apply:
• If the value of bits 15:2 of the CS image on the stack is 0.
• If the value of bits 15:2 of the SS image on the stack is 0.
#GP(selector)
If ERETU is loading CS and SS from descriptor tables (see Operation section) and any of the
following apply:
• A segment selector index is outside its descriptor table limits.
• A segment descriptor memory address is not paging canonical.
• The segment descriptor for CS does not indicate that it is a code segment.
• The segment descriptor for CS has both the D-bit and L-bit set.
• The segment descriptor for CS is non-conforming and its DPL is not 3.
• The segment descriptor for SS does not indicate that it is a writable data segment.
• The DPL of the segment descriptor for SS is not 3.
#SS(0)
If an ordinary stack access would use an address that is not paging canonical or would cause
a LASS violation.
#CP(FAR-RET/IRET) If the value in SSP differs from that in IA32_FRED_SSP0.
ERETU-Event Return to User
Vol. 2A
3-304
EXTRACTPS-Extract Packed Floating-Point Values
Opcode/
Op /
64/32 bit
CPUID Feature
Description
Instruction
En
Mode
Flag
Support
66 0F 3A 17 /r ib
A
VV
SSE4_1
Extract one single precision floating-point value
EXTRACTPS reg/m32, xmm1, imm8
from xmm1 at the offset specified by imm8 and
store the result in reg or m32. Zero extend the
results in 64-bit register if applicable.
VEX.128.66.0F3A.WIG 17 /r ib
A
V/V
AVX
Extract one single precision floating-point value
VEXTRACTPS reg/m32, xmm1, imm8
from xmm1 at the offset specified by imm8 and
store the result in reg or m32. Zero extend the
results in 64-bit register if applicable.
EVEX.128.66.0F3A.WIG 17 /r ib
B
V/V
AVX512F
Extract one single precision floating-point value
VEXTRACTPS reg/m32, xmm1, imm8
OR AVX10.1
from xmm1 at the offset specified by imm8 and
store the result in reg or m32. Zero extend the
results in 64-bit register if applicable.
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:r/m (w)
ModRM:reg (r)
imm8
N/A
B
Tuple1 Scalar
ModRM:r/m (w)
ModRM:reg (r)
imm8
N/A
Description
Extracts a single precision floating-point value from the source operand (second operand) at the 32-bit offset spec-
ified from imm8. Immediate bits higher than the most significant offset for the vector length are ignored.
The extracted single precision floating-point value is stored in the low 32-bits of the destination operand
In 64-bit mode, destination register operand has default operand size of 64 bits. The upper 32-bits of the register
are filled with zero. REX.W is ignored.
VEX.128 and EVEX encoded version: When VEX.W1 or EVEX.W1 form is used in 64-bit mode with a general
purpose register (GPR) as a destination operand, the packed single quantity is zero extended to 64 bits.
VEX.vvvv/EVEX.vvvv is reserved and must be 1111b otherwise instructions will #UD.
128-bit Legacy SSE version: When a REX.W prefix is used in 64-bit mode with a general purpose register (GPR) as
a destination operand, the packed single quantity is zero extended to 64 bits.
The source register is an XMM register. Imm8[1:0] determine the starting DWORD offset from which to extract the
32-bit floating-point value.
If VEXTRACTPS is encoded with VEX.L= 1, an attempt to execute the instruction encoded with VEX.L= 1 will cause
an #UD exception.
EXTRACTPS-Extract Packed Floating-Point Values
Vol. 2A
3-305
Operation
VEXTRACTPS (EVEX and VEX.128 Encoded Version)
SRC_OFFSET := IMM8[1:0]
IF (64-Bit Mode and DEST is register)
DEST[31:0] := (SRC[127:0] >> (SRC_OFFSET*32)) AND 0FFFFFFFFh
DEST[63:32] := 0
ELSE
DEST[31:0] := (SRC[127:0] >> (SRC_OFFSET*32)) AND 0FFFFFFFFh
FI
EXTRACTPS (128-bit Legacy SSE Version)
SRC_OFFSET := IMM8[1:0]
IF (64-Bit Mode and DEST is register)
DEST[31:0] := (SRC[127:0] >> (SRC_OFFSET*32)) AND 0FFFFFFFFh
DEST[63:32] := 0
ELSE
DEST[31:0] := (SRC[127:0] >> (SRC_OFFSET*32)) AND 0FFFFFFFFh
FI
Intel C/C++ Compiler Intrinsic Equivalent
EXTRACTPS int _mm_extract_ps (__m128 a, const int nidx);
SIMD Floating-Point Exceptions
None.
Other Exceptions
VEX-encoded instructions, see Table 2-22, “Type 5 Class Exception Conditions.”
EVEX-encoded instructions, see Table 2-59, “Type E9NF Class Exception Conditions.”
Additionally:
#UD
IF VEX.L = 0.
#UD
If VEX.vvvv != 1111B or EVEX.vvvv != 1111B.
EXTRACTPS-Extract Packed Floating-Point Values
Vol. 2A
3-306
F2XM1-Compute 2x-1
Opcode
Instruction
64-Bit
Compat/
Description
Mode
Leg Mode
D9 F0
F2XM1
Valid
Valid
Replace ST(0) with (2ST(0) - 1).
Description
Computes the exponential value of 2 to the power of the source operand minus 1. The source operand is located in
register ST(0) and the result is also stored in ST(0). The value of the source operand must lie in the range -1.0 to
+1.0. If the source value is outside this range, the result is undefined.
The following table shows the results obtained when computing the exponential value of various classes of
numbers, assuming that neither overflow nor underflow occurs.
Table 3-18. Results Obtained from F2XM1
ST(0) SRC
ST(0) DEST
− 1.0 to -0
- 0.5 to - 0
- 0
- 0
+ 0
+ 0
+ 0 to +1.0
+ 0 to 1.0
Values other than 2 can be exponentiated using the following formula:
xy := 2(y ∗ log2x)
This instruction’s operation is the same in non-64-bit modes and 64-bit mode.
Operation
ST(0) := (2ST(0) - 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 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.
#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.
F2XM1-Compute 2x-1
Vol. 2A
3-307
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
Same exceptions as in protected mode.
F2XM1-Compute 2x-1
Vol. 2A
3-308
FABS-Absolute Value
Opcode
Instruction
64-Bit
Compat/
Description
Mode
Leg Mode
D9 E1
FABS
Valid
Valid
Replace ST with its absolute value.
Description
Clears the sign bit of ST(0) to create the absolute value of the operand. The following table shows the results
obtained when creating the absolute value of various classes of numbers.
Table 3-19. Results Obtained from FABS
ST(0) SRC
ST(0) DEST
- ∞
+ ∞
- F
+ F
− 0
+ 0
+ 0
+ 0
+ F
+ F
+ ∞
+ ∞
NaN
NaN
NOTES:
F Means finite floating-point value.
This instruction’s operation is the same in non-64-bit modes and 64-bit mode.
Operation
ST(0) := |ST(0)|;
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.
#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.
FABS-Absolute Value
Vol. 2A
3-309
FABS-Absolute Value
Vol. 2A
3-310
FADD/FADDP/FIADD-Add
Opcode
Instruction
64-Bit
Compat/
Description
Mode
Leg Mode
D8 /0
FADD m32fp
Valid
Valid
Add m32fp to ST(0) and store result in ST(0).
DC /0
FADD m64fp
Valid
Valid
Add m64fp to ST(0) and store result in ST(0).
D8 C0+i
FADD ST(0), ST(i)
Valid
Valid
Add ST(0) to ST(i) and store result in ST(0).
DC C0+i
FADD ST(i), ST(0)
Valid
Valid
Add ST(i) to ST(0) and store result in ST(i).
DE C0+i
FADDP ST(i), ST(0)
Valid
Valid
Add ST(0) to ST(i), store result in ST(i), and pop the
register stack.
DE C1
FADDP
Valid
Valid
Add ST(0) to ST(1), store result in ST(1), and pop the
register stack.
DA /0
FIADD m32int
Valid
Valid
Add m32int to ST(0) and store result in ST(0).
DE /0
FIADD m16int
Valid
Valid
Add m16int to ST(0) and store result in ST(0).
Description
Adds the destination and source operands and stores the sum 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.
The no-operand version of the instruction adds the contents of the ST(0) register to the ST(1) register. The one-
operand version adds the contents of a memory location (either a floating-point or an integer value) to the
contents of the ST(0) register. The two-operand version, adds the contents of the ST(0) register to the ST(i)
register or vice versa. The value in ST(0) can be doubled by coding:
FADD ST(0), ST(0);
The FADDP instructions perform the additional operation of popping the FPU register stack after storing the result.
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 add instructions always results in the register stack being
popped. In some assemblers, the mnemonic for this instruction is FADD rather than FADDP.)
The FIADD instructions convert an integer source operand to double extended-precision floating-point format
before performing the addition.
The table on the following page shows the results obtained when adding various classes of numbers, assuming that
neither overflow nor underflow occurs.
When the sum of two operands with opposite signs is 0, the result is +0, except for the round toward -∞ mode, in
which case the result is -0. When the source operand is an integer 0, it is treated as a +0.
When both operand are infinities of the same sign, the result is ∞ of the expected sign. If both operands are infini-
ties of opposite signs, an invalid-operation exception is generated. See Table 3-20.
FADD/FADDP/FIADD-Add
Vol. 2A
3-311
Table 3-20. FADD/FADDP/FIADD Results
DEST
- ∞
- F
- 0
+ 0
+ F
+ ∞
NaN
− ∞
- ∞
- ∞
- ∞
- ∞
- ∞
*
NaN
− F or - I
- ∞
- F
SRC
SRC
± F or ± 0
+ ∞
NaN
SRC
-0
- ∞
DEST
- 0
± 0
DEST
+ ∞
NaN
+ 0
- ∞
DEST
± 0
+ 0
DEST
+ ∞
NaN
+ F or + I
- ∞
± F or ± 0
SRC
SRC
+ F
+ ∞
NaN
+ ∞
*
+ ∞
+ ∞
+ ∞
+ ∞
+ ∞
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 = FIADD
THEN
DEST := DEST + ConvertToDoubleExtendedPrecisionFP(SRC);
ELSE (* Source operand is floating-point value *)
DEST := DEST + SRC;
FI;
IF Instruction = FADDP
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 unlike 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.
FADD/FADDP/FIADD-Add
Vol. 2A
3-312
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.
FADD/FADDP/FIADD-Add
Vol. 2A
3-313
FBLD-Load Binary Coded Decimal
Opcode
Instruction
64-Bit
Compat/
Description
Mode
Leg Mode
DF /4
FBLD m80bcd
Valid
Valid
Convert BCD value to floating-point and push onto the
FPU stack.
Description
Converts the BCD source operand into double extended-precision floating-point format and pushes the value onto
the FPU stack. The source operand is loaded without rounding errors. The sign of the source operand is preserved,
including that of -0.
The packed BCD digits are assumed to be in the range 0 through 9; the instruction does not check for invalid digits
(AH through FH). Attempting to load an invalid encoding produces an undefined result.
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; otherwise, set to 0.
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.
FBLD-Load Binary Coded Decimal
Vol. 2A
3-314
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.
FBLD-Load Binary Coded Decimal
Vol. 2A
3-315
FBSTP-Store BCD Integer and Pop
Opcode
Instruction
64-Bit
Compat/
Description
Mode
Leg Mode
DF /6
FBSTP m80bcd
Valid
Valid
Store ST(0) in m80bcd and pop ST(0).
Description
Converts the value in the ST(0) register to an 18-digit packed BCD integer, stores the result in the destination
operand, and pops the register stack. If the source value is a non-integral value, it is rounded to an integer value,
according to rounding mode specified by the RC field of the FPU control word. To pop the register stack, the
processor marks the ST(0) register as empty and increments the stack pointer (TOP) by 1.
The destination operand specifies the address where the first byte destination value is to be stored. The BCD value
(including its sign bit) requires 10 bytes of space in memory.
The following table shows the results obtained when storing various classes of numbers in packed BCD format.
Table 3-21. FBSTP Results
ST(0)
DEST
− ∞ or Value Too Large for DEST Format
*
F ≤ - 1
- D
−1 < F < -0
**
- 0
- 0
+ 0
+ 0
+ 0 < F < +1
**
F ≥ +1
+ D
+ ∞ or Value Too Large for DEST Format
*
NaN
*
NOTES:
F Means finite floating-point value.
D Means packed-BCD number.
* Indicates floating-point invalid-operation (#IA) exception.
** ±0 or ±1, depending on the rounding mode.
If the converted value is too large for the destination format, or if the source operand is an ∞, 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 packed BCD indefinite value is stored in memory.
This instruction’s operation is the same in non-64-bit modes and 64-bit mode.
Operation
DEST := BCD(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.
FBSTP-Store BCD Integer and Pop
Vol. 2A
3-316
Floating-Point Exceptions
#IS
Stack underflow occurred.
#IA
Converted value that exceeds 18 BCD digits in length.
Source operand is an SNaN, QNaN, ±∞, or in an unsupported format.
#P
Value cannot be represented exactly in destination format.
Protected Mode Exceptions
#GP(0)
If a segment register is being loaded with a segment selector that points to 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 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.
FBSTP-Store BCD Integer and Pop
Vol. 2A
3-317
FCHS-Change Sign
Opcode
Instruction
64-Bit
Compat/
Description
Mode
Leg Mode
D9 E0
FCHS
Valid
Valid
Complements sign of ST(0).
Description
Complements the sign bit of ST(0). This operation changes a positive value into a negative value of equal magni-
tude or vice versa. The following table shows the results obtained when changing the sign of various classes of
numbers.
Table 3-22. FCHS Results
ST(0) SRC
ST(0) DEST
− ∞
+ ∞
- F
+ F
- 0
+ 0
+ 0
- 0
+ F
- F
+ ∞
- ∞
NaN
NaN
NOTES:
* F means finite floating-point value.
This instruction’s operation is the same in non-64-bit modes and 64-bit mode.
Operation
SignBit(ST(0)) := NOT (SignBit(ST(0)));
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.
#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.
FCHS-Change Sign
Vol. 2A
3-318
64-Bit Mode Exceptions
Same exceptions as in protected mode.
FCHS-Change Sign
Vol. 2A
3-319
FCLEX/FNCLEX-Clear Exceptions
Opcode1
Instruction
64-Bit
Compat/
Description
Mode
Leg Mode
9B DB E2
FCLEX
Valid
Valid
Clear floating-point exception flags after checking for
pending unmasked floating-point exceptions.
DB E2
FNCLEX1
Valid
Valid
Clear floating-point exception flags without checking for
pending unmasked floating-point exceptions.
NOTES:
1. See IA-32 Architecture Compatibility section below.
Description
Clears the floating-point exception flags (PE, UE, OE, ZE, DE, and IE), the exception summary status flag (ES), the
stack fault flag (SF), and the busy flag (B) in the FPU status word. The FCLEX instruction checks for and handles
any pending unmasked floating-point exceptions before clearing the exception flags; the FNCLEX instruction does
not.
The assembler issues two instructions for the FCLEX instruction (an FWAIT instruction followed by an FNCLEX
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.
IA-32 Architecture Compatibility
When operating a Pentium or Intel486 processor in MS-DOS* compatibility mode, it is possible (under unusual
circumstances) for an FNCLEX 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
FNCLEX instruction cannot be interrupted in this way on later Intel processors, except for the Intel QuarkTM X1000
processor.
This instruction affects only the x87 FPU floating-point exception flags. It does not affect the SIMD floating-point
exception flags in the MXCSR register.
This instruction’s operation is the same in non-64-bit modes and 64-bit mode.
Operation
FPUStatusWord[0:7] := 0;
FPUStatusWord[15] := 0;
FPU Flags Affected
The PE, UE, OE, ZE, DE, IE, ES, SF, and B flags in the FPU status word are cleared. The C0, C1, C2, and C3 flags are
undefined.
Floating-Point Exceptions
None.
Protected Mode Exceptions
#NM
CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#UD
If the LOCK prefix is used.
Real-Address Mode Exceptions
Same exceptions as in protected mode.
FCLEX/FNCLEX-Clear Exceptions
Vol. 2A
3-320
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.
FCLEX/FNCLEX-Clear Exceptions
Vol. 2A
3-321
FCMOVcc-Floating-Point Conditional Move
Opcode1
Instruction
64-Bit
Compat/
Description
Mode
Leg Mode1
DA C0+i
FCMOVB ST(0), ST(i)
Valid
Valid
Move if below (CF=1).
DA C8+i
FCMOVE ST(0), ST(i)
Valid
Valid
Move if equal (ZF=1).
DA D0+i
FCMOVBE ST(0), ST(i)
Valid
Valid
Move if below or equal (CF=1 or ZF=1).
DA D8+i
FCMOVU ST(0), ST(i)
Valid
Valid
Move if unordered (PF=1).
DB C0+i
FCMOVNB ST(0), ST(i)
Valid
Valid
Move if not below (CF=0).
DB C8+i
FCMOVNE ST(0), ST(i)
Valid
Valid
Move if not equal (ZF=0).
DB D0+i
FCMOVNBE ST(0), ST(i)
Valid
Valid
Move if not below or equal (CF=0 and ZF=0).
DB D8+i
FCMOVNU ST(0), ST(i)
Valid
Valid
Move if not unordered (PF=0).
NOTES:
1. See IA-32 Architecture Compatibility section below.
Description
Tests the status flags in the EFLAGS register and moves the source operand (second operand) to the destination
operand (first operand) if the given test condition is true. The condition for each mnemonic os given in the Descrip-
tion column above and in Chapter 8 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume
1. The source operand is always in the ST(i) register and the destination operand is always ST(0).
The FCMOVcc instructions are useful for optimizing small IF constructions. They also help eliminate branching over-
head for IF operations and the possibility of branch mispredictions by the processor.
A processor may not support the FCMOVcc instructions. Software can check if the FCMOVcc instructions are
supported by checking the processor’s feature information with the CPUID instruction (see “COMISS-Compare
Scalar Ordered Single Precision Floating-Point Values and Set EFLAGS” in this chapter). If both the CMOV and FPU
feature bits are set, the FCMOVcc instructions are supported.
This instruction’s operation is the same in non-64-bit modes and 64-bit mode.
IA-32 Architecture Compatibility
The FCMOVcc instructions were introduced to the IA-32 Architecture in the P6 family processors and are not avail-
able in earlier IA-32 processors.
Operation
IF condition TRUE
THEN ST(0) := ST(i);
FI;
FPU Flags Affected
C1
Set to 0 if stack underflow occurred.
C0, C2, C3
Undefined.
Floating-Point Exceptions
#IS
Stack underflow occurred.
Integer Flags Affected
None.
FCMOVcc-Floating-Point Conditional Move
Vol. 2A
3-322
Protected Mode Exceptions
#NM
CR0.EM[bit 2] or CR0.TS[bit 3] = 1.
#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.
FCMOVcc-Floating-Point Conditional Move
Vol. 2A
3-323
FCOM/FCOMP/FCOMPP-Compare Floating-Point Values
Opcode
Instruction
64-Bit
Compat/
Description
Mode
Leg Mode
D8 /2
FCOM m32fp
Valid
Valid
Compare ST(0) with m32fp.
DC /2
FCOM m64fp
Valid
Valid
Compare ST(0) with m64fp.
D8 D0+i
FCOM ST(i)
Valid
Valid
Compare ST(0) with ST(i).
D8 D1
FCOM
Valid
Valid
Compare ST(0) with ST(1).
D8 /3
FCOMP m32fp
Valid
Valid
Compare ST(0) with m32fp and pop register stack.
DC /3
FCOMP m64fp
Valid
Valid
Compare ST(0) with m64fp and pop register stack.
D8 D8+i
FCOMP ST(i)
Valid
Valid
Compare ST(0) with ST(i) and pop register stack.
D8 D9
FCOMP
Valid
Valid
Compare ST(0) with ST(1) and pop register stack.
DE D9
FCOMPP
Valid
Valid
Compare ST(0) with ST(1) and pop register stack
twice.
Description
Compares the contents of register ST(0) and source value and sets condition code flags C0, C2, and C3 in the FPU
status word according to the results (see the table below). The source operand can be a data register or a memory
location. If no source operand is given, the value in ST(0) is compared with the value in ST(1). The sign of zero is
ignored, so that -0.0 is equal to +0.0.
Table 3-23. FCOM/FCOMP/FCOMPP 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
NOTES:
* Flags not set if unmasked invalid-arithmetic-operand (#IA) exception is generated.
This instruction 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 unsupported format, an invalid-arithmetic-operand exception (#IA)
is raised and, if the exception is masked, the condition flags are set to “unordered.” If the invalid-arithmetic-
operand exception is unmasked, the condition code flags are not set.
The FCOMP instruction pops the register stack following the comparison operation and the FCOMPP 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.
The FCOM instructions perform the same operation as the FUCOM instructions. The only difference is how they
handle QNaN operands. The FCOM instructions raise an invalid-arithmetic-operand exception (#IA) when either or
both of the operands is a NaN value or is in an unsupported format. The FUCOM instructions perform the same
operation as the FCOM instructions, except that they do not generate an invalid-arithmetic-operand exception for
QNaNs.
This instruction’s operation is the same in non-64-bit modes and 64-bit mode.
FCOM/FCOMP/FCOMPP-Compare Floating-Point Values
Vol. 2A
3-324
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 = NaN or unsupported format
THEN
#IA
IF FPUControlWord.IM = 1
THEN
C3, C2, C0 := 111;
FI;
FI;
IF Instruction = FCOMP
THEN
PopRegisterStack;
FI;
IF Instruction = FCOMPP
THEN
PopRegisterStack;
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.
Register is marked empty.
#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.
FCOM/FCOMP/FCOMPP-Compare Floating-Point Values
Vol. 2A
3-325
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.
FCOM/FCOMP/FCOMPP-Compare Floating-Point Values
Vol. 2A
3-326
FCOMI/FCOMIP/FUCOMI/FUCOMIP-Compare Floating-Point Values and Set EFLAGS
Opcode
Instruction
64-Bit
Compat/
Description
Mode
Leg Mode
DB F0+i
FCOMI ST, ST(i)
Valid
Valid
Compare ST(0) with ST(i) and set status flags accordingly.
DF F0+i
FCOMIP ST, ST(i)
Valid
Valid
Compare ST(0) with ST(i), set status flags accordingly, and
pop register stack.
DB E8+i
FUCOMI ST, ST(i)
Valid
Valid
Compare ST(0) with ST(i), check for ordered values, and set
status flags accordingly.
DF E8+i
FUCOMIP ST, ST(i)
Valid
Valid
Compare ST(0) with ST(i), check for ordered values, set
status flags accordingly, and pop register stack.
Description
Performs an unordered comparison of the contents of registers ST(0) and ST(i) and sets the status flags ZF, PF, and
CF in the EFLAGS register according to the results (see the table below). The sign of zero is ignored for compari-
sons, so that -0.0 is equal to +0.0.
Table 3-24. FCOMI/FCOMIP/ FUCOMI/FUCOMIP Results
Comparison Results*
ZF
PF
CF
ST0 > ST(i)
0
0
0
ST0 < ST(i)
0
0
1
ST0 = ST(i)
1
0
0
Unordered**
1
1
1
NOTES:
* See the IA-32 Architecture Compatibility section below.
** 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 FUCOMI/FUCOMIP instructions perform the same operations as the FCOMI/FCOMIP instruc-
tions. The only difference is that the FUCOMI/FUCOMIP instructions raise the invalid-arithmetic-operand exception
(#IA) only when either or both operands are an SNaN or are in an unsupported format; QNaNs cause the condition
code flags to be set to unordered, but do not cause an exception to be generated. The FCOMI/FCOMIP 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.
If the operation results in an invalid-arithmetic-operand exception being raised, the status flags in the EFLAGS
register are set only if the exception is masked.
The FCOMI/FCOMIP and FUCOMI/FUCOMIP instructions set the OF, SF, and AF flags to zero in the EFLAGS register
(regardless of whether an invalid-operation exception is detected).
The FCOMIP and FUCOMIP instructions also pop the register stack 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.
IA-32 Architecture Compatibility
The FCOMI/FCOMIP/FUCOMI/FUCOMIP instructions were introduced to the IA-32 Architecture in the P6 family
processors and are not available in earlier IA-32 processors.
FCOMI/FCOMIP/ FUCOMI/FUCOMIP-Compare Floating-Point Values and Set EFLAGS
Vol. 2A
3-327
Operation
CASE (relation of operands) OF
ST(0) > ST(i):
ZF, PF, CF := 000;
ST(0) < ST(i):
ZF, PF, CF := 001;
ST(0) = ST(i):
ZF, PF, CF := 100;
ESAC;
IF Instruction is FCOMI or FCOMIP
THEN
IF ST(0) or ST(i) = NaN or unsupported format
THEN
#IA
IF FPUControlWord.IM = 1
THEN
ZF, PF, CF := 111;
FI;
FI;
FI;
IF Instruction is FUCOMI or FUCOMIP
THEN
IF ST(0) or ST(i) = QNaN, but not SNaN or unsupported format
THEN
ZF, PF, CF := 111;
ELSE (* ST(0) or ST(i) is SNaN or unsupported format *)
#IA;
IF FPUControlWord.IM = 1
THEN
ZF, PF, CF := 111;
FI;
FI;
FI;
IF Instruction is FCOMIP or FUCOMIP
THEN
PopRegisterStack;
FI;
FPU Flags Affected
C1
Set to 0.
C0, C2, C3
Not affected.
Floating-Point Exceptions
#IS
Stack underflow occurred.
#IA
(FCOMI or FCOMIP instruction) One or both operands are NaN values or have unsupported
formats.
(FUCOMI or FUCOMIP instruction) One or both operands are SNaN values (but not QNaNs) or
have undefined formats. Detection of a QNaN value does not raise an invalid-operand excep-
tion.
FCOMI/FCOMIP/ FUCOMI/FUCOMIP-Compare Floating-Point Values and Set EFLAGS
Vol. 2A
3-328
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.
FCOMI/FCOMIP/ FUCOMI/FUCOMIP-Compare Floating-Point Values and Set EFLAGS
Vol. 2A
3-329
FCOS-Cosine
Opcode
Instruction
64-Bit
Compat/
Description
Mode
Leg Mode
D9 FF
FCOS
Valid
Valid
Replace ST(0) with its approximate cosine.
Description
Computes the approximate cosine 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 cosine of various classes of numbers.
Table 3-25. FCOS Results
ST(0) SRC
ST(0) DEST
- ∞
*
- F
-1 to +1
− 0
+ 1
+ 0
+ 1
+ F
- 1 to + 1
+ ∞
*
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 2π.
However, even within the range -263 to +263, inaccurate results can occur because the finite approximation of π
used internally for argument reduction is not sufficient in all cases. Therefore, for accurate results it is safe to apply
FCOS only to arguments reduced accurately in software, to a value smaller in absolute value than 3π/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 π 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;
ST(0) := FCOS(ST(0)); // approximation of cosine
ELSE (* Source operand is out-of-range *)
C2 := 1;
FI;
FCOS-Cosine
Vol. 2A
3-330
FPU Flags Affected
C1
Set to 0 if stack underflow occurred.
Set if result was rounded up; cleared otherwise.
Undefined if C2 is 1.
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, ∞, or unsupported format.
#D
Source 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.
FCOS-Cosine
Vol. 2A
3-331
FDECSTP-Decrement Stack-Top Pointer
Opcode
Instruction
64-Bit
Compat/
Description
Mode
Leg Mode
D9 F6
FDECSTP
Valid
Valid
Decrement TOP field in FPU status word.
Description
Subtracts one from the TOP field of the FPU status word (decrements the top-of-stack pointer). If the TOP field
contains a 0, it is set to 7. 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 instruction’s operation is the same in non-64-bit modes and 64-bit mode.
Operation
IF TOP = 0
THEN TOP := 7;
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.
FDECSTP-Decrement Stack-Top Pointer
Vol. 2A
3-332
FDIV/FDIVP/FIDIV-Divide
Opcode
Instruction
64-Bit
Compat/
Description
Mode
Leg Mode
D8 /6
FDIV m32fp
Valid
Valid
Divide ST(0) by m32fp and store result in ST(0).
DC /6
FDIV m64fp
Valid
Valid
Divide ST(0) by m64fp and store result in ST(0).
D8 F0+i
FDIV ST(0), ST(i)
Valid
Valid
Divide ST(0) by ST(i) and store result in ST(0).
DC F8+i
FDIV ST(i), ST(0)
Valid
Valid
Divide ST(i) by ST(0) and store result in ST(i).
DE F8+i
FDIVP ST(i), ST(0)
Valid
Valid
Divide ST(i) by ST(0), store result in ST(i), and pop the
register stack.
DE F9
FDIVP
Valid
Valid
Divide ST(1) by ST(0), store result in ST(1), and pop
the register stack.
DA /6
FIDIV m32int
Valid
Valid
Divide ST(0) by m32int and store result in ST(0).
DE /6
FIDIV m16int
Valid
Valid
Divide ST(0) by m16int and store result in ST(0).
Description
Divides the destination operand by the source operand and stores the result in the destination location. The desti-
nation operand (dividend) is always in an FPU register; the source operand (divisor) can be a register or a memory
location. Source operands in memory can be in single precision or double precision floating-point format, word or
doubleword integer format.
The no-operand version of the instruction divides the contents of the ST(1) register by the contents of the ST(0)
register. The one-operand version divides the contents of the ST(0) register by the contents of a memory location
(either a floating-point or an integer value). The two-operand version, divides the contents of the ST(0) register by
the contents of the ST(i) register or vice versa.
The FDIVP instructions perform the additional operation of popping the FPU register stack after storing the result.
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 divide instructions always results in the register stack being
popped. In some assemblers, the mnemonic for this instruction is FDIV rather than FDIVP.
The FIDIV instructions convert an integer source operand to double extended-precision floating-point format
before performing the division. When the source operand is an integer 0, it is treated as a +0.
If an unmasked divide-by-zero exception (#Z) is generated, no result is stored; if the exception is masked, an ∞ of
the appropriate sign is stored in the destination operand.
The following table shows the results obtained when dividing various classes of numbers, assuming that neither
overflow nor underflow occurs.
FDIV/FDIVP/FIDIV-Divide
Vol. 2A
3-333
Table 3-26. FDIV/FDIVP/FIDIV Results
DEST
- ∞
- F
- 0
+ 0
+ F
+ ∞
NaN
− ∞
*
+ 0
+ 0
- 0
- 0
*
NaN
− F
+ ∞
+ F
+ 0
- 0
- F
- ∞
NaN
− I
+ ∞
+ F
+ 0
- 0
- F
- ∞
NaN
SRC
- 0
+ ∞
**
*
*
**
- ∞
NaN
+ 0
- ∞
**
*
*
**
+ ∞
NaN
+ I
- ∞
- F
- 0
+ 0
+ F
+ ∞
NaN
+ F
- ∞
- F
- 0
+ 0
+ F
+ ∞
NaN
+ ∞
*
- 0
- 0
+ 0
+ 0
*
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.
** Indicates floating-point zero-divide (#Z) exception.
This instruction’s operation is the same in non-64-bit modes and 64-bit mode.
Operation
IF SRC = 0
THEN
#Z;
ELSE
IF Instruction is FIDIV
THEN
DEST := DEST / ConvertToDoubleExtendedPrecisionFP(SRC);
ELSE (* Source operand is floating-point value *)
DEST := DEST / SRC;
FI;
FI;
IF Instruction = FDIVP
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.
FDIV/FDIVP/FIDIV-Divide
Vol. 2A
3-334
|
||
|
|
|