Intel 64 and IA-32 Architectures. Software Developer’s Manual (Collection, 2023) - page 96

 

  Index      Manuals     Intel 64 and IA-32 Architectures. Software Developer’s Manual (Collection, 2023)

 

Search            copyright infringement  

 

   

 

   

 

Content      ..     94      95      96      97     ..

 

 

 

Intel 64 and IA-32 Architectures. Software Developer’s Manual (Collection, 2023) - page 96

 

 

INSTRUCTION SET REFERENCE, V
VFCMULCSH/VFMULCSH—Complex Multiply Scalar FP16 Values
Opcode/
Op/
64/32
CPUID Feature
Description
Instruction
En
bit Mode
Flag
Support
EVEX.LLIG.F2.MAP6.W0 D7 /r
A
V/V
AVX512-FP16
Complex multiply a pair of FP16 values from
VFCMULCSH xmm1{k1}{z}, xmm2,
xmm2 and xmm3/m32, and store the result in
xmm3/m32 {er}
xmm1 subject to writemask k1. Bits 127:32 of
xmm2 are copied to xmm1[127:32].
EVEX.LLIG.F3.MAP6.W0 D7 /r
A
V/V
AVX512-FP16
Complex multiply a pair of FP16 values from
VFMULCSH xmm1{k1}{z}, xmm2,
xmm2 and the complex conjugate of xmm3/m32,
xmm3/m32 {er}
and store the result in xmm1 subject to
writemask k1. Bits 127:32 of xmm2 are copied to
xmm1[127:32].
Instruction Operand Encoding
Op/En
Tuple
Operand 1
Operand 2
Operand 3
Operand 4
A
Scalar
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
This instruction performs a complex multiply operation. There are normal and complex conjugate forms of the oper-
ation. The masking for this operation is done on 32-bit quantities representing a pair of FP16 values.
Bits 127:32 of the destination operand are copied from the corresponding bits of the first source operand. Bits
MAXVL-1:128 of the destination operand are zeroed. The low FP16 element of the destination is updated according
to the writemask.
Rounding is performed at every FMA (fused multiply and add) boundary. Execution occurs as if all MXCSR excep-
tions are masked. MXCSR status bits are updated to reflect exceptional conditions.
Operation
VFMULCSH dest{k1}, src1, src2 (AVX512)
KL := VL / 32
IF k1[0] or *no writemask*:
// non-conjugate version subtracts last even term
tmp.fp16[0] := src1.fp16[0] * src2.fp16[0]
tmp.fp16[1] := src1.fp16[1] * src2.fp16[0]
dest.fp16[0] := tmp.fp16[0] - src1.fp16[1] * src2.fp16[1]
dest.fp16[1] := tmp.fp16[1] + src1.fp16[0] * src2.fp16[1]
ELSE IF *zeroing*:
dest.fp16[0] := 0
dest.fp16[1] := 0
DEST[127:32] := src1[127:32] // copy upper part of src1
DEST[MAXVL-1:128] := 0
VFCMULCSH/VFMULCSH—Complex Multiply Scalar FP16 Values
Vol. 2C
5-177
INSTRUCTION SET REFERENCE, V
VFCMULCSH dest{k1}, src1, src2 (AVX512)
KL := VL / 32
IF k1[0] or *no writemask*:
tmp.fp16[0] := src1.fp16[0] * src2.fp16[0]
tmp.fp16[1] := src1.fp16[1] * src2.fp16[0]
// conjugate version subtracts odd final term
dest.fp16[0] := tmp.fp16[0] + src1.fp16[1] * src2.fp16[1]
dest.fp16[1] := tmp.fp16[1] - src1.fp16[0] * src2.fp16[1]
ELSE IF *zeroing*:
dest.fp16[0] := 0
dest.fp16[1] := 0
DEST[127:32] := src1[127:32] // copy upper part of src1
DEST[MAXVL-1:128] := 0
Intel C/C++ Compiler Intrinsic Equivalent
VFCMULCSH __m128h _mm_cmul_round_sch (__m128h a, __m128h b, const int rounding);
VFCMULCSH __m128h _mm_mask_cmul_round_sch (__m128h src, __mmask8 k, __m128h a, __m128h b, const int rounding);
VFCMULCSH __m128h _mm_maskz_cmul_round_sch (__mmask8 k, __m128h a, __m128h b, const int rounding);
VFCMULCSH __m128h _mm_cmul_sch (__m128h a, __m128h b);
VFCMULCSH __m128h _mm_mask_cmul_sch (__m128h src, __mmask8 k, __m128h a, __m128h b);
VFCMULCSH __m128h _mm_maskz_cmul_sch (__mmask8 k, __m128h a, __m128h b);
VFCMULCSH __m128h _mm_fcmul_round_sch (__m128h a, __m128h b, const int rounding);
VFCMULCSH __m128h _mm_mask_fcmul_round_sch (__m128h src, __mmask8 k, __m128h a, __m128h b, const int rounding);
VFCMULCSH __m128h _mm_maskz_fcmul_round_sch (__mmask8 k, __m128h a, __m128h b, const int rounding);
VFCMULCSH __m128h _mm_fcmul_sch (__m128h a, __m128h b);
VFCMULCSH __m128h _mm_mask_fcmul_sch (__m128h src, __mmask8 k, __m128h a, __m128h b);
VFCMULCSH __m128h _mm_maskz_fcmul_sch (__mmask8 k, __m128h a, __m128h b);
VFMULCSH __m128h _mm_fmul_round_sch (__m128h a, __m128h b, const int rounding);
VFMULCSH __m128h _mm_mask_fmul_round_sch (__m128h src, __mmask8 k, __m128h a, __m128h b, const int rounding);
VFMULCSH __m128h _mm_maskz_fmul_round_sch (__mmask8 k, __m128h a, __m128h b, const int rounding);
VFMULCSH __m128h _mm_fmul_sch (__m128h a, __m128h b);
VFMULCSH __m128h _mm_mask_fmul_sch (__m128h src, __mmask8 k, __m128h a, __m128h b);
VFMULCSH __m128h _mm_maskz_fmul_sch (__mmask8 k, __m128h a, __m128h b);
VFMULCSH __m128h _mm_mask_mul_round_sch (__m128h src, __mmask8 k, __m128h a, __m128h b, const int rounding);
VFMULCSH __m128h _mm_maskz_mul_round_sch (__mmask8 k, __m128h a, __m128h b, const int rounding);
VFMULCSH __m128h _mm_mul_round_sch (__m128h a, __m128h b, const int rounding);
VFMULCSH __m128h _mm_mask_mul_sch (__m128h src, __mmask8 k, __m128h a, __m128h b);
VFMULCSH __m128h _mm_maskz_mul_sch (__mmask8 k, __m128h a, __m128h b);
VFMULCSH __m128h _mm_mul_sch (__m128h a, __m128h b);
SIMD Floating-Point Exceptions
Invalid, Underflow, Overflow, Precision, Denormal
Other Exceptions
EVEX-encoded instructions, see Table 2-58, “Type E10 Class Exception Conditions.”
Additionally:
#UD
If (dest_reg == src1_reg) or (dest_reg == src2_reg).
5-178
Vol. 2C
VFCMULCSH/VFMULCSH—Complex Multiply Scalar FP16 Values
INSTRUCTION SET REFERENCE, V
VFIXUPIMMPD—Fix Up Special Packed Float64 Values
Opcode/
Op /
64/32
CPUID
Description
Instruction
En
bit Mode
Feature
Support
Flag
EVEX.128.66.0F3A.W1 54 /r ib
A
V/V
AVX512VL
Fix up special numbers in float64 vector xmm1, float64
VFIXUPIMMPD xmm1 {k1}{z}, xmm2,
AVX512F
vector xmm2 and int64 vector xmm3/m128/m64bcst
xmm3/m128/m64bcst, imm8
and store the result in xmm1, under writemask.
EVEX.256.66.0F3A.W1 54 /r ib
A
V/V
AVX512VL
Fix up special numbers in float64 vector ymm1, float64
VFIXUPIMMPD ymm1 {k1}{z}, ymm2,
AVX512F
vector ymm2 and int64 vector ymm3/m256/m64bcst
ymm3/m256/m64bcst, imm8
and store the result in ymm1, under writemask.
EVEX.512.66.0F3A.W1 54 /r ib
A
V/V
AVX512F
Fix up elements of float64 vector in zmm2 using int64
VFIXUPIMMPD zmm1 {k1}{z}, zmm2,
vector table in zmm3/m512/m64bcst, combine with
zmm3/m512/m64bcst{sae}, imm8
preserved elements from zmm1, and store the result in
zmm1.
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
Full
ModRM:reg (r, w)
EVEX.vvvv (r)
ModRM:r/m (r)
imm8
Description
Perform fix-up of quad-word elements encoded in double precision floating-point format in the first source operand
(the second operand) using a 32-bit, two-level look-up table specified in the corresponding quadword element of
the second source operand (the third operand) with exception reporting specifier imm8. The elements that are
fixed-up are selected by mask bits of 1 specified in the opmask k1. Mask bits of 0 in the opmask k1 or table
response action of 0000b preserves the corresponding element of the first operand. The fixed-up elements from
the first source operand and the preserved element in the first operand are combined as the final results in the
destination operand (the first operand).
The destination and the first source operands are ZMM/YMM/XMM registers. 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 two-level look-up table perform a fix-up of each double precision floating-point input data in the first source
operand by decoding the input data encoding into 8 token types. A response table is defined for each token type
that converts the input encoding in the first source operand with one of 16 response actions.
This instruction is specifically intended for use in fixing up the results of arithmetic calculations involving one source
so that they match the spec, although it is generally useful for fixing up the results of multiple-instruction
sequences to reflect special-number inputs. For example, consider rcp(0). Input 0 to rcp, and you should get INF
according to the DX10 spec. However, evaluating rcp via Newton-Raphson, where x=approx(1/0), yields an incor-
rect result. To deal with this, VFIXUPIMMPD can be used after the N-R reciprocal sequence to set the result to the
correct value (i.e., INF when the input is 0).
If MXCSR.DAZ is not set, denormal input elements in the first source operand are considered as normal inputs and
do not trigger any fixup nor fault reporting.
Imm8 is used to set the required flags reporting. It supports #ZE and #IE fault reporting (see details below).
MXCSR mask bits are ignored and are treated as if all mask bits are set to masked response). If any of the imm8
bits is set and the condition met for fault reporting, MXCSR.IE or MXCSR.ZE might be updated.
This instruction is writemasked, so only those elements with the corresponding bit set in vector mask register k1
are computed and stored into zmm1. Elements in the destination with the corresponding bit clear in k1 retain their
previous values or are set to 0.
VFIXUPIMMPD—Fix Up Special Packed Float64 Values
Vol. 2C
5-179
INSTRUCTION SET REFERENCE, V
Operation
enum TOKEN_TYPE
{
QNAN_TOKEN := 0,
SNAN_TOKEN := 1,
ZERO_VALUE_TOKEN := 2,
POS_ONE_VALUE_TOKEN := 3,
NEG_INF_TOKEN := 4,
POS_INF_TOKEN := 5,
NEG_VALUE_TOKEN := 6,
POS_VALUE_TOKEN := 7
}
FIXUPIMM_DP (dest[63:0], src1[63:0],tbl3[63:0], imm8 [7:0]){
tsrc[63:0] := ((src1[62:52] = 0) AND (MXCSR.DAZ =1)) ? 0.0 : src1[63:0]
CASE(tsrc[63:0] of TOKEN_TYPE) {
QNAN_TOKEN: j := 0;
SNAN_TOKEN: j := 1;
ZERO_VALUE_TOKEN: j := 2;
POS_ONE_VALUE_TOKEN: j := 3;
NEG_INF_TOKEN: j := 4;
POS_INF_TOKEN: j := 5;
NEG_VALUE_TOKEN: j := 6;
POS_VALUE_TOKEN: j := 7;
}
; end source special CASE(tsrc…)
; The required response from src3 table is extracted
token_response[3:0] = tbl3[3+4*j:4*j];
CASE(token_response[3:0]) {
0000: dest[63:0] := dest[63:0];
; preserve content of DEST
0001: dest[63:0] := tsrc[63:0];
; pass through src1 normal input value, denormal as zero
0010: dest[63:0] := QNaN(tsrc[63:0]);
0011: dest[63:0] := QNAN_Indefinite;
0100: dest[63:0] := -INF;
0101: dest[63:0] := +INF;
0110: dest[63:0] := tsrc.sign? -INF : +INF;
0111: dest[63:0] := -0;
1000: dest[63:0] := +0;
1001: dest[63:0] := -1;
1010: dest[63:0] := +1;
1011: dest[63:0] := ½;
1100: dest[63:0] := 90.0;
1101: dest[63:0] := PI/2;
1110: dest[63:0] := MAX_FLOAT;
1111: dest[63:0] := -MAX_FLOAT;
}
; end of token_response CASE
; The required fault reporting from imm8 is extracted
; TOKENs are mutually exclusive and TOKENs priority defines the order.
; Multiple faults related to a single token can occur simultaneously.
IF (tsrc[63:0] of TOKEN_TYPE: ZERO_VALUE_TOKEN) AND imm8[0] then set #ZE;
IF (tsrc[63:0] of TOKEN_TYPE: ZERO_VALUE_TOKEN) AND imm8[1] then set #IE;
IF (tsrc[63:0] of TOKEN_TYPE: ONE_VALUE_TOKEN) AND imm8[2] then set #ZE;
5-180
Vol. 2C
VFIXUPIMMPD—Fix Up Special Packed Float64 Values
INSTRUCTION SET REFERENCE, V
IF (tsrc[63:0] of TOKEN_TYPE: ONE_VALUE_TOKEN) AND imm8[3] then set #IE;
IF (tsrc[63:0] of TOKEN_TYPE: SNAN_TOKEN) AND imm8[4] then set #IE;
IF (tsrc[63:0] of TOKEN_TYPE: NEG_INF_TOKEN) AND imm8[5] then set #IE;
IF (tsrc[63:0] of TOKEN_TYPE: NEG_VALUE_TOKEN) AND imm8[6] then set #IE;
IF (tsrc[63:0] of TOKEN_TYPE: POS_INF_TOKEN) AND imm8[7] then set #IE;
; end fault reporting
return dest[63:0];
}
; end of FIXUPIMM_DP()
VFIXUPIMMPD
(KL, VL) = (2, 128), (4, 256), (8, 512)
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] := FIXUPIMM_DP(DEST[i+63:i], SRC1[i+63:i], SRC2[63:0], imm8 [7:0])
ELSE
DEST[i+63:i] := FIXUPIMM_DP(DEST[i+63:i], SRC1[i+63:i], SRC2[i+63:i], imm8 [7:0])
FI;
ELSE
IF *merging-masking*
; merging-masking
THEN *DEST[i+63:i] remains unchanged*
ELSE DEST[i+63:i] := 0
; zeroing-masking
FI
FI;
ENDFOR
DEST[MAXVL-1:VL] := 0
Immediate Control Description:
7
6
5
4
3
2
1
0
+ INF ˘
#IE
- VE ˘
#IE
- INF ˘
#IE
SNaN ˘
#IE
ONE ˘
#IE
ONE ˘
#ZE
ZERO ˘
#IE
ZERO ˘
#ZE
Figure 5-9. VFIXUPIMMPD Immediate Control Description
VFIXUPIMMPD—Fix Up Special Packed Float64 Values
Vol. 2C
5-181
INSTRUCTION SET REFERENCE, V
Intel C/C++ Compiler Intrinsic Equivalent
VFIXUPIMMPD __m512d _mm512_fixupimm_pd( __m512d a, __m512i tbl, int imm);
VFIXUPIMMPD __m512d _mm512_mask_fixupimm_pd(__m512d s, __mmask8 k, __m512d a, __m512i tbl, int imm);
VFIXUPIMMPD __m512d _mm512_maskz_fixupimm_pd( __mmask8 k, __m512d a, __m512i tbl, int imm);
VFIXUPIMMPD __m512d _mm512_fixupimm_round_pd( __m512d a, __m512i tbl, int imm, int sae);
VFIXUPIMMPD __m512d _mm512_mask_fixupimm_round_pd(__m512d s, __mmask8 k, __m512d a, __m512i tbl, int imm, int sae);
VFIXUPIMMPD __m512d _mm512_maskz_fixupimm_round_pd( __mmask8 k, __m512d a, __m512i tbl, int imm, int sae);
VFIXUPIMMPD __m256d _mm256_fixupimm_pd( __m256d a, m256d b, __m256i c, int imm8);
VFIXUPIMMPD __m256d _mm256_mask_fixupimm_pd(__m256d a, __mmask8 k, __m256d b, __m256i c, int imm8);
VFIXUPIMMPD __m256d _mm256_maskz_fixupimm_pd( __mmask8 k, __m256d a, __m256d b, __m256i c, int imm8);
VFIXUPIMMPD __m128d _mm_fixupimm_pd( __m128d a, __m128d b, __m128i c, int imm8);
VFIXUPIMMPD __m128d _mm_mask_fixupimm_pd(__m128d a, __mmask8 k, __m128d b, __m128i c, int imm8);
VFIXUPIMMPD __m128d _mm_maskz_fixupimm_pd( __mmask8 k, __m128d a, __m128d b, 128ic, int imm8);
SIMD Floating-Point Exceptions
Zero, Invalid
Other Exceptions
See Table 2-46, “Type E2 Class Exception Conditions.”
5-182
Vol. 2C
VFIXUPIMMPD—Fix Up Special Packed Float64 Values
INSTRUCTION SET REFERENCE, V
VFIXUPIMMPS—Fix Up Special Packed Float32 Values
Opcode/
Op /
64/32
CPUID
Description
Instruction
En
bit Mode
Feature
Support
Flag
EVEX.128.66.0F3A.W0 54 /r
A
V/V
AVX512VL
Fix up special numbers in float32 vector xmm1, float32
VFIXUPIMMPS xmm1 {k1}{z}, xmm2,
AVX512F
vector xmm2 and int32 vector xmm3/m128/m32bcst
xmm3/m128/m32bcst, imm8
and store the result in xmm1, under writemask.
EVEX.256.66.0F3A.W0 54 /r
A
V/V
AVX512VL
Fix up special numbers in float32 vector ymm1, float32
VFIXUPIMMPS ymm1 {k1}{z}, ymm2,
AVX512F
vector ymm2 and int32 vector ymm3/m256/m32bcst
ymm3/m256/m32bcst, imm8
and store the result in ymm1, under writemask.
EVEX.512.66.0F3A.W0 54 /r ib
A
V/V
AVX512F
Fix up elements of float32 vector in zmm2 using int32
VFIXUPIMMPS zmm1 {k1}{z}, zmm2,
vector table in zmm3/m512/m32bcst, combine with
zmm3/m512/m32bcst{sae}, imm8
preserved elements from zmm1, and store the result in
zmm1.
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
Full
ModRM:reg (r, w)
EVEX.vvvv (r)
ModRM:r/m (r)
imm8
Description
Perform fix-up of doubleword elements encoded in single precision floating-point format in the first source operand
(the second operand) using a 32-bit, two-level look-up table specified in the corresponding doubleword element of
the second source operand (the third operand) with exception reporting specifier imm8. The elements that are
fixed-up are selected by mask bits of 1 specified in the opmask k1. Mask bits of 0 in the opmask k1 or table
response action of 0000b preserves the corresponding element of the first operand. The fixed-up elements from
the first source operand and the preserved element in the first operand are combined as the final results in the
destination operand (the first operand).
The destination and the first source operands are ZMM/YMM/XMM registers. 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 two-level look-up table perform a fix-up of each single precision floating-point input data in the first source
operand by decoding the input data encoding into 8 token types. A response table is defined for each token type
that converts the input encoding in the first source operand with one of 16 response actions.
This instruction is specifically intended for use in fixing up the results of arithmetic calculations involving one source
so that they match the spec, although it is generally useful for fixing up the results of multiple-instruction
sequences to reflect special-number inputs. For example, consider rcp(0). Input 0 to rcp, and you should get INF
according to the DX10 spec. However, evaluating rcp via Newton-Raphson, where x=approx(1/0), yields an incor-
rect result. To deal with this, VFIXUPIMMPS can be used after the N-R reciprocal sequence to set the result to the
correct value (i.e., INF when the input is 0).
If MXCSR.DAZ is not set, denormal input elements in the first source operand are considered as normal inputs and
do not trigger any fixup nor fault reporting.
Imm8 is used to set the required flags reporting. It supports #ZE and #IE fault reporting (see details below).
MXCSR.DAZ is used and refer to zmm2 only (i.e., zmm1 is not considered as zero in case MXCSR.DAZ is set).
MXCSR mask bits are ignored and are treated as if all mask bits are set to masked response). If any of the imm8
bits is set and the condition met for fault reporting, MXCSR.IE or MXCSR.ZE might be updated.
VFIXUPIMMPS—Fix Up Special Packed Float32 Values
Vol. 2C
5-183
INSTRUCTION SET REFERENCE, V
Operation
enum TOKEN_TYPE
{
QNAN_TOKEN := 0,
SNAN_TOKEN := 1,
ZERO_VALUE_TOKEN := 2,
POS_ONE_VALUE_TOKEN := 3,
NEG_INF_TOKEN := 4,
POS_INF_TOKEN := 5,
NEG_VALUE_TOKEN := 6,
POS_VALUE_TOKEN := 7
}
FIXUPIMM_SP ( dest[31:0], src1[31:0],tbl3[31:0], imm8 [7:0]){
tsrc[31:0] := ((src1[30:23] = 0) AND (MXCSR.DAZ =1)) ? 0.0 : src1[31:0]
CASE(tsrc[31:0] of TOKEN_TYPE) {
QNAN_TOKEN: j := 0;
SNAN_TOKEN: j := 1;
ZERO_VALUE_TOKEN: j := 2;
POS_ONE_VALUE_TOKEN: j := 3;
NEG_INF_TOKEN: j := 4;
POS_INF_TOKEN: j := 5;
NEG_VALUE_TOKEN: j := 6;
POS_VALUE_TOKEN: j := 7;
}
; end source special CASE(tsrc…)
; The required response from src3 table is extracted
token_response[3:0] = tbl3[3+4*j:4*j];
CASE(token_response[3:0]) {
0000: dest[31:0] := dest[31:0];
; preserve content of DEST
0001: dest[31:0] := tsrc[31:0];
; pass through src1 normal input value, denormal as zero
0010: dest[31:0] := QNaN(tsrc[31:0]);
0011: dest[31:0] := QNAN_Indefinite;
0100: dest[31:0] := -INF;
0101: dest[31:0] := +INF;
0110: dest[31:0] := tsrc.sign? -INF : +INF;
0111: dest[31:0] := -0;
1000: dest[31:0] := +0;
1001: dest[31:0] := -1;
1010: dest[31:0] := +1;
1011: dest[31:0] := ½;
1100: dest[31:0] := 90.0;
1101: dest[31:0] := PI/2;
1110: dest[31:0] := MAX_FLOAT;
1111: dest[31:0] := -MAX_FLOAT;
}
; end of token_response CASE
; The required fault reporting from imm8 is extracted
; TOKENs are mutually exclusive and TOKENs priority defines the order.
; Multiple faults related to a single token can occur simultaneously.
IF (tsrc[31:0] of TOKEN_TYPE: ZERO_VALUE_TOKEN) AND imm8[0] then set #ZE;
IF (tsrc[31:0] of TOKEN_TYPE: ZERO_VALUE_TOKEN) AND imm8[1] then set #IE;
IF (tsrc[31:0] of TOKEN_TYPE: ONE_VALUE_TOKEN) AND imm8[2] then set #ZE;
5-184
Vol. 2C
VFIXUPIMMPS—Fix Up Special Packed Float32 Values
INSTRUCTION SET REFERENCE, V
IF (tsrc[31:0] of TOKEN_TYPE: ONE_VALUE_TOKEN) AND imm8[3] then set #IE;
IF (tsrc[31:0] of TOKEN_TYPE: SNAN_TOKEN) AND imm8[4] then set #IE;
IF (tsrc[31:0] of TOKEN_TYPE: NEG_INF_TOKEN) AND imm8[5] then set #IE;
IF (tsrc[31:0] of TOKEN_TYPE: NEG_VALUE_TOKEN) AND imm8[6] then set #IE;
IF (tsrc[31:0] of TOKEN_TYPE: POS_INF_TOKEN) AND imm8[7] then set #IE;
; end fault reporting
return dest[31:0];
}
; end of FIXUPIMM_SP()
VFIXUPIMMPS (EVEX)
(KL, VL) = (4, 128), (8, 256), (16, 512)
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] := FIXUPIMM_SP(DEST[i+31:i], SRC1[i+31:i], SRC2[31:0], imm8 [7:0])
ELSE
DEST[i+31:i] := FIXUPIMM_SP(DEST[i+31:i], SRC1[i+31:i], SRC2[i+31:i], imm8 [7:0])
FI;
ELSE
IF *merging-masking*
; merging-masking
THEN *DEST[i+31:i] remains unchanged*
ELSE DEST[i+31:i] := 0
; zeroing-masking
FI
FI;
ENDFOR
DEST[MAXVL-1:VL] := 0
Immediate Control Description:
7
6
5
4
3
2
1
0
+ INF ˘
#IE
- VE ˘
#IE
- INF ˘
#IE
SNaN ˘
#IE
ONE ˘
#IE
ONE ˘
#ZE
ZERO ˘
#IE
ZERO ˘
#ZE
Figure 5-10. VFIXUPIMMPS Immediate Control Description
VFIXUPIMMPS—Fix Up Special Packed Float32 Values
Vol. 2C
5-185
INSTRUCTION SET REFERENCE, V
Intel C/C++ Compiler Intrinsic Equivalent
VFIXUPIMMPS __m512 _mm512_fixupimm_ps( __m512 a, __m512i tbl, int imm);
VFIXUPIMMPS __m512 _mm512_mask_fixupimm_ps(__m512 s, __mmask16 k, __m512 a, __m512i tbl, int imm);
VFIXUPIMMPS __m512 _mm512_maskz_fixupimm_ps( __mmask16 k, __m512 a, __m512i tbl, int imm);
VFIXUPIMMPS __m512 _mm512_fixupimm_round_ps( __m512 a, __m512i tbl, int imm, int sae);
VFIXUPIMMPS __m512 _mm512_mask_fixupimm_round_ps(__m512 s, __mmask16 k, __m512 a, __m512i tbl, int imm, int sae);
VFIXUPIMMPS __m512 _mm512_maskz_fixupimm_round_ps( __mmask16 k, __m512 a, __m512i tbl, int imm, int sae);
VFIXUPIMMPS __m256 _mm256_fixupimm_ps( __m256 a, __m256 b, __m256i c, int imm8);
VFIXUPIMMPS __m256 _mm256_mask_fixupimm_ps(__m256 a, __mmask8 k, __m256 b, __m256i c, int imm8);
VFIXUPIMMPS __m256 _mm256_maskz_fixupimm_ps( __mmask8 k, __m256 a, __m256b, __m256i c, int imm8);
VFIXUPIMMPS __m128 _mm_fixupimm_ps( __m128 a, __m128 b, 128i c, int imm8);
VFIXUPIMMPS __m128 _mm_mask_fixupimm_ps(__m128 a, __mmask8 k, __m128 b, __m128i c, int imm8);
VFIXUPIMMPS __m128 _mm_maskz_fixupimm_ps( __mmask8 k, __m128 a, __m128 b, __m128i c, int imm8);
SIMD Floating-Point Exceptions
Zero, Invalid
Other Exceptions
See Table 2-46, “Type E2 Class Exception Conditions.”
5-186
Vol. 2C
VFIXUPIMMPS—Fix Up Special Packed Float32 Values
INSTRUCTION SET REFERENCE, V
VFIXUPIMMSD—Fix Up Special Scalar Float64 Value
Opcode/
Op /
64/32
CPUID
Description
Instruction
En
bit Mode
Feature
Support
Flag
EVEX.LLIG.66.0F3A.W1 55 /r ib
A
V/V
AVX512F
Fix up a float64 number in the low quadword element of
VFIXUPIMMSD xmm1 {k1}{z},
xmm2 using scalar int32 table in xmm3/m64 and store the
xmm2, xmm3/m64{sae}, imm8
result in xmm1.
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
Tuple1 Scalar
ModRM:reg (r, w)
EVEX.vvvv (r)
ModRM:r/m (r)
imm8
Description
Perform a fix-up of the low quadword element encoded in double precision floating-point format in the first source
operand (the second operand) using a 32-bit, two-level look-up table specified in the low quadword element of the
second source operand (the third operand) with exception reporting specifier imm8. The element that is fixed-up
is selected by mask bit of 1 specified in the opmask k1. Mask bit of 0 in the opmask k1 or table response action of
0000b preserves the corresponding element of the first operand. The fixed-up element from the first source
operand or the preserved element in the first operand becomes the low quadword element of the destination
operand (the first operand). Bits 127:64 of the destination operand is copied from the corresponding bits of the
first source operand. The destination and first source operands are XMM registers. The second source operand can
be a XMM register or a 64- bit memory location.
The two-level look-up table perform a fix-up of each double precision floating-point input data in the first source
operand by decoding the input data encoding into 8 token types. A response table is defined for each token type
that converts the input encoding in the first source operand with one of 16 response actions.
This instruction is specifically intended for use in fixing up the results of arithmetic calculations involving one source
so that they match the spec, although it is generally useful for fixing up the results of multiple-instruction
sequences to reflect special-number inputs. For example, consider rcp(0). Input 0 to rcp, and you should get INF
according to the DX10 spec. However, evaluating rcp via Newton-Raphson, where x=approx(1/0), yields an incor-
rect result. To deal with this, VFIXUPIMMPD can be used after the N-R reciprocal sequence to set the result to the
correct value (i.e., INF when the input is 0).
If MXCSR.DAZ is not set, denormal input elements in the first source operand are considered as normal inputs and
do not trigger any fixup nor fault reporting.
Imm8 is used to set the required flags reporting. It supports #ZE and #IE fault reporting (see details below).
MXCSR.DAZ is used and refer to zmm2 only (i.e., zmm1 is not considered as zero in case MXCSR.DAZ is set).
MXCSR mask bits are ignored and are treated as if all mask bits are set to masked response). If any of the imm8
bits is set and the condition met for fault reporting, MXCSR.IE or MXCSR.ZE might be updated.
Operation
enum TOKEN_TYPE
{
QNAN_TOKEN := 0,
SNAN_TOKEN := 1,
ZERO_VALUE_TOKEN := 2,
POS_ONE_VALUE_TOKEN := 3,
NEG_INF_TOKEN := 4,
POS_INF_TOKEN := 5,
NEG_VALUE_TOKEN := 6,
POS_VALUE_TOKEN := 7
}
VFIXUPIMMSD—Fix Up Special Scalar Float64 Value
Vol. 2C
5-187
INSTRUCTION SET REFERENCE, V
FIXUPIMM_DP (dest[63:0], src1[63:0],tbl3[63:0], imm8 [7:0]){
tsrc[63:0] := ((src1[62:52] = 0) AND (MXCSR.DAZ =1)) ? 0.0 : src1[63:0]
CASE(tsrc[63:0] of TOKEN_TYPE) {
QNAN_TOKEN: j := 0;
SNAN_TOKEN: j := 1;
ZERO_VALUE_TOKEN: j := 2;
POS_ONE_VALUE_TOKEN: j := 3;
NEG_INF_TOKEN: j := 4;
POS_INF_TOKEN: j := 5;
NEG_VALUE_TOKEN: j := 6;
POS_VALUE_TOKEN: j := 7;
}
; end source special CASE(tsrc…)
; The required response from src3 table is extracted
token_response[3:0] = tbl3[3+4*j:4*j];
CASE(token_response[3:0]) {
0000: dest[63:0] := dest[63:0]
; preserve content of DEST
0001: dest[63:0] := tsrc[63:0];
; pass through src1 normal input value, denormal as zero
0010: dest[63:0] := QNaN(tsrc[63:0]);
0011: dest[63:0] := QNAN_Indefinite;
0100:dest[63:0] := -INF;
0101: dest[63:0] := +INF;
0110: dest[63:0] := tsrc.sign? -INF : +INF;
0111: dest[63:0] := -0;
1000: dest[63:0] := +0;
1001: dest[63:0] := -1;
1010: dest[63:0] := +1;
1011: dest[63:0] := ½;
1100: dest[63:0] := 90.0;
1101: dest[63:0] := PI/2;
1110: dest[63:0] := MAX_FLOAT;
1111: dest[63:0] := -MAX_FLOAT;
}
; end of token_response CASE
; The required fault reporting from imm8 is extracted
; TOKENs are mutually exclusive and TOKENs priority defines the order.
; Multiple faults related to a single token can occur simultaneously.
IF (tsrc[63:0] of TOKEN_TYPE: ZERO_VALUE_TOKEN) AND imm8[0] then set #ZE;
IF (tsrc[63:0] of TOKEN_TYPE: ZERO_VALUE_TOKEN) AND imm8[1] then set #IE;
IF (tsrc[63:0] of TOKEN_TYPE: ONE_VALUE_TOKEN) AND imm8[2] then set #ZE;
IF (tsrc[63:0] of TOKEN_TYPE: ONE_VALUE_TOKEN) AND imm8[3] then set #IE;
IF (tsrc[63:0] of TOKEN_TYPE: SNAN_TOKEN) AND imm8[4] then set #IE;
IF (tsrc[63:0] of TOKEN_TYPE: NEG_INF_TOKEN) AND imm8[5] then set #IE;
IF (tsrc[63:0] of TOKEN_TYPE: NEG_VALUE_TOKEN) AND imm8[6] then set #IE;
IF (tsrc[63:0] of TOKEN_TYPE: POS_INF_TOKEN) AND imm8[7] then set #IE;
; end fault reporting
return dest[63:0];
}
; end of FIXUPIMM_DP()
5-188
Vol. 2C
VFIXUPIMMSD—Fix Up Special Scalar Float64 Value
INSTRUCTION SET REFERENCE, V
VFIXUPIMMSD (EVEX encoded version)
IF k1[0] OR *no writemask*
THEN DEST[63:0] := FIXUPIMM_DP(DEST[63:0], SRC1[63:0], SRC2[63:0], imm8 [7:0])
ELSE
IF *merging-masking*
; merging-masking
THEN *DEST[63:0] remains unchanged*
ELSE DEST[63:0] := 0
; zeroing-masking
FI
FI;
DEST[127:64] := SRC1[127:64]
DEST[MAXVL-1:128] := 0
Immediate Control Description:
7
6
5
4
3
2
1
0
+ INF ˘
#IE
- VE ˘
#IE
- INF ˘
#IE
SNaN ˘
#IE
ONE ˘
#IE
ONE ˘
#ZE
ZERO ˘
#IE
ZERO ˘
#ZE
Figure 5-11. VFIXUPIMMSD Immediate Control Description
Intel C/C++ Compiler Intrinsic Equivalent
VFIXUPIMMSD __m128d _mm_fixupimm_sd( __m128d a, __m128i tbl, int imm);
VFIXUPIMMSD __m128d _mm_mask_fixupimm_sd(__m128d s, __mmask8 k, __m128d a, __m128i tbl, int imm);
VFIXUPIMMSD __m128d _mm_maskz_fixupimm_sd( __mmask8 k, __m128d a, __m128i tbl, int imm);
VFIXUPIMMSD __m128d _mm_fixupimm_round_sd( __m128d a, __m128i tbl, int imm, int sae);
VFIXUPIMMSD __m128d _mm_mask_fixupimm_round_sd(__m128d s, __mmask8 k, __m128d a, __m128i tbl, int imm, int sae);
VFIXUPIMMSD __m128d _mm_maskz_fixupimm_round_sd( __mmask8 k, __m128d a, __m128i tbl, int imm, int sae);
SIMD Floating-Point Exceptions
Zero, Invalid
Other Exceptions
See Table 2-47, “Type E3 Class Exception Conditions.”
VFIXUPIMMSD—Fix Up Special Scalar Float64 Value
Vol. 2C
5-189
INSTRUCTION SET REFERENCE, V
VFIXUPIMMSS—Fix Up Special Scalar Float32 Value
Opcode/
Op /
64/32
CPUID
Description
Instruction
En
bit Mode
Feature
Support
Flag
EVEX.LLIG.66.0F3A.W0 55 /r ib
A
V/V
AVX512F
Fix up a float32 number in the low doubleword element
VFIXUPIMMSS xmm1 {k1}{z}, xmm2,
in xmm2 using scalar int32 table in xmm3/m32 and store
xmm3/m32{sae}, imm8
the result in xmm1.
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
Tuple1 Scalar
ModRM:reg (r, w)
EVEX.vvvv (r)
ModRM:r/m (r)
imm8
Description
Perform a fix-up of the low doubleword element encoded in single precision floating-point format in the first source
operand (the second operand) using a 32-bit, two-level look-up table specified in the low doubleword element of
the second source operand (the third operand) with exception reporting specifier imm8. The element that is fixed-
up is selected by mask bit of 1 specified in the opmask k1. Mask bit of 0 in the opmask k1 or table response action
of 0000b preserves the corresponding element of the first operand. The fixed-up element from the first source
operand or the preserved element in the first operand becomes the low doubleword element of the destination
operand (the first operand) Bits 127:32 of the destination operand is copied from the corresponding bits of the first
source operand. The destination and first source operands are XMM registers. The second source operand can be a
XMM register or a 32-bit memory location.
The two-level look-up table perform a fix-up of each single precision floating-point input data in the first source
operand by decoding the input data encoding into 8 token types. A response table is defined for each token type
that converts the input encoding in the first source operand with one of 16 response actions.
This instruction is specifically intended for use in fixing up the results of arithmetic calculations involving one source
so that they match the spec, although it is generally useful for fixing up the results of multiple-instruction
sequences to reflect special-number inputs. For example, consider rcp(0). Input 0 to rcp, and you should get INF
according to the DX10 spec. However, evaluating rcp via Newton-Raphson, where x=approx(1/0), yields an incor-
rect result. To deal with this, VFIXUPIMMPD can be used after the N-R reciprocal sequence to set the result to the
correct value (i.e., INF when the input is 0).
If MXCSR.DAZ is not set, denormal input elements in the first source operand are considered as normal inputs and
do not trigger any fixup nor fault reporting.
Imm8 is used to set the required flags reporting. It supports #ZE and #IE fault reporting (see details below).
MXCSR.DAZ is used and refer to zmm2 only (i.e., zmm1 is not considered as zero in case MXCSR.DAZ is set).
MXCSR mask bits are ignored and are treated as if all mask bits are set to masked response). If any of the imm8
bits is set and the condition met for fault reporting, MXCSR.IE or MXCSR.ZE might be updated.
Operation
enum TOKEN_TYPE
{
QNAN_TOKEN := 0,
SNAN_TOKEN := 1,
ZERO_VALUE_TOKEN := 2,
POS_ONE_VALUE_TOKEN := 3,
NEG_INF_TOKEN := 4,
POS_INF_TOKEN := 5,
NEG_VALUE_TOKEN := 6,
POS_VALUE_TOKEN := 7
}
5-190
Vol. 2C
VFIXUPIMMSS—Fix Up Special Scalar Float32 Value
INSTRUCTION SET REFERENCE, V
FIXUPIMM_SP (dest[31:0], src1[31:0],tbl3[31:0], imm8 [7:0]){
tsrc[31:0] := ((src1[30:23] = 0) AND (MXCSR.DAZ =1)) ? 0.0 : src1[31:0]
CASE(tsrc[63:0] of TOKEN_TYPE) {
QNAN_TOKEN: j := 0;
SNAN_TOKEN: j := 1;
ZERO_VALUE_TOKEN: j := 2;
POS_ONE_VALUE_TOKEN: j := 3;
NEG_INF_TOKEN: j := 4;
POS_INF_TOKEN: j := 5;
NEG_VALUE_TOKEN: j := 6;
POS_VALUE_TOKEN: j := 7;
}
; end source special CASE(tsrc…)
; The required response from src3 table is extracted
token_response[3:0] = tbl3[3+4*j:4*j];
CASE(token_response[3:0]) {
0000: dest[31:0] := dest[31:0];
; preserve content of DEST
0001: dest[31:0] := tsrc[31:0];
; pass through src1 normal input value, denormal as zero
0010: dest[31:0] := QNaN(tsrc[31:0]);
0011: dest[31:0] := QNAN_Indefinite;
0100: dest[31:0] := -INF;
0101: dest[31:0] := +INF;
0110: dest[31:0] := tsrc.sign? -INF : +INF;
0111: dest[31:0] := -0;
1000: dest[31:0] := +0;
1001: dest[31:0] := -1;
1010: dest[31:0] := +1;
1011: dest[31:0] := ½;
1100: dest[31:0] := 90.0;
1101: dest[31:0] := PI/2;
1110: dest[31:0] := MAX_FLOAT;
1111: dest[31:0] := -MAX_FLOAT;
}
; end of token_response CASE
; The required fault reporting from imm8 is extracted
; TOKENs are mutually exclusive and TOKENs priority defines the order.
; Multiple faults related to a single token can occur simultaneously.
IF (tsrc[31:0] of TOKEN_TYPE: ZERO_VALUE_TOKEN) AND imm8[0] then set #ZE;
IF (tsrc[31:0] of TOKEN_TYPE: ZERO_VALUE_TOKEN) AND imm8[1] then set #IE;
IF (tsrc[31:0] of TOKEN_TYPE: ONE_VALUE_TOKEN) AND imm8[2] then set #ZE;
IF (tsrc[31:0] of TOKEN_TYPE: ONE_VALUE_TOKEN) AND imm8[3] then set #IE;
IF (tsrc[31:0] of TOKEN_TYPE: SNAN_TOKEN) AND imm8[4] then set #IE;
IF (tsrc[31:0] of TOKEN_TYPE: NEG_INF_TOKEN) AND imm8[5] then set #IE;
IF (tsrc[31:0] of TOKEN_TYPE: NEG_VALUE_TOKEN) AND imm8[6] then set #IE;
IF (tsrc[31:0] of TOKEN_TYPE: POS_INF_TOKEN) AND imm8[7] then set #IE;
; end fault reporting
return dest[31:0];
}
; end of FIXUPIMM_SP()
VFIXUPIMMSS—Fix Up Special Scalar Float32 Value
Vol. 2C
5-191
INSTRUCTION SET REFERENCE, V
VFIXUPIMMSS (EVEX encoded version)
IF k1[0] OR *no writemask*
THEN DEST[31:0] := FIXUPIMM_SP(DEST[31:0], SRC1[31:0], SRC2[31:0], imm8 [7:0])
ELSE
IF *merging-masking*
; merging-masking
THEN *DEST[31:0] remains unchanged*
ELSE DEST[31:0] := 0
; zeroing-masking
FI
FI;
DEST[127:32] := SRC1[127:32]
DEST[MAXVL-1:128] := 0
Immediate Control Description:
7
6
5
4
3
2
1
0
+ INF ˘
#IE
- VE ˘
#IE
- INF ˘
#IE
SNaN ˘
#IE
ONE ˘
#IE
ONE ˘
#ZE
ZERO ˘
#IE
ZERO ˘
#ZE
Figure 5-12. VFIXUPIMMSS Immediate Control Description
Intel C/C++ Compiler Intrinsic Equivalent
VFIXUPIMMSS __m128 _mm_fixupimm_ss( __m128 a, __m128i tbl, int imm);
VFIXUPIMMSS __m128 _mm_mask_fixupimm_ss(__m128 s, __mmask8 k, __m128 a, __m128i tbl, int imm);
VFIXUPIMMSS __m128 _mm_maskz_fixupimm_ss( __mmask8 k, __m128 a, __m128i tbl, int imm);
VFIXUPIMMSS __m128 _mm_fixupimm_round_ss( __m128 a, __m128i tbl, int imm, int sae);
VFIXUPIMMSS __m128 _mm_mask_fixupimm_round_ss(__m128 s, __mmask8 k, __m128 a, __m128i tbl, int imm, int sae);
VFIXUPIMMSS __m128 _mm_maskz_fixupimm_round_ss( __mmask8 k, __m128 a, __m128i tbl, int imm, int sae);
SIMD Floating-Point Exceptions
Zero, Invalid
Other Exceptions
See Table 2-47, “Type E3 Class Exception Conditions.”
5-192
Vol. 2C
VFIXUPIMMSS—Fix Up Special Scalar Float32 Value
INSTRUCTION SET REFERENCE, V
VFMADD132PD/VFMADD213PD/VFMADD231PD—Fused Multiply-Add of Packed Double
Precision Floating-Point Values
Opcode/
Op/
64/32
CPUID
Description
Instruction
En
bit Mode
Feature
Support
Flag
VEX.128.66.0F38.W1 98 /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMADD132PD xmm1, xmm2,
values from xmm1 and xmm3/mem, add to xmm2
xmm3/m128
and put result in xmm1.
VEX.128.66.0F38.W1 A8 /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMADD213PD xmm1, xmm2,
values from xmm1 and xmm2, add to xmm3/mem
xmm3/m128
and put result in xmm1.
VEX.128.66.0F38.W1 B8 /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMADD231PD xmm1, xmm2,
values from xmm2 and xmm3/mem, add to xmm1
xmm3/m128
and put result in xmm1.
VEX.256.66.0F38.W1 98 /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMADD132PD ymm1, ymm2,
values from ymm1 and ymm3/mem, add to ymm2
ymm3/m256
and put result in ymm1.
VEX.256.66.0F38.W1 A8 /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMADD213PD ymm1, ymm2,
values from ymm1 and ymm2, add to ymm3/mem
ymm3/m256
and put result in ymm1.
VEX.256.66.0F38.W1 B8 /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMADD231PD ymm1, ymm2,
values from ymm2 and ymm3/mem, add to ymm1
ymm3/m256
and put result in ymm1.
EVEX.128.66.0F38.W1 98 /r
B
V/V
AVX512VL
Multiply packed double precision floating-point
VFMADD132PD xmm1 {k1}{z}, xmm2,
AVX512F
values from xmm1 and xmm3/m128/m64bcst, add
xmm3/m128/m64bcst
to xmm2 and put result in xmm1.
EVEX.128.66.0F38.W1 A8 /r
B
V/V
AVX512VL
Multiply packed double precision floating-point
VFMADD213PD xmm1 {k1}{z}, xmm2,
AVX512F
values from xmm1 and xmm2, add to
xmm3/m128/m64bcst
xmm3/m128/m64bcst and put result in xmm1.
EVEX.128.66.0F38.W1 B8 /r
B
V/V
AVX512VL
Multiply packed double precision floating-point
VFMADD231PD xmm1 {k1}{z}, xmm2,
AVX512F
values from xmm2 and xmm3/m128/m64bcst, add
xmm3/m128/m64bcst
to xmm1 and put result in xmm1.
EVEX.256.66.0F38.W1 98 /r
B
V/V
AVX512VL
Multiply packed double precision floating-point
VFMADD132PD ymm1 {k1}{z}, ymm2,
AVX512F
values from ymm1 and ymm3/m256/m64bcst, add
ymm3/m256/m64bcst
to ymm2 and put result in ymm1.
EVEX.256.66.0F38.W1 A8 /r
B
V/V
AVX512VL
Multiply packed double precision floating-point
VFMADD213PD ymm1 {k1}{z}, ymm2,
AVX512F
values from ymm1 and ymm2, add to
ymm3/m256/m64bcst
ymm3/m256/m64bcst and put result in ymm1.
EVEX.256.66.0F38.W1 B8 /r
B
V/V
AVX512VL
Multiply packed double precision floating-point
VFMADD231PD ymm1 {k1}{z}, ymm2,
AVX512F
values from ymm2 and ymm3/m256/m64bcst, add
ymm3/m256/m64bcst
to ymm1 and put result in ymm1.
EVEX.512.66.0F38.W1 98 /r
B
V/V
AVX512F
Multiply packed double precision floating-point
VFMADD132PD zmm1 {k1}{z}, zmm2,
values from zmm1 and zmm3/m512/m64bcst, add
zmm3/m512/m64bcst{er}
to zmm2 and put result in zmm1.
EVEX.512.66.0F38.W1 A8 /r
B
V/V
AVX512F
Multiply packed double precision floating-point
VFMADD213PD zmm1 {k1}{z}, zmm2,
values from zmm1 and zmm2, add to
zmm3/m512/m64bcst{er}
zmm3/m512/m64bcst and put result in zmm1.
EVEX.512.66.0F38.W1 B8 /r
B
V/V
AVX512F
Multiply packed double precision floating-point
VFMADD231PD zmm1 {k1}{z}, zmm2,
values from zmm2 and zmm3/m512/m64bcst, add
zmm3/m512/m64bcst{er}
to zmm1 and put result in zmm1.
VFMADD132PD/VFMADD213PD/VFMADD231PD—Fused Multiply-Add of Packed Double Precision Floating-Point Values
Vol. 2C
5-193
INSTRUCTION SET REFERENCE, V
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:reg (r, w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
B
Full
ModRM:reg (r, w)
EVEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
Performs a set of SIMD multiply-add computation on packed double precision floating-point values using three
source operands and writes the multiply-add results in the destination operand. The destination operand is also the
first source operand. The second operand must be a SIMD register. The third source operand can be a SIMD
register or a memory location.
VFMADD132PD: Multiplies the two, four or eight packed double precision floating-point values from the first source
operand to the two, four or eight packed double precision floating-point values in the third source operand, adds
the infinite precision intermediate result to the two, four or eight packed double precision floating-point values in
the second source operand, performs rounding and stores the resulting two, four or eight packed double precision
floating-point values to the destination operand (first source operand).
VFMADD213PD: Multiplies the two, four or eight packed double precision floating-point values from the second
source operand to the two, four or eight packed double precision floating-point values in the first source operand,
adds the infinite precision intermediate result to the two, four or eight packed double precision floating-point values
in the third source operand, performs rounding and stores the resulting two, four or eight packed double precision
floating-point values to the destination operand (first source operand).
VFMADD231PD: Multiplies the two, four or eight packed double precision floating-point values from the second
source to the two, four or eight packed double precision floating-point values in the third source operand, adds the
infinite precision intermediate result to the two, four or eight packed double precision floating-point values in the
first source operand, performs rounding and stores the resulting two, four or eight packed double precision
floating-point values to the destination operand (first source operand).
EVEX encoded versions: The destination operand (also first source operand) is a ZMM register and encoded in
reg_field. The second source operand is a ZMM register and encoded in EVEX.vvvv. The third source operand is a
ZMM register, a 512-bit memory location, or a 512-bit vector broadcasted from a 64-bit memory location. The
destination operand is conditionally updated with write mask k1.
VEX.256 encoded version: The destination operand (also first source operand) is a YMM register and encoded in
reg_field. The second source operand is a YMM register and encoded in VEX.vvvv. The third source operand is a
YMM register or a 256-bit memory location and encoded in rm_field.
VEX.128 encoded version: The destination operand (also first source operand) is a XMM register and encoded in
reg_field. The second source operand is a XMM register and encoded in VEX.vvvv. The third source operand is a
XMM register or a 128-bit memory location and encoded in rm_field. The upper 128 bits of the YMM destination
register are zeroed.
5-194
Vol. 2C
VFMADD132PD/VFMADD213PD/VFMADD231PD—Fused Multiply-Add of Packed Double Precision Floating-Point Values
INSTRUCTION SET REFERENCE, V
Operation
In the operations below, “*” and “+” symbols represent multiplication and addition with infinite precision inputs and outputs (no
rounding).
VFMADD132PD DEST, SRC2, SRC3 (VEX encoded version)
IF (VEX.128) THEN
MAXNUM := 2
ELSEIF (VEX.256)
MAXNUM := 4
FI
For i = 0 to MAXNUM-1 {
n := 64*i;
DEST[n+63:n] := RoundFPControl_MXCSR(DEST[n+63:n]*SRC3[n+63:n] + SRC2[n+63:n])
}
IF (VEX.128) THEN
DEST[MAXVL-1:128] := 0
ELSEIF (VEX.256)
DEST[MAXVL-1:256] := 0
FI
VFMADD213PD DEST, SRC2, SRC3 (VEX encoded version)
IF (VEX.128) THEN
MAXNUM := 2
ELSEIF (VEX.256)
MAXNUM := 4
FI
For i = 0 to MAXNUM-1 {
n := 64*i;
DEST[n+63:n] := RoundFPControl_MXCSR(SRC2[n+63:n]*DEST[n+63:n] + SRC3[n+63:n])
}
IF (VEX.128) THEN
DEST[MAXVL-1:128] := 0
ELSEIF (VEX.256)
DEST[MAXVL-1:256] := 0
FI
VFMADD231PD DEST, SRC2, SRC3 (VEX encoded version)
IF (VEX.128) THEN
MAXNUM := 2
ELSEIF (VEX.256)
MAXNUM := 4
FI
For i = 0 to MAXNUM-1 {
n := 64*i;
DEST[n+63:n] := RoundFPControl_MXCSR(SRC2[n+63:n]*SRC3[n+63:n] + DEST[n+63:n])
}
IF (VEX.128) THEN
DEST[MAXVL-1:128] := 0
ELSEIF (VEX.256)
DEST[MAXVL-1:256] := 0
FI
VFMADD132PD/VFMADD213PD/VFMADD231PD—Fused Multiply-Add of Packed Double Precision Floating-Point Values
Vol. 2C
5-195
INSTRUCTION SET REFERENCE, V
VFMADD132PD DEST, SRC2, SRC3 (EVEX encoded version, when src3 operand is a register)
(KL, VL) = (2, 128), (4, 256), (8, 512)
IF (VL = 512) AND (EVEX.b = 1)
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 * 64
IF k1[j] OR *no writemask*
THEN DEST[i+63:i] :=
RoundFPControl(DEST[i+63:i]*SRC3[i+63:i] + SRC2[i+63:i])
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
VFMADD132PD DEST, SRC2, SRC3 (EVEX encoded version, when src3 operand is a memory source)
(KL, VL) = (2, 128), (4, 256), (8, 512)
FOR j := 0 TO KL-1
i := j * 64
IF k1[j] OR *no writemask*
THEN
IF (EVEX.b = 1)
THEN
DEST[i+63:i] :=
RoundFPControl_MXCSR(DEST[i+63:i]*SRC3[63:0] + SRC2[i+63:i])
ELSE
DEST[i+63:i] :=
RoundFPControl_MXCSR(DEST[i+63:i]*SRC3[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
5-196
Vol. 2C
VFMADD132PD/VFMADD213PD/VFMADD231PD—Fused Multiply-Add of Packed Double Precision Floating-Point Values
INSTRUCTION SET REFERENCE, V
VFMADD213PD DEST, SRC2, SRC3 (EVEX encoded version, when src3 operand is a is a register)
(KL, VL) = (2, 128), (4, 256), (8, 512)
IF (VL = 512) AND (EVEX.b = 1)
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 * 64
IF k1[j] OR *no writemask*
THEN DEST[i+63:i] :=
RoundFPControl(SRC2[i+63:i]*DEST[i+63:i] + SRC3[i+63:i])
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
VFMADD213PD DEST, SRC2, SRC3 (EVEX encoded version, when src3 operand is a memory source)
(KL, VL) = (2, 128), (4, 256), (8, 512)
FOR j := 0 TO KL-1
i := j * 64
IF k1[j] OR *no writemask*
THEN
IF (EVEX.b = 1)
THEN
DEST[i+63:i] :=
RoundFPControl_MXCSR(SRC2[i+63:i]*DEST[i+63:i] + SRC3[63:0])
ELSE
DEST[i+63:i] :=
RoundFPControl_MXCSR(SRC2[i+63:i]*DEST[i+63:i] + SRC3[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
VFMADD132PD/VFMADD213PD/VFMADD231PD—Fused Multiply-Add of Packed Double Precision Floating-Point Values
Vol. 2C
5-197
INSTRUCTION SET REFERENCE, V
VFMADD231PD DEST, SRC2, SRC3 (EVEX encoded version, when src3 operand is a register)
(KL, VL) = (2, 128), (4, 256), (8, 512)
IF (VL = 512) AND (EVEX.b = 1)
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 * 64
IF k1[j] OR *no writemask*
THEN DEST[i+63:i] :=
RoundFPControl(SRC2[i+63:i]*SRC3[i+63:i] + DEST[i+63:i])
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
VFMADD231PD DEST, SRC2, SRC3 (EVEX encoded version, when src3 operand is a memory source)
(KL, VL) = (2, 128), (4, 256), (8, 512)
FOR j := 0 TO KL-1
i := j * 64
IF k1[j] OR *no writemask*
THEN
IF (EVEX.b = 1)
THEN
DEST[i+63:i] :=
RoundFPControl_MXCSR(SRC2[i+63:i]*SRC3[63:0] + DEST[i+63:i])
ELSE
DEST[i+63:i] :=
RoundFPControl_MXCSR(SRC2[i+63:i]*SRC3[i+63:i] + DEST[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
5-198
Vol. 2C
VFMADD132PD/VFMADD213PD/VFMADD231PD—Fused Multiply-Add of Packed Double Precision Floating-Point Values
INSTRUCTION SET REFERENCE, V
Intel C/C++ Compiler Intrinsic Equivalent
VFMADDxxxPD __m512d _mm512_fmadd_pd(__m512d a, __m512d b, __m512d c);
VFMADDxxxPD __m512d _mm512_fmadd_round_pd(__m512d a, __m512d b, __m512d c, int r);
VFMADDxxxPD __m512d _mm512_mask_fmadd_pd(__m512d a, __mmask8 k, __m512d b, __m512d c);
VFMADDxxxPD __m512d _mm512_maskz_fmadd_pd(__mmask8 k, __m512d a, __m512d b, __m512d c);
VFMADDxxxPD __m512d _mm512_mask3_fmadd_pd(__m512d a, __m512d b, __m512d c, __mmask8 k);
VFMADDxxxPD __m512d _mm512_mask_fmadd_round_pd(__m512d a, __mmask8 k, __m512d b, __m512d c, int r);
VFMADDxxxPD __m512d _mm512_maskz_fmadd_round_pd(__mmask8 k, __m512d a, __m512d b, __m512d c, int r);
VFMADDxxxPD __m512d _mm512_mask3_fmadd_round_pd(__m512d a, __m512d b, __m512d c, __mmask8 k, int r);
VFMADDxxxPD __m256d _mm256_mask_fmadd_pd(__m256d a, __mmask8 k, __m256d b, __m256d c);
VFMADDxxxPD __m256d _mm256_maskz_fmadd_pd(__mmask8 k, __m256d a, __m256d b, __m256d c);
VFMADDxxxPD __m256d _mm256_mask3_fmadd_pd(__m256d a, __m256d b, __m256d c, __mmask8 k);
VFMADDxxxPD __m128d _mm_mask_fmadd_pd(__m128d a, __mmask8 k, __m128d b, __m128d c);
VFMADDxxxPD __m128d _mm_maskz_fmadd_pd(__mmask8 k, __m128d a, __m128d b, __m128d c);
VFMADDxxxPD __m128d _mm_mask3_fmadd_pd(__m128d a, __m128d b, __m128d c, __mmask8 k);
VFMADDxxxPD __m128d _mm_fmadd_pd (__m128d a, __m128d b, __m128d c);
VFMADDxxxPD __m256d _mm256_fmadd_pd (__m256d a, __m256d b, __m256d c);
SIMD Floating-Point Exceptions
Overflow, Underflow, Invalid, Precision, Denormal
Other Exceptions
VEX-encoded instructions, see Table 2-19, “Type 2 Class Exception Conditions.”
EVEX-encoded instructions, see Table 2-46, “Type E2 Class Exception Conditions.”
VFMADD132PD/VFMADD213PD/VFMADD231PD—Fused Multiply-Add of Packed Double Precision Floating-Point Values
Vol. 2C
5-199
INSTRUCTION SET REFERENCE, V
VF[,N]MADD[132,213,231]PH—Fused Multiply-Add of Packed FP16 Values
Opcode/
Op/
64/32
CPUID Feature
Description
Instruction
En
bit Mode
Flag
Support
EVEX.128.66.MAP6.W0 98 /r
A
V/V
AVX512-FP16
Multiply packed FP16 values from xmm1 and
VFMADD132PH xmm1{k1}{z}, xmm2,
AVX512VL
xmm3/m128/m16bcst, add to xmm2, and store
xmm3/m128/m16bcst
the result in xmm1.
EVEX.256.66.MAP6.W0 98 /r
A
V/V
AVX512-FP16
Multiply packed FP16 values from ymm1 and
VFMADD132PH ymm1{k1}{z}, ymm2,
AVX512VL
ymm3/m256/m16bcst, add to ymm2, and store
ymm3/m256/m16bcst
the result in ymm1.
EVEX.512.66.MAP6.W0 98 /r
A
V/V
AVX512-FP16
Multiply packed FP16 values from zmm1 and
VFMADD132PH zmm1{k1}{z}, zmm2,
zmm3/m512/m16bcst, add to zmm2, and store
zmm3/m512/m16bcst {er}
the result in zmm1.
EVEX.128.66.MAP6.W0 A8 /r
A
V/V
AVX512-FP16
Multiply packed FP16 values from xmm1 and
VFMADD213PH xmm1{k1}{z}, xmm2,
AVX512VL
xmm2, add to xmm3/m128/m16bcst, and store
xmm3/m128/m16bcst
the result in xmm1.
EVEX.256.66.MAP6.W0 A8 /r
A
V/V
AVX512-FP16
Multiply packed FP16 values from ymm1 and
VFMADD213PH ymm1{k1}{z}, ymm2,
AVX512VL
ymm2, add to ymm3/m256/m16bcst, and store
ymm3/m256/m16bcst
the result in ymm1.
EVEX.512.66.MAP6.W0 A8 /r
A
V/V
AVX512-FP16
Multiply packed FP16 values from zmm1 and
VFMADD213PH zmm1{k1}{z}, zmm2,
zmm2, add to zmm3/m512/m16bcst, and store
zmm3/m512/m16bcst {er}
the result in zmm1.
EVEX.128.66.MAP6.W0 B8 /r
A
V/V
AVX512-FP16
Multiply packed FP16 values from xmm2 and
VFMADD231PH xmm1{k1}{z}, xmm2,
AVX512VL
xmm3/m128/m16bcst, add to xmm1, and store
xmm3/m128/m16bcst
the result in xmm1.
EVEX.256.66.MAP6.W0 B8 /r
A
V/V
AVX512-FP16
Multiply packed FP16 values from ymm2 and
VFMADD231PH ymm1{k1}{z}, ymm2,
AVX512VL
ymm3/m256/m16bcst, add to ymm1, and store
ymm3/m256/m16bcst
the result in ymm1.
EVEX.512.66.MAP6.W0 B8 /r
A
V/V
AVX512-FP16
Multiply packed FP16 values from zmm2 and
VFMADD231PH zmm1{k1}{z}, zmm2,
zmm3/m512/m16bcst, add to zmm1, and store
zmm3/m512/m16bcst {er}
the result in zmm1.
EVEX.128.66.MAP6.W0 9C /r
A
V/V
AVX512-FP16
Multiply packed FP16 values from xmm1 and
VFNMADD132PH xmm1{k1}{z},
AVX512VL
xmm3/m128/m16bcst, and negate the value.
xmm2, xmm3/m128/m16bcst
Add this value to xmm2, and store the result in
xmm1.
EVEX.256.66.MAP6.W0 9C /r
A
V/V
AVX512-FP16
Multiply packed FP16 values from ymm1 and
VFNMADD132PH ymm1{k1}{z},
AVX512VL
ymm3/m256/m16bcst, and negate the value.
ymm2, ymm3/m256/m16bcst
Add this value to ymm2, and store the result in
ymm1.
EVEX.512.66.MAP6.W0 9C /r
A
V/V
AVX512-FP16
Multiply packed FP16 values from zmm1 and
VFNMADD132PH zmm1{k1}{z},
zmm3/m512/m16bcst, and negate the value.
zmm2, zmm3/m512/m16bcst {er}
Add this value to zmm2, and store the result in
zmm1.
EVEX.128.66.MAP6.W0 AC /r
A
V/V
AVX512-FP16
Multiply packed FP16 values from xmm1 and
VFNMADD213PH xmm1{k1}{z},
AVX512VL
xmm2, and negate the value. Add this value to
xmm2, xmm3/m128/m16bcst
xmm3/m128/m16bcst, and store the result in
xmm1.
EVEX.256.66.MAP6.W0 AC /r
A
V/V
AVX512-FP16
Multiply packed FP16 values from ymm1 and
VFNMADD213PH ymm1{k1}{z},
AVX512VL
ymm2, and negate the value. Add this value to
ymm2, ymm3/m256/m16bcst
ymm3/m256/m16bcst, and store the result in
ymm1.
5-200
Vol. 2C
VF[,N]MADD[132,213,231]PH—Fused Multiply-Add of Packed FP16 Values
INSTRUCTION SET REFERENCE, V
Opcode/
Op/
64/32
CPUID Feature
Description
Instruction
En
bit Mode
Flag
Support
EVEX.512.66.MAP6.W0 AC /r
A
V/V
AVX512-FP16
Multiply packed FP16 values from zmm1 and
VFNMADD213PH zmm1{k1}{z},
zmm2, and negate the value. Add this value to
zmm2, zmm3/m512/m16bcst {er}
zmm3/m512/m16bcst, and store the result in
zmm1.
EVEX.128.66.MAP6.W0 BC /r
A
V/V
AVX512-FP16
Multiply packed FP16 values from xmm2 and
VFNMADD231PH xmm1{k1}{z},
AVX512VL
xmm3/m128/m16bcst, and negate the value.
xmm2, xmm3/m128/m16bcst
Add this value to xmm1, and store the result in
xmm1.
EVEX.256.66.MAP6.W0 BC /r
A
V/V
AVX512-FP16
Multiply packed FP16 values from ymm2 and
VFNMADD231PH ymm1{k1}{z},
AVX512VL
ymm3/m256/m16bcst, and negate the value.
ymm2, ymm3/m256/m16bcst
Add this value to ymm1, and store the result in
ymm1.
EVEX.512.66.MAP6.W0 BC /r
A
V/V
AVX512-FP16
Multiply packed FP16 values from zmm2 and
VFNMADD231PH zmm1{k1}{z},
zmm3/m512/m16bcst, and negate the value.
zmm2, zmm3/m512/m16bcst {er}
Add this value to zmm1, and store the result in
zmm1.
Instruction Operand Encoding
Op/En
Tuple
Operand 1
Operand 2
Operand 3
Operand 4
A
Full
ModRM:reg (r, w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
This instruction performs a packed multiply-add or negated multiply-add computation on FP16 values using three
source operands and writes the results in the destination operand. The destination operand is also the first source
operand. The “N” (negated) forms of this instruction add the negated infinite precision intermediate product to the
corresponding remaining operand. The notation’ “132”, “213” and “231” indicate the use of the operands in ±A * B
+ C, where each digit corresponds to the operand number, with the destination being operand 1; see Table 5-2.
The destination elements are updated according to the writemask.
Table 5-2. VF[,N]MADD[132,213,231]PH Notation for Operands
Notation
Operands
132
dest = ± dest*src3+src2
231
dest = ± src2*src3+dest
213
dest = ± src2*dest+src3
VF[,N]MADD[132,213,231]PH—Fused Multiply-Add of Packed FP16 Values
Vol. 2C
5-201
INSTRUCTION SET REFERENCE, V
Operation
VF[,N]MADD132PH DEST, SRC2, SRC3 (EVEX encoded versions) when src3 operand is a register
VL = 128, 256 or 512
KL := VL/16
IF (VL = 512) AND (EVEX.b = 1):
SET_RM(EVEX.RC)
ELSE
SET_RM(MXCSR.RC)
FOR j := 0 TO KL-1:
IF k1[j] OR *no writemask*:
IF *negative form*:
DEST.fp16[j] := RoundFPControl(-DEST.fp16[j]*SRC3.fp16[j] + SRC2.fp16[j])
ELSE:
DEST.fp16[j] := RoundFPControl(DEST.fp16[j]*SRC3.fp16[j] + SRC2.fp16[j])
ELSE IF *zeroing*:
DEST.fp16[j] := 0
// else dest.fp16[j] remains unchanged
DEST[MAXVL-1:VL] := 0
VF[,N]MADD132PH DEST, SRC2, SRC3 (EVEX encoded versions) when src3 operand is a memory source
VL = 128, 256 or 512
KL := VL/16
FOR j := 0 TO KL-1:
IF k1[j] OR *no writemask*:
IF EVEX.b = 1:
t3 := SRC3.fp16[0]
ELSE:
t3 := SRC3.fp16[j]
IF *negative form*:
DEST.fp16[j] := RoundFPControl(-DEST.fp16[j] * t3 + SRC2.fp16[j])
ELSE:
DEST.fp16[j] := RoundFPControl(DEST.fp16[j] * t3 + SRC2.fp16[j])
ELSE IF *zeroing*:
DEST.fp16[j] := 0
// else dest.fp16[j] remains unchanged
DEST[MAXVL-1:VL] := 0
5-202
Vol. 2C
VF[,N]MADD[132,213,231]PH—Fused Multiply-Add of Packed FP16 Values
INSTRUCTION SET REFERENCE, V
VF[,N]MADD213PH DEST, SRC2, SRC3 (EVEX encoded versions) when src3 operand is a register
VL = 128, 256 or 512
KL := VL/16
IF (VL = 512) AND (EVEX.b = 1):
SET_RM(EVEX.RC)
ELSE
SET_RM(MXCSR.RC)
FOR j := 0 TO KL-1:
IF k1[j] OR *no writemask*:
IF *negative form*:
DEST.fp16[j] := RoundFPControl(-SRC2.fp16[j]*DEST.fp16[j] + SRC3.fp16[j])
ELSE
DEST.fp16[j] := RoundFPControl(SRC2.fp16[j]*DEST.fp16[j] + SRC3.fp16[j])
ELSE IF *zeroing*:
DEST.fp16[j] := 0
// else dest.fp16[j] remains unchanged
DEST[MAXVL-1:VL] := 0
VF[,N]MADD213PH DEST, SRC2, SRC3 (EVEX encoded versions) when src3 operand is a memory source
VL = 128, 256 or 512
KL := VL/16
FOR j := 0 TO KL-1:
IF k1[j] OR *no writemask*:
IF EVEX.b = 1:
t3 := SRC3.fp16[0]
ELSE:
t3 := SRC3.fp16[j]
IF *negative form*:
DEST.fp16[j] := RoundFPControl(-SRC2.fp16[j] * DEST.fp16[j] + t3 )
ELSE:
DEST.fp16[j] := RoundFPControl(SRC2.fp16[j] * DEST.fp16[j] + t3 )
ELSE IF *zeroing*:
DEST.fp16[j] := 0
// else dest.fp16[j] remains unchanged
DEST[MAXVL-1:VL] := 0
VF[,N]MADD[132,213,231]PH—Fused Multiply-Add of Packed FP16 Values
Vol. 2C
5-203
INSTRUCTION SET REFERENCE, V
VF[,N]MADD231PH DEST, SRC2, SRC3 (EVEX encoded versions) when src3 operand is a register
VL = 128, 256 or 512
KL := VL/16
IF (VL = 512) AND (EVEX.b = 1):
SET_RM(EVEX.RC)
ELSE
SET_RM(MXCSR.RC)
FOR j := 0 TO KL-1:
IF k1[j] OR *no writemask*:
IF *negative form:
DEST.fp16[j] := RoundFPControl(-SRC2.fp16[j]*SRC3.fp16[j] + DEST.fp16[j])
ELSE:
DEST.fp16[j] := RoundFPControl(SRC2.fp16[j]*SRC3.fp16[j] + DEST.fp16[j])
ELSE IF *zeroing*:
DEST.fp16[j] := 0
// else dest.fp16[j] remains unchanged
DEST[MAXVL-1:VL] := 0
VF[,N]MADD231PH DEST, SRC2, SRC3 (EVEX encoded versions) when src3 operand is a memory source
VL = 128, 256 or 512
KL := VL/16
FOR j := 0 TO KL-1:
IF k1[j] OR *no writemask*:
IF EVEX.b = 1:
t3 := SRC3.fp16[0]
ELSE:
t3 := SRC3.fp16[j]
IF *negative form*:
DEST.fp16[j] := RoundFPControl(-SRC2.fp16[j] * t3 + DEST.fp16[j] )
ELSE:
DEST.fp16[j] := RoundFPControl(SRC2.fp16[j] * t3 + DEST.fp16[j] )
ELSE IF *zeroing*:
DEST.fp16[j] := 0
// else dest.fp16[j] remains unchanged
DEST[MAXVL-1:VL] := 0
5-204
Vol. 2C
VF[,N]MADD[132,213,231]PH—Fused Multiply-Add of Packed FP16 Values
INSTRUCTION SET REFERENCE, V
Intel C/C++ Compiler Intrinsic Equivalent
VFMADD132PH, VFMADD213PH , and VFMADD231PH:
__m128h _mm_fmadd_ph (__m128h a, __m128h b, __m128h c);
__m128h _mm_mask_fmadd_ph (__m128h a, __mmask8 k, __m128h b, __m128h c);
__m128h _mm_mask3_fmadd_ph (__m128h a, __m128h b, __m128h c, __mmask8 k);
__m128h _mm_maskz_fmadd_ph (__mmask8 k, __m128h a, __m128h b, __m128h c);
__m256h _mm256_fmadd_ph (__m256h a, __m256h b, __m256h c);
__m256h _mm256_mask_fmadd_ph (__m256h a, __mmask16 k, __m256h b, __m256h c);
__m256h _mm256_mask3_fmadd_ph (__m256h a, __m256h b, __m256h c, __mmask16 k);
__m256h _mm256_maskz_fmadd_ph (__mmask16 k, __m256h a, __m256h b, __m256h c);
__m512h _mm512_fmadd_ph (__m512h a, __m512h b, __m512h c);
__m512h _mm512_mask_fmadd_ph (__m512h a, __mmask32 k, __m512h b, __m512h c);
__m512h _mm512_mask3_fmadd_ph (__m512h a, __m512h b, __m512h c, __mmask32 k);
__m512h _mm512_maskz_fmadd_ph (__mmask32 k, __m512h a, __m512h b, __m512h c);
__m512h _mm512_fmadd_round_ph (__m512h a, __m512h b, __m512h c, const int rounding);
__m512h _mm512_mask_fmadd_round_ph (__m512h a, __mmask32 k, __m512h b, __m512h c, const int rounding);
__m512h _mm512_mask3_fmadd_round_ph (__m512h a, __m512h b, __m512h c, __mmask32 k, const int rounding);
__m512h _mm512_maskz_fmadd_round_ph (__mmask32 k, __m512h a, __m512h b, __m512h c, const int rounding);
VFNMADD132PH, VFNMADD213PH, and VFNMADD231PH:
__m128h _mm_fnmadd_ph (__m128h a, __m128h b, __m128h c);
__m128h _mm_mask_fnmadd_ph (__m128h a, __mmask8 k, __m128h b, __m128h c);
__m128h _mm_mask3_fnmadd_ph (__m128h a, __m128h b, __m128h c, __mmask8 k);
__m128h _mm_maskz_fnmadd_ph (__mmask8 k, __m128h a, __m128h b, __m128h c);
__m256h _mm256_fnmadd_ph (__m256h a, __m256h b, __m256h c);
__m256h _mm256_mask_fnmadd_ph (__m256h a, __mmask16 k, __m256h b, __m256h c);
__m256h _mm256_mask3_fnmadd_ph (__m256h a, __m256h b, __m256h c, __mmask16 k);
__m256h _mm256_maskz_fnmadd_ph (__mmask16 k, __m256h a, __m256h b, __m256h c);
__m512h _mm512_fnmadd_ph (__m512h a, __m512h b, __m512h c);
__m512h _mm512_mask_fnmadd_ph (__m512h a, __mmask32 k, __m512h b, __m512h c);
__m512h _mm512_mask3_fnmadd_ph (__m512h a, __m512h b, __m512h c, __mmask32 k);
__m512h _mm512_maskz_fnmadd_ph (__mmask32 k, __m512h a, __m512h b, __m512h c);
__m512h _mm512_fnmadd_round_ph (__m512h a, __m512h b, __m512h c, const int rounding);
__m512h _mm512_mask_fnmadd_round_ph (__m512h a, __mmask32 k, __m512h b, __m512h c, const int rounding);
__m512h _mm512_mask3_fnmadd_round_ph (__m512h a, __m512h b, __m512h c, __mmask32 k, const int rounding);
__m512h _mm512_maskz_fnmadd_round_ph (__mmask32 k, __m512h a, __m512h b, __m512h c, const int rounding);
SIMD Floating-Point Exceptions
Invalid, Underflow, Overflow, Precision, Denormal
Other Exceptions
EVEX-encoded instructions, see Table 2-46, “Type E2 Class Exception Conditions.”
VF[,N]MADD[132,213,231]PH—Fused Multiply-Add of Packed FP16 Values
Vol. 2C
5-205
INSTRUCTION SET REFERENCE, V
VFMADD132PS/VFMADD213PS/VFMADD231PS—Fused Multiply-Add of Packed Single
Precision Floating-Point Values
Opcode/
Op/
64/32
CPUID
Description
Instruction
En
bit Mode
Feature
Support
Flag
VEX.128.66.0F38.W0 98 /r
A
V/V
FMA
Multiply packed single precision floating-point values
VFMADD132PS xmm1, xmm2,
from xmm1 and xmm3/mem, add to xmm2 and put
xmm3/m128
result in xmm1.
VEX.128.66.0F38.W0 A8 /r
A
V/V
FMA
Multiply packed single precision floating-point values
VFMADD213PS xmm1, xmm2,
from xmm1 and xmm2, add to xmm3/mem and put
xmm3/m128
result in xmm1.
VEX.128.66.0F38.W0 B8 /r
A
V/V
FMA
Multiply packed single precision floating-point values
VFMADD231PS xmm1, xmm2,
from xmm2 and xmm3/mem, add to xmm1 and put
xmm3/m128
result in xmm1.
VEX.256.66.0F38.W0 98 /r
A
V/V
FMA
Multiply packed single precision floating-point values
VFMADD132PS ymm1, ymm2,
from ymm1 and ymm3/mem, add to ymm2 and put
ymm3/m256
result in ymm1.
VEX.256.66.0F38.W0 A8 /r
A
V/V
FMA
Multiply packed single precision floating-point values
VFMADD213PS ymm1, ymm2,
from ymm1 and ymm2, add to ymm3/mem and put
ymm3/m256
result in ymm1.
VEX.256.66.0F38.0 B8 /r
A
V/V
FMA
Multiply packed single precision floating-point values
VFMADD231PS ymm1, ymm2,
from ymm2 and ymm3/mem, add to ymm1 and put
ymm3/m256
result in ymm1.
EVEX.128.66.0F38.W0 98 /r
B
V/V
AVX512VL
Multiply packed single precision floating-point values
VFMADD132PS xmm1 {k1}{z}, xmm2,
AVX512F
from xmm1 and xmm3/m128/m32bcst, add to
xmm3/m128/m32bcst
xmm2 and put result in xmm1.
EVEX.128.66.0F38.W0 A8 /r
B
V/V
AVX512VL
Multiply packed single precision floating-point values
VFMADD213PS xmm1 {k1}{z}, xmm2,
AVX512F
from xmm1 and xmm2, add to
xmm3/m128/m32bcst
xmm3/m128/m32bcst and put result in xmm1.
EVEX.128.66.0F38.W0 B8 /r
B
V/V
AVX512VL
Multiply packed single precision floating-point values
VFMADD231PS xmm1 {k1}{z}, xmm2,
AVX512F
from xmm2 and xmm3/m128/m32bcst, add to
xmm3/m128/m32bcst
xmm1 and put result in xmm1.
EVEX.256.66.0F38.W0 98 /r
B
V/V
AVX512VL
Multiply packed single precision floating-point values
VFMADD132PS ymm1 {k1}{z}, ymm2,
AVX512F
from ymm1 and ymm3/m256/m32bcst, add to
ymm3/m256/m32bcst
ymm2 and put result in ymm1.
EVEX.256.66.0F38.W0 A8 /r
B
V/V
AVX512VL
Multiply packed single precision floating-point values
VFMADD213PS ymm1 {k1}{z}, ymm2,
AVX512F
from ymm1 and ymm2, add to
ymm3/m256/m32bcst
ymm3/m256/m32bcst and put result in ymm1.
EVEX.256.66.0F38.W0 B8 /r
B
V/V
AVX512VL
Multiply packed single precision floating-point values
VFMADD231PS ymm1 {k1}{z}, ymm2,
AVX512F
from ymm2 and ymm3/m256/m32bcst, add to
ymm3/m256/m32bcst
ymm1 and put result in ymm1.
EVEX.512.66.0F38.W0 98 /r
B
V/V
AVX512F
Multiply packed single precision floating-point values
VFMADD132PS zmm1 {k1}{z}, zmm2,
from zmm1 and zmm3/m512/m32bcst, add to
zmm3/m512/m32bcst{er}
zmm2 and put result in zmm1.
EVEX.512.66.0F38.W0 A8 /r
B
V/V
AVX512F
Multiply packed single precision floating-point values
VFMADD213PS zmm1 {k1}{z}, zmm2,
from zmm1 and zmm2, add to
zmm3/m512/m32bcst{er}
zmm3/m512/m32bcst and put result in zmm1.
EVEX.512.66.0F38.W0 B8 /r
B
V/V
AVX512F
Multiply packed single precision floating-point values
VFMADD231PS zmm1 {k1}{z}, zmm2,
from zmm2 and zmm3/m512/m32bcst, add to
zmm3/m512/m32bcst{er}
zmm1 and put result in zmm1.
5-206
Vol. 2C
VFMADD132PS/VFMADD213PS/VFMADD231PS—Fused Multiply-Add of Packed Single Precision Floating-Point Values
INSTRUCTION SET REFERENCE, V
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:reg (r, w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
B
Full
ModRM:reg (r, w)
EVEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
Performs a set of SIMD multiply-add computation on packed single precision floating-point values using three
source operands and writes the multiply-add results in the destination operand. The destination operand is also the
first source operand. The second operand must be a SIMD register. The third source operand can be a SIMD
register or a memory location.
VFMADD132PS: Multiplies the four, eight or sixteen packed single precision floating-point values from the first
source operand to the four, eight or sixteen packed single precision floating-point values in the third source
operand, adds the infinite precision intermediate result to the four, eight or sixteen packed single precision floating-
point values in the second source operand, performs rounding and stores the resulting four, eight or sixteen packed
single precision floating-point values to the destination operand (first source operand).
VFMADD213PS: Multiplies the four, eight or sixteen packed single precision floating-point values from the second
source operand to the four, eight or sixteen packed single precision floating-point values in the first source
operand, adds the infinite precision intermediate result to the four, eight or sixteen packed single precision floating-
point values in the third source operand, performs rounding and stores the resulting the four, eight or sixteen
packed single precision floating-point values to the destination operand (first source operand).
VFMADD231PS: Multiplies the four, eight or sixteen packed single precision floating-point values from the second
source operand to the four, eight or sixteen packed single precision floating-point values in the third source
operand, adds the infinite precision intermediate result to the four, eight or sixteen packed single precision floating-
point values in the first source operand, performs rounding and stores the resulting four, eight or sixteen packed
single precision floating-point values to the destination operand (first source operand).
EVEX encoded versions: The destination operand (also first source operand) is a ZMM register and encoded in
reg_field. The second source operand is a ZMM register and encoded in EVEX.vvvv. The third source operand is a
ZMM register, a 512-bit memory location, or a 512-bit vector broadcasted from a 32-bit memory location. The
destination operand is conditionally updated with write mask k1.
VEX.256 encoded version: The destination operand (also first source operand) is a YMM register and encoded in
reg_field. The second source operand is a YMM register and encoded in VEX.vvvv. The third source operand is a
YMM register or a 256-bit memory location and encoded in rm_field.
VEX.128 encoded version: The destination operand (also first source operand) is a XMM register and encoded in
reg_field. The second source operand is a XMM register and encoded in VEX.vvvv. The third source operand is a
XMM register or a 128-bit memory location and encoded in rm_field. The upper 128 bits of the YMM destination
register are zeroed.
Operation
In the operations below, “*” and “+” symbols represent multiplication and addition with infinite precision inputs and outputs (no
rounding).
VFMADD132PS DEST, SRC2, SRC3
IF (VEX.128) THEN
MAXNUM := 4
ELSEIF (VEX.256)
MAXNUM := 8
FI
For i = 0 to MAXNUM-1 {
n := 32*i;
DEST[n+31:n] := RoundFPControl_MXCSR(DEST[n+31:n]*SRC3[n+31:n] + SRC2[n+31:n])
}
IF (VEX.128) THEN
DEST[MAXVL-1:128] := 0
VFMADD132PS/VFMADD213PS/VFMADD231PS—Fused Multiply-Add of Packed Single Precision Floating-Point Values
Vol. 2C
5-207
INSTRUCTION SET REFERENCE, V
ELSEIF (VEX.256)
DEST[MAXVL-1:256] := 0
FI
VFMADD213PS DEST, SRC2, SRC3
IF (VEX.128) THEN
MAXNUM := 4
ELSEIF (VEX.256)
MAXNUM := 8
FI
For i = 0 to MAXNUM-1 {
n := 32*i;
DEST[n+31:n] := RoundFPControl_MXCSR(SRC2[n+31:n]*DEST[n+31:n] + SRC3[n+31:n])
}
IF (VEX.128) THEN
DEST[MAXVL-1:128] := 0
ELSEIF (VEX.256)
DEST[MAXVL-1:256] := 0
FI
VFMADD231PS DEST, SRC2, SRC3
IF (VEX.128) THEN
MAXNUM := 4
ELSEIF (VEX.256)
MAXNUM := 8
FI
For i = 0 to MAXNUM-1 {
n := 32*i;
DEST[n+31:n] := RoundFPControl_MXCSR(SRC2[n+31:n]*SRC3[n+31:n] + DEST[n+31:n])
}
IF (VEX.128) THEN
DEST[MAXVL-1:128] := 0
ELSEIF (VEX.256)
DEST[MAXVL-1:256] := 0
FI
VFMADD132PS DEST, SRC2, SRC3 (EVEX encoded version, when src3 operand is a register)
(KL, VL) = (4, 128), (8, 256), (16, 512)
IF (VL = 512) AND (EVEX.b = 1)
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 DEST[i+31:i] :=
RoundFPControl(DEST[i+31:i]*SRC3[i+31:i] + SRC2[i+31:i])
ELSE
IF *merging-masking*
; merging-masking
THEN *DEST[i+31:i] remains unchanged*
ELSE
; zeroing-masking
DEST[i+31:i] := 0
5-208
Vol. 2C
VFMADD132PS/VFMADD213PS/VFMADD231PS—Fused Multiply-Add of Packed Single Precision Floating-Point Values
INSTRUCTION SET REFERENCE, V
FI
FI;
ENDFOR
DEST[MAXVL-1:VL] := 0
VFMADD132PS DEST, SRC2, SRC3 (EVEX encoded version, when src3 operand is a memory source)
(KL, VL) = (4, 128), (8, 256), (16, 512)
FOR j := 0 TO KL-1
i := j * 32
IF k1[j] OR *no writemask*
THEN
IF (EVEX.b = 1)
THEN
DEST[i+31:i] :=
RoundFPControl_MXCSR(DEST[i+31:i]*SRC3[31:0] + SRC2[i+31:i])
ELSE
DEST[i+31:i] :=
RoundFPControl_MXCSR(DEST[i+31:i]*SRC3[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
VFMADD213PS DEST, SRC2, SRC3 (EVEX encoded version, when src3 operand is a register)
(KL, VL) = (4, 128), (8, 256), (16, 512)
IF (VL = 512) AND (EVEX.b = 1)
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 DEST[i+31:i] :=
RoundFPControl(SRC2[i+31:i]*DEST[i+31:i] + SRC3[i+31:i])
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
VFMADD132PS/VFMADD213PS/VFMADD231PS—Fused Multiply-Add of Packed Single Precision Floating-Point Values
Vol. 2C
5-209
INSTRUCTION SET REFERENCE, V
VFMADD213PS DEST, SRC2, SRC3 (EVEX encoded version, when src3 operand is a memory source)
(KL, VL) = (4, 128), (8, 256), (16, 512)
FOR j := 0 TO KL-1
i := j * 32
IF k1[j] OR *no writemask*
THEN
IF (EVEX.b = 1)
THEN
DEST[i+31:i] :=
RoundFPControl_MXCSR(SRC2[i+31:i]*DEST[i+31:i] + SRC3[31:0])
ELSE
DEST[i+31:i] :=
RoundFPControl_MXCSR(SRC2[i+31:i]*DEST[i+31:i] + SRC3[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
VFMADD231PS DEST, SRC2, SRC3 (EVEX encoded version, when src3 operand is a register)
(KL, VL) = (4, 128), (8, 256), (16, 512)
IF (VL = 512) AND (EVEX.b = 1)
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 DEST[i+31:i] :=
RoundFPControl(SRC2[i+31:i]*SRC3[i+31:i] + DEST[i+31:i])
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
VFMADD231PS DEST, SRC2, SRC3 (EVEX encoded version, when src3 operand is a memory source)
(KL, VL) = (4, 128), (8, 256), (16, 512)
FOR j := 0 TO KL-1
i := j * 32
IF k1[j] OR *no writemask*
5-210
Vol. 2C
VFMADD132PS/VFMADD213PS/VFMADD231PS—Fused Multiply-Add of Packed Single Precision Floating-Point Values
INSTRUCTION SET REFERENCE, V
THEN
IF (EVEX.b = 1)
THEN
DEST[i+31:i] :=
RoundFPControl_MXCSR(SRC2[i+31:i]*SRC3[31:0] + DEST[i+31:i])
ELSE
DEST[i+31:i] :=
RoundFPControl_MXCSR(SRC2[i+31:i]*SRC3[i+31:i] + DEST[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
Intel C/C++ Compiler Intrinsic Equivalent
VFMADDxxxPS __m512 _mm512_fmadd_ps(__m512 a, __m512 b, __m512 c);
VFMADDxxxPS __m512 _mm512_fmadd_round_ps(__m512 a, __m512 b, __m512 c, int r);
VFMADDxxxPS __m512 _mm512_mask_fmadd_ps(__m512 a, __mmask16 k, __m512 b, __m512 c);
VFMADDxxxPS __m512 _mm512_maskz_fmadd_ps(__mmask16 k, __m512 a, __m512 b, __m512 c);
VFMADDxxxPS __m512 _mm512_mask3_fmadd_ps(__m512 a, __m512 b, __m512 c, __mmask16 k);
VFMADDxxxPS __m512 _mm512_mask_fmadd_round_ps(__m512 a, __mmask16 k, __m512 b, __m512 c, int r);
VFMADDxxxPS __m512 _mm512_maskz_fmadd_round_ps(__mmask16 k, __m512 a, __m512 b, __m512 c, int r);
VFMADDxxxPS __m512 _mm512_mask3_fmadd_round_ps(__m512 a, __m512 b, __m512 c, __mmask16 k, int r);
VFMADDxxxPS __m256 _mm256_mask_fmadd_ps(__m256 a, __mmask8 k, __m256 b, __m256 c);
VFMADDxxxPS __m256 _mm256_maskz_fmadd_ps(__mmask8 k, __m256 a, __m256 b, __m256 c);
VFMADDxxxPS __m256 _mm256_mask3_fmadd_ps(__m256 a, __m256 b, __m256 c, __mmask8 k);
VFMADDxxxPS __m128 _mm_mask_fmadd_ps(__m128 a, __mmask8 k, __m128 b, __m128 c);
VFMADDxxxPS __m128 _mm_maskz_fmadd_ps(__mmask8 k, __m128 a, __m128 b, __m128 c);
VFMADDxxxPS __m128 _mm_mask3_fmadd_ps(__m128 a, __m128 b, __m128 c, __mmask8 k);
VFMADDxxxPS __m128 _mm_fmadd_ps (__m128 a, __m128 b, __m128 c);
VFMADDxxxPS __m256 _mm256_fmadd_ps (__m256 a, __m256 b, __m256 c);
SIMD Floating-Point Exceptions
Overflow, Underflow, Invalid, Precision, Denormal
Other Exceptions
VEX-encoded instructions, see Table 2-19, “Type 2 Class Exception Conditions.”
EVEX-encoded instructions, see Table 2-46, “Type E2 Class Exception Conditions.”
VFMADD132PS/VFMADD213PS/VFMADD231PS—Fused Multiply-Add of Packed Single Precision Floating-Point Values
Vol. 2C
5-211
INSTRUCTION SET REFERENCE, V
VFMADD132SD/VFMADD213SD/VFMADD231SD—Fused Multiply-Add of Scalar Double
Precision Floating-Point Values
Opcode/
Op/
64/32
CPUID
Description
Instruction
En
bit Mode
Feature
Support
Flag
VEX.LIG.66.0F38.W1 99 /r
A
V/V
FMA
Multiply scalar double precision floating-point value
VFMADD132SD xmm1, xmm2,
from xmm1 and xmm3/m64, add to xmm2 and put
xmm3/m64
result in xmm1.
VEX.LIG.66.0F38.W1 A9 /r
A
V/V
FMA
Multiply scalar double precision floating-point value
VFMADD213SD xmm1, xmm2,
from xmm1 and xmm2, add to xmm3/m64 and put
xmm3/m64
result in xmm1.
VEX.LIG.66.0F38.W1 B9 /r
A
V/V
FMA
Multiply scalar double precision floating-point value
VFMADD231SD xmm1, xmm2,
from xmm2 and xmm3/m64, add to xmm1 and put
xmm3/m64
result in xmm1.
EVEX.LLIG.66.0F38.W1 99 /r
B
V/V
AVX512F
Multiply scalar double precision floating-point value
VFMADD132SD xmm1 {k1}{z}, xmm2,
from xmm1 and xmm3/m64, add to xmm2 and put
xmm3/m64{er}
result in xmm1.
EVEX.LLIG.66.0F38.W1 A9 /r
B
V/V
AVX512F
Multiply scalar double precision floating-point value
VFMADD213SD xmm1 {k1}{z}, xmm2,
from xmm1 and xmm2, add to xmm3/m64 and put
xmm3/m64{er}
result in xmm1.
EVEX.LLIG.66.0F38.W1 B9 /r
B
V/V
AVX512F
Multiply scalar double precision floating-point value
VFMADD231SD xmm1 {k1}{z}, xmm2,
from xmm2 and xmm3/m64, add to xmm1 and put
xmm3/m64{er}
result in xmm1.
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:reg (r, w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
B
Tuple1 Scalar
ModRM:reg (r, w)
EVEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
Performs a SIMD multiply-add computation on the low double precision floating-point values using three source
operands and writes the multiply-add result in the destination operand. The destination operand is also the first
source operand. The first and second operand are XMM registers. The third source operand can be an XMM register
or a 64-bit memory location.
VFMADD132SD: Multiplies the low double precision floating-point value from the first source operand to the low
double precision floating-point value in the third source operand, adds the infinite precision intermediate result to
the low double precision floating-point values in the second source operand, performs rounding and stores the
resulting double precision floating-point value to the destination operand (first source operand).
VFMADD213SD: Multiplies the low double precision floating-point value from the second source operand to the low
double precision floating-point value in the first source operand, adds the infinite precision intermediate result to
the low double precision floating-point value in the third source operand, performs rounding and stores the
resulting double precision floating-point value to the destination operand (first source operand).
VFMADD231SD: Multiplies the low double precision floating-point value from the second source to the low double
precision floating-point value in the third source operand, adds the infinite precision intermediate result to the low
double precision floating-point value in the first source operand, performs rounding and stores the resulting double
precision floating-point value to the destination operand (first source operand).
VEX.128 and EVEX encoded version: The destination operand (also first source operand) is encoded in reg_field.
The second source operand is encoded in VEX.vvvv/EVEX.vvvv. The third source operand is encoded in rm_field.
Bits 127:64 of the destination are unchanged. Bits MAXVL-1:128 of the destination register are zeroed.
EVEX encoded version: The low quadword element of the destination is updated according to the writemask.
5-212
Vol. 2C
VFMADD132SD/VFMADD213SD/VFMADD231SD—Fused Multiply-Add of Scalar Double Precision Floating-Point Values
INSTRUCTION SET REFERENCE, V
Operation
In the operations below, “*” and “+” symbols represent multiplication and addition with infinite precision inputs and outputs (no
rounding).
VFMADD132SD DEST, SRC2, SRC3 (EVEX encoded version)
IF (EVEX.b = 1) and SRC3 *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] := RoundFPControl(DEST[63:0]*SRC3[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] := DEST[127:64]
DEST[MAXVL-1:128] := 0
VFMADD213SD DEST, SRC2, SRC3 (EVEX encoded version)
IF (EVEX.b = 1) and SRC3 *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] := RoundFPControl(SRC2[63:0]*DEST[63:0] + SRC3[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] := DEST[127:64]
DEST[MAXVL-1:128] := 0
VFMADD132SD/VFMADD213SD/VFMADD231SD—Fused Multiply-Add of Scalar Double Precision Floating-Point Values
Vol. 2C
5-213
INSTRUCTION SET REFERENCE, V
VFMADD231SD DEST, SRC2, SRC3 (EVEX encoded version)
IF (EVEX.b = 1) and SRC3 *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] := RoundFPControl(SRC2[63:0]*SRC3[63:0] + DEST[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] := DEST[127:64]
DEST[MAXVL-1:128] := 0
VFMADD132SD DEST, SRC2, SRC3 (VEX encoded version)
DEST[63:0] := MAXVL-1:128RoundFPControl_MXCSR(DEST[63:0]*SRC3[63:0] + SRC2[63:0])
DEST[127:63] := DEST[127:63]
DEST[MAXVL-1:128] := 0
VFMADD213SD DEST, SRC2, SRC3 (VEX encoded version)
DEST[63:0] := RoundFPControl_MXCSR(SRC2[63:0]*DEST[63:0] + SRC3[63:0])
DEST[127:63] := DEST[127:63]
DEST[MAXVL-1:128] := 0
VFMADD231SD DEST, SRC2, SRC3 (VEX encoded version)
DEST[63:0] := RoundFPControl_MXCSR(SRC2[63:0]*SRC3[63:0] + DEST[63:0])
DEST[127:63] := DEST[127:63]
DEST[MAXVL-1:128] := 0
Intel C/C++ Compiler Intrinsic Equivalent
VFMADDxxxSD __m128d _mm_fmadd_round_sd(__m128d a, __m128d b, __m128d c, int r);
VFMADDxxxSD __m128d _mm_mask_fmadd_sd(__m128d a, __mmask8 k, __m128d b, __m128d c);
VFMADDxxxSD __m128d _mm_maskz_fmadd_sd(__mmask8 k, __m128d a, __m128d b, __m128d c);
VFMADDxxxSD __m128d _mm_mask3_fmadd_sd(__m128d a, __m128d b, __m128d c, __mmask8 k);
VFMADDxxxSD __m128d _mm_mask_fmadd_round_sd(__m128d a, __mmask8 k, __m128d b, __m128d c, int r);
VFMADDxxxSD __m128d _mm_maskz_fmadd_round_sd(__mmask8 k, __m128d a, __m128d b, __m128d c, int r);
VFMADDxxxSD __m128d _mm_mask3_fmadd_round_sd(__m128d a, __m128d b, __m128d c, __mmask8 k, int r);
VFMADDxxxSD __m128d _mm_fmadd_sd (__m128d a, __m128d b, __m128d c);
SIMD Floating-Point Exceptions
Overflow, Underflow, Invalid, Precision, Denormal
Other Exceptions
VEX-encoded instructions, see Table 2-20, “Type 3 Class Exception Conditions.”
EVEX-encoded instructions, see Table 2-47, “Type E3 Class Exception Conditions.”
5-214
Vol. 2C
VFMADD132SD/VFMADD213SD/VFMADD231SD—Fused Multiply-Add of Scalar Double Precision Floating-Point Values
INSTRUCTION SET REFERENCE, V
VF[,N]MADD[132,213,231]SH—Fused Multiply-Add of Scalar FP16 Values
Opcode/
Op/
64/32
CPUID Feature
Description
Instruction
En
bit Mode
Flag
Support
EVEX.LLIG.66.MAP6.W0 99 /r
A
V/V
AVX512-FP16
Multiply FP16 values from xmm1 and xmm3/
VFMADD132SH xmm1{k1}{z}, xmm2,
m16, add to xmm2, and store the result in xmm1.
xmm3/m16 {er}
EVEX.LLIG.66.MAP6.W0 A9 /r
A
V/V
AVX512-FP16
Multiply FP16 values from xmm1 and xmm2, add
VFMADD213SH xmm1{k1}{z}, xmm2,
to xmm3/m16, and store the result in xmm1.
xmm3/m16 {er}
EVEX.LLIG.66.MAP6.W0 B9 /r
A
V/V
AVX512-FP16
Multiply FP16 values from xmm2 and xmm3/
VFMADD231SH xmm1{k1}{z}, xmm2,
m16, add to xmm1, and store the result in xmm1.
xmm3/m16 {er}
EVEX.LLIG.66.MAP6.W0 9D /r
A
V/V
AVX512-FP16
Multiply FP16 values from xmm1 and xmm3/
VFNMADD132SH xmm1{k1}{z},
m16, and negate the value. Add this value to
xmm2, xmm3/m16 {er}
xmm2, and store the result in xmm1.
EVEX.LLIG.66.MAP6.W0 AD /r
A
V/V
AVX512-FP16
Multiply FP16 values from xmm1 and xmm2, and
VFNMADD213SH xmm1{k1}{z},
negate the value. Add this value to xmm3/m16,
xmm2, xmm3/m16 {er}
and store the result in xmm1.
EVEX.LLIG.66.MAP6.W0 BD /r
A
V/V
AVX512-FP16
Multiply FP16 values from xmm2 and xmm3/
VFNMADD231SH xmm1{k1}{z},
m16, and negate the value. Add this value to
xmm2, xmm3/m16 {er}
xmm1, and store the result in xmm1.
Instruction Operand Encoding
Op/En
Tuple
Operand 1
Operand 2
Operand 3
Operand 4
A
Scalar
ModRM:reg (r, w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
Performs a scalar multiply-add or negated multiply-add computation on the low FP16 values using three source
operands and writes the result in the destination operand. The destination operand is also the first source operand.
The “N” (negated) forms of this instruction add the negated infinite precision intermediate product to the corre-
sponding remaining operand. The notation’ “132”, “213” and “231” indicate the use of the operands in ±A * B + C,
where each digit corresponds to the operand number, with the destination being operand 1; see Table 5-3.
Bits 127:16 of the destination operand are preserved. Bits MAXVL-1:128 of the destination operand are zeroed. The
low FP16 element of the destination is updated according to the writemask.
Table 5-3. VF[,N]MADD[132,213,231]SH Notation for Operands
Notation
Operands
132
dest = ± dest*src3+src2
231
dest = ± src2*src3+dest
213
dest = ± src2*dest+src3
VF[,N]MADD[132,213,231]SH—Fused Multiply-Add of Scalar FP16 Values
Vol. 2C
5-215
INSTRUCTION SET REFERENCE, V
Operation
VF[,N]MADD132SH DEST, SRC2, SRC3 (EVEX encoded versions)
IF EVEX.b = 1 and SRC3 is a register:
SET_RM(EVEX.RC)
ELSE
SET_RM(MXCSR.RC)
IF k1[0] OR *no writemask*:
IF *negative form*:
DEST.fp16[0] := RoundFPControl(-DEST.fp16[0]*SRC3.fp16[0] + SRC2.fp16[0])
ELSE:
DEST.fp16[0] := RoundFPControl(DEST.fp16[0]*SRC3.fp16[0] + SRC2.fp16[0])
ELSE IF *zeroing*:
DEST.fp16[0] := 0
// else DEST.fp16[0] remains unchanged
//DEST[127:16] remains unchanged
DEST[MAXVL-1:128] := 0
VF[,N]MADD213SH DEST, SRC2, SRC3 (EVEX encoded versions)
IF EVEX.b = 1 and SRC3 is a register:
SET_RM(EVEX.RC)
ELSE
SET_RM(MXCSR.RC)
IF k1[0] OR *no writemask*:
IF *negative form:
DEST.fp16[0] := RoundFPControl(-SRC2.fp16[0]*DEST.fp16[0] + SRC3.fp16[0])
ELSE:
DEST.fp16[0] := RoundFPControl(SRC2.fp16[0]*DEST.fp16[0] + SRC3.fp16[0])
ELSE IF *zeroing*:
DEST.fp16[0] := 0
// else DEST.fp16[0] remains unchanged
//DEST[127:16] remains unchanged
DEST[MAXVL-1:128] := 0
VF[,N]MADD231SH DEST, SRC2, SRC3 (EVEX encoded versions)
IF EVEX.b = 1 and SRC3 is a register:
SET_RM(EVEX.RC)
ELSE
SET_RM(MXCSR.RC)
IF k1[0] OR *no writemask*:
IF *negative form*:
DEST.fp16[0] := RoundFPControl(-SRC2.fp16[0]*SRC3.fp16[0] + DEST.fp16[0])
ELSE:
DEST.fp16[0] := RoundFPControl(SRC2.fp16[0]*SRC3.fp16[0] + DEST.fp16[0])
ELSE IF *zeroing*:
DEST.fp16[0] := 0
// else DEST.fp16[0] remains unchanged
//DEST[127:16] remains unchanged
DEST[MAXVL-1:128] := 0
5-216
Vol. 2C
VF[,N]MADD[132,213,231]SH—Fused Multiply-Add of Scalar FP16 Values
INSTRUCTION SET REFERENCE, V
Intel C/C++ Compiler Intrinsic Equivalent
VFMADD132SH, VFMADD213SH, and VFMADD231SH:
__m128h _mm_fmadd_round_sh (__m128h a, __m128h b, __m128h c, const int rounding);
__m128h _mm_mask_fmadd_round_sh (__m128h a, __mmask8 k, __m128h b, __m128h c, const int rounding);
__m128h _mm_mask3_fmadd_round_sh (__m128h a, __m128h b, __m128h c, __mmask8 k, const int rounding);
__m128h _mm_maskz_fmadd_round_sh (__mmask8 k, __m128h a, __m128h b, __m128h c, const int rounding);
__m128h _mm_fmadd_sh (__m128h a, __m128h b, __m128h c);
__m128h _mm_mask_fmadd_sh (__m128h a, __mmask8 k, __m128h b, __m128h c);
__m128h _mm_mask3_fmadd_sh (__m128h a, __m128h b, __m128h c, __mmask8 k);
__m128h _mm_maskz_fmadd_sh (__mmask8 k, __m128h a, __m128h b, __m128h c);
VFNMADD132SH, VFNMADD213SH, and VFNMADD231SH:
__m128h _mm_fnmadd_round_sh (__m128h a, __m128h b, __m128h c, const int rounding);
__m128h _mm_mask_fnmadd_round_sh (__m128h a, __mmask8 k, __m128h b, __m128h c, const int rounding);
__m128h _mm_mask3_fnmadd_round_sh (__m128h a, __m128h b, __m128h c, __mmask8 k, const int rounding);
__m128h _mm_maskz_fnmadd_round_sh (__mmask8 k, __m128h a, __m128h b, __m128h c, const int rounding);
__m128h _mm_fnmadd_sh (__m128h a, __m128h b, __m128h c);
__m128h _mm_mask_fnmadd_sh (__m128h a, __mmask8 k, __m128h b, __m128h c);
__m128h _mm_mask3_fnmadd_sh (__m128h a, __m128h b, __m128h c, __mmask8 k);
__m128h _mm_maskz_fnmadd_sh (__mmask8 k, __m128h a, __m128h b, __m128h c);
SIMD Floating-Point Exceptions
Invalid, Underflow, Overflow, Precision, Denormal
Other Exceptions
EVEX-encoded instructions, see Table 2-47, “Type E3 Class Exception Conditions.”
VF[,N]MADD[132,213,231]SH—Fused Multiply-Add of Scalar FP16 Values
Vol. 2C
5-217
INSTRUCTION SET REFERENCE, V
VFMADD132SS/VFMADD213SS/VFMADD231SS—Fused Multiply-Add of Scalar Single Precision
Floating-Point Values
Opcode/
Op /
64/32
CPUID
Description
Instruction
En
bit Mode
Feature
Support
Flag
VEX.LIG.66.0F38.W0 99 /r
A
V/V
FMA
Multiply scalar single precision floating-point value
VFMADD132SS xmm1, xmm2,
from xmm1 and xmm3/m32, add to xmm2 and put
xmm3/m32
result in xmm1.
VEX.LIG.66.0F38.W0 A9 /r
A
V/V
FMA
Multiply scalar single precision floating-point value
VFMADD213SS xmm1, xmm2,
from xmm1 and xmm2, add to xmm3/m32 and put
xmm3/m32
result in xmm1.
VEX.LIG.66.0F38.W0 B9 /r
A
V/V
FMA
Multiply scalar single precision floating-point value
VFMADD231SS xmm1, xmm2,
from xmm2 and xmm3/m32, add to xmm1 and put
xmm3/m32
result in xmm1.
EVEX.LLIG.66.0F38.W0 99 /r
B
V/V
AVX512F
Multiply scalar single precision floating-point value
VFMADD132SS xmm1 {k1}{z}, xmm2,
from xmm1 and xmm3/m32, add to xmm2 and put
xmm3/m32{er}
result in xmm1.
EVEX.LLIG.66.0F38.W0 A9 /r
B
V/V
AVX512F
Multiply scalar single precision floating-point value
VFMADD213SS xmm1 {k1}{z}, xmm2,
from xmm1 and xmm2, add to xmm3/m32 and put
xmm3/m32{er}
result in xmm1.
EVEX.LLIG.66.0F38.W0 B9 /r
B
V/V
AVX512F
Multiply scalar single precision floating-point value
VFMADD231SS xmm1 {k1}{z}, xmm2,
from xmm2 and xmm3/m32, add to xmm1 and put
xmm3/m32{er}
result in xmm1.
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:reg (r, w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
B
Tuple1 Scalar
ModRM:reg (r, w)
EVEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
Performs a SIMD multiply-add computation on single precision floating-point values using three source operands
and writes the multiply-add results in the destination operand. The destination operand is also the first source
operand. The first and second operands are XMM registers. The third source operand can be a XMM register or a 32-
bit memory location.
VFMADD132SS: Multiplies the low single precision floating-point value from the first source operand to the low
single precision floating-point value in the third source operand, adds the infinite precision intermediate result to
the low single precision floating-point value in the second source operand, performs rounding and stores the
resulting single precision floating-point value to the destination operand (first source operand).
VFMADD213SS: Multiplies the low single precision floating-point value from the second source operand to the low
single precision floating-point value in the first source operand, adds the infinite precision intermediate result to the
low single precision floating-point value in the third source operand, performs rounding and stores the resulting
single precision floating-point value to the destination operand (first source operand).
VFMADD231SS: Multiplies the low single precision floating-point value from the second source operand to the low
single precision floating-point value in the third source operand, adds the infinite precision intermediate result to
the low single precision floating-point value in the first source operand, performs rounding and stores the resulting
single precision floating-point value to the destination operand (first source operand).
VEX.128 and EVEX encoded version: The destination operand (also first source operand) is encoded in reg_field.
The second source operand is encoded in VEX.vvvv/EVEX.vvvv. The third source operand is encoded in rm_field.
Bits 127:32 of the destination are unchanged. Bits MAXVL-1:128 of the destination register are zeroed.
5-218
Vol. 2C
VFMADD132SS/VFMADD213SS/VFMADD231SS—Fused Multiply-Add of Scalar Single Precision Floating-Point Values
INSTRUCTION SET REFERENCE, V
EVEX encoded version: The low doubleword element of the destination is updated according to the writemask.
Compiler tools may optionally support a complementary mnemonic for each instruction mnemonic listed in the
opcode/instruction column of the summary table. The behavior of the complementary mnemonic in situations
involving NANs are governed by the definition of the instruction mnemonic defined in the opcode/instruction
column.
Operation
In the operations below, “*” and “+” symbols represent multiplication and addition with infinite precision inputs and outputs (no
rounding).
VFMADD132SS DEST, SRC2, SRC3 (EVEX encoded version)
IF (EVEX.b = 1) and SRC3 *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] := RoundFPControl(DEST[31:0]*SRC3[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] := DEST[127:32]
DEST[MAXVL-1:128] := 0
VFMADD213SS DEST, SRC2, SRC3 (EVEX encoded version)
IF (EVEX.b = 1) and SRC3 *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] := RoundFPControl(SRC2[31:0]*DEST[31:0] + SRC3[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] := DEST[127:32]
DEST[MAXVL-1:128] := 0
VFMADD132SS/VFMADD213SS/VFMADD231SS—Fused Multiply-Add of Scalar Single Precision Floating-Point Values
Vol. 2C
5-219
INSTRUCTION SET REFERENCE, V
VFMADD231SS DEST, SRC2, SRC3 (EVEX encoded version)
IF (EVEX.b = 1) and SRC3 *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] := RoundFPControl(SRC2[31:0]*SRC3[31:0] + DEST[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] := DEST[127:32]
DEST[MAXVL-1:128] := 0
VFMADD132SS DEST, SRC2, SRC3 (VEX encoded version)
DEST[31:0] := RoundFPControl_MXCSR(DEST[31:0]*SRC3[31:0] + SRC2[31:0])
DEST[127:32] := DEST[127:32]
DEST[MAXVL-1:128] := 0
VFMADD213SS DEST, SRC2, SRC3 (VEX encoded version)
DEST[31:0] := RoundFPControl_MXCSR(SRC2[31:0]*DEST[31:0] + SRC3[31:0])
DEST[127:32] := DEST[127:32]
DEST[MAXVL-1:128] := 0
VFMADD231SS DEST, SRC2, SRC3 (VEX encoded version)
DEST[31:0] := RoundFPControl_MXCSR(SRC2[31:0]*SRC3[31:0] + DEST[31:0])
DEST[127:32] := DEST[127:32]
DEST[MAXVL-1:128] := 0
Intel C/C++ Compiler Intrinsic Equivalent
VFMADDxxxSS __m128 _mm_fmadd_round_ss(__m128 a, __m128 b, __m128 c, int r);
VFMADDxxxSS __m128 _mm_mask_fmadd_ss(__m128 a, __mmask8 k, __m128 b, __m128 c);
VFMADDxxxSS __m128 _mm_maskz_fmadd_ss(__mmask8 k, __m128 a, __m128 b, __m128 c);
VFMADDxxxSS __m128 _mm_mask3_fmadd_ss(__m128 a, __m128 b, __m128 c, __mmask8 k);
VFMADDxxxSS __m128 _mm_mask_fmadd_round_ss(__m128 a, __mmask8 k, __m128 b, __m128 c, int r);
VFMADDxxxSS __m128 _mm_maskz_fmadd_round_ss(__mmask8 k, __m128 a, __m128 b, __m128 c, int r);
VFMADDxxxSS __m128 _mm_mask3_fmadd_round_ss(__m128 a, __m128 b, __m128 c, __mmask8 k, int r);
VFMADDxxxSS __m128 _mm_fmadd_ss (__m128 a, __m128 b, __m128 c);
SIMD Floating-Point Exceptions
Overflow, Underflow, Invalid, Precision, Denormal
Other Exceptions
VEX-encoded instructions, see Table 2-20, “Type 3 Class Exception Conditions.”
EVEX-encoded instructions, see Table 2-47, “Type E3 Class Exception Conditions.”
5-220
Vol. 2C
VFMADD132SS/VFMADD213SS/VFMADD231SS—Fused Multiply-Add of Scalar Single Precision Floating-Point Values
INSTRUCTION SET REFERENCE, V
VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD—Fused Multiply-Alternating
Add/Subtract of Packed Double Precision Floating-Point Values
Opcode/
Op /
64/32
CPUID
Description
Instruction
En
bit Mode
Feature
Support
Flag
VEX.128.66.0F38.W1 96 /r
A
V/V
FMA
Multiply packed double precision floating-point values
VFMADDSUB132PD xmm1, xmm2,
from xmm1 and xmm3/mem, add/subtract elements in
xmm3/m128
xmm2 and put result in xmm1.
VEX.128.66.0F38.W1 A6 /r
A
V/V
FMA
Multiply packed double precision floating-point values
VFMADDSUB213PD xmm1, xmm2,
from xmm1 and xmm2, add/subtract elements in
xmm3/m128
xmm3/mem and put result in xmm1.
VEX.128.66.0F38.W1 B6 /r
A
V/V
FMA
Multiply packed double precision floating-point values
VFMADDSUB231PD xmm1, xmm2,
from xmm2 and xmm3/mem, add/subtract elements in
xmm3/m128
xmm1 and put result in xmm1.
VEX.256.66.0F38.W1 96 /r
A
V/V
FMA
Multiply packed double precision floating-point values
VFMADDSUB132PD ymm1, ymm2,
from ymm1 and ymm3/mem, add/subtract elements in
ymm3/m256
ymm2 and put result in ymm1.
VEX.256.66.0F38.W1 A6 /r
A
V/V
FMA
Multiply packed double precision floating-point values
VFMADDSUB213PD ymm1, ymm2,
from ymm1 and ymm2, add/subtract elements in
ymm3/m256
ymm3/mem and put result in ymm1.
VEX.256.66.0F38.W1 B6 /r
A
V/V
FMA
Multiply packed double precision floating-point values
VFMADDSUB231PD ymm1, ymm2,
from ymm2 and ymm3/mem, add/subtract elements in
ymm3/m256
ymm1 and put result in ymm1.
EVEX.128.66.0F38.W1 A6 /r
B
V/V
AVX512VL
Multiply packed double precision floating-point values
VFMADDSUB213PD xmm1 {k1}{z},
AVX512F
from xmm1 and xmm2, add/subtract elements in
xmm2, xmm3/m128/m64bcst
xmm3/m128/m64bcst and put result in xmm1 subject to
writemask k1.
EVEX.128.66.0F38.W1 B6 /r
B
V/V
AVX512VL
Multiply packed double precision floating-point values
VFMADDSUB231PD xmm1 {k1}{z},
AVX512F
from xmm2 and xmm3/m128/m64bcst, add/subtract
xmm2, xmm3/m128/m64bcst
elements in xmm1 and put result in xmm1 subject to
writemask k1.
EVEX.128.66.0F38.W1 96 /r
B
V/V
AVX512VL
Multiply packed double precision floating-point values
VFMADDSUB132PD xmm1 {k1}{z},
AVX512F
from xmm1 and xmm3/m128/m64bcst, add/subtract
xmm2, xmm3/m128/m64bcst
elements in xmm2 and put result in xmm1 subject to
writemask k1.
EVEX.256.66.0F38.W1 A6 /r
B
V/V
AVX512VL
Multiply packed double precision floating-point values
VFMADDSUB213PD ymm1 {k1}{z},
AVX512F
from ymm1 and ymm2, add/subtract elements in
ymm2, ymm3/m256/m64bcst
ymm3/m256/m64bcst and put result in ymm1 subject to
writemask k1.
EVEX.256.66.0F38.W1 B6 /r
B
V/V
AVX512VL
Multiply packed double precision floating-point values
VFMADDSUB231PD ymm1 {k1}{z},
AVX512F
from ymm2 and ymm3/m256/m64bcst, add/subtract
ymm2, ymm3/m256/m64bcst
elements in ymm1 and put result in ymm1 subject to
writemask k1.
EVEX.256.66.0F38.W1 96 /r
B
V/V
AVX512VL
Multiply packed double precision floating-point values
VFMADDSUB132PD ymm1 {k1}{z},
AVX512F
from ymm1 and ymm3/m256/m64bcst, add/subtract
ymm2, ymm3/m256/m64bcst
elements in ymm2 and put result in ymm1 subject to
writemask k1.
VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD—Fused Multiply-Alternating Add/Subtract of Packed Double Precision
Vol. 2C
5-221
INSTRUCTION SET REFERENCE, V
Opcode/
Op /
64/32
CPUID
Description
Instruction
En
bit Mode
Feature
Support
Flag
EVEX.512.66.0F38.W1 A6 /r
B
V/V
AVX512F
Multiply packed double precision floating-point values
VFMADDSUB213PD zmm1 {k1}{z},
from zmm1and zmm2, add/subtract elements in
zmm2, zmm3/m512/m64bcst{er}
zmm3/m512/m64bcst and put result in zmm1 subject to
writemask k1.
EVEX.512.66.0F38.W1 B6 /r
B
V/V
AVX512F
Multiply packed double precision floating-point values
VFMADDSUB231PD zmm1 {k1}{z},
from zmm2 and zmm3/m512/m64bcst, add/subtract
zmm2, zmm3/m512/m64bcst{er}
elements in zmm1 and put result in zmm1 subject to
writemask k1.
EVEX.512.66.0F38.W1 96 /r
B
V/V
AVX512F
Multiply packed double precision floating-point values
VFMADDSUB132PD zmm1 {k1}{z},
from zmm1 and zmm3/m512/m64bcst, add/subtract
zmm2, zmm3/m512/m64bcst{er}
elements in zmm2 and put result in 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)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
B
Full
ModRM:reg (r, w)
EVEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
VFMADDSUB132PD: Multiplies the two, four, or eight packed double precision floating-point values from the first
source operand to the two or four packed double precision floating-point values in the third source operand. From
the infinite precision intermediate result, adds the odd double precision floating-point elements and subtracts the
even double precision floating-point values in the second source operand, performs rounding and stores the
resulting two or four packed double precision floating-point values to the destination operand (first source
operand).
VFMADDSUB213PD: Multiplies the two, four, or eight packed double precision floating-point values from the second
source operand to the two or four packed double precision floating-point values in the first source operand. From
the infinite precision intermediate result, adds the odd double precision floating-point elements and subtracts the
even double precision floating-point values in the third source operand, performs rounding and stores the resulting
two or four packed double precision floating-point values to the destination operand (first source operand).
VFMADDSUB231PD: Multiplies the two, four, or eight packed double precision floating-point values from the second
source operand to the two or four packed double precision floating-point values in the third source operand. From
the infinite precision intermediate result, adds the odd double precision floating-point elements and subtracts the
even double precision floating-point values in the first source operand, performs rounding and stores the resulting
two or four packed double precision floating-point values to the destination operand (first source operand).
EVEX encoded versions: The destination operand (also first source operand) and the second source operand are
ZMM/YMM/XMM register. The third source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory loca-
tion or a 512/256/128-bit vector broadcasted from a 64-bit memory location. The destination operand is condition-
ally updated with write mask k1.
VEX.256 encoded version: The destination operand (also first source operand) is a YMM register and encoded in
reg_field. The second source operand is a YMM register and encoded in VEX.vvvv. The third source operand is a
YMM register or a 256-bit memory location and encoded in rm_field.
VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD—Fused Multiply-Alternating Add/Subtract of Packed Double Precision
5-222
Vol. 2C
INSTRUCTION SET REFERENCE, V
VEX.128 encoded version: The destination operand (also first source operand) is a XMM register and encoded in
reg_field. The second source operand is a XMM register and encoded in VEX.vvvv. The third source operand is a
XMM register or a 128-bit memory location and encoded in rm_field. The upper 128 bits of the YMM destination
register are zeroed.
Compiler tools may optionally support a complementary mnemonic for each instruction mnemonic listed in the
opcode/instruction column of the summary table. The behavior of the complementary mnemonic in situations
involving NANs are governed by the definition of the instruction mnemonic defined in the opcode/instruction
column.
Operation
In the operations below, “*” and “-” symbols represent multiplication and subtraction with infinite precision inputs and outputs (no
rounding).
VFMADDSUB132PD DEST, SRC2, SRC3
IF (VEX.128) THEN
DEST[63:0] := RoundFPControl_MXCSR(DEST[63:0]*SRC3[63:0] - SRC2[63:0])
DEST[127:64] := RoundFPControl_MXCSR(DEST[127:64]*SRC3[127:64] + SRC2[127:64])
DEST[MAXVL-1:128] := 0
ELSEIF (VEX.256)
DEST[63:0] := RoundFPControl_MXCSR(DEST[63:0]*SRC3[63:0] - SRC2[63:0])
DEST[127:64] := RoundFPControl_MXCSR(DEST[127:64]*SRC3[127:64] + SRC2[127:64])
DEST[191:128] := RoundFPControl_MXCSR(DEST[191:128]*SRC3[191:128] - SRC2[191:128])
DEST[255:192] := RoundFPControl_MXCSR(DEST[255:192]*SRC3[255:192] + SRC2[255:192]
FI
VFMADDSUB213PD DEST, SRC2, SRC3
IF (VEX.128) THEN
DEST[63:0] := RoundFPControl_MXCSR(SRC2[63:0]*DEST[63:0] - SRC3[63:0])
DEST[127:64] := RoundFPControl_MXCSR(SRC2[127:64]*DEST[127:64] + SRC3[127:64])
DEST[MAXVL-1:128] := 0
ELSEIF (VEX.256)
DEST[63:0] := RoundFPControl_MXCSR(SRC2[63:0]*DEST[63:0] - SRC3[63:0])
DEST[127:64] := RoundFPControl_MXCSR(SRC2[127:64]*DEST[127:64] + SRC3[127:64])
DEST[191:128] := RoundFPControl_MXCSR(SRC2[191:128]*DEST[191:128] - SRC3[191:128])
DEST[255:192] := RoundFPControl_MXCSR(SRC2[255:192]*DEST[255:192] + SRC3[255:192]
FI
VFMADDSUB231PD DEST, SRC2, SRC3
IF (VEX.128) THEN
DEST[63:0] := RoundFPControl_MXCSR(SRC2[63:0]*SRC3[63:0] - DEST[63:0])
DEST[127:64] := RoundFPControl_MXCSR(SRC2[127:64]*SRC3[127:64] + DEST[127:64])
DEST[MAXVL-1:128] := 0
ELSEIF (VEX.256)
DEST[63:0] := RoundFPControl_MXCSR(SRC2[63:0]*SRC3[63:0] - DEST[63:0])
DEST[127:64] := RoundFPControl_MXCSR(SRC2[127:64]*SRC3[127:64] + DEST[127:64])
DEST[191:128] := RoundFPControl_MXCSR(SRC2[191:128]*SRC3[191:128] - DEST[191:128])
DEST[255:192] := RoundFPControl_MXCSR(SRC2[255:192]*SRC3[255:192] + DEST[255:192]
FI
VFMADDSUB132PD DEST, SRC2, SRC3 (EVEX encoded version, when src3 operand is a register)
(KL, VL) = (2, 128), (4, 256), (8, 512)
IF (VL = 512) AND (EVEX.b = 1)
THEN
SET_ROUNDING_MODE_FOR_THIS_INSTRUCTION(EVEX.RC);
VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD—Fused Multiply-Alternating Add/Subtract of Packed Double Precision
Vol. 2C
5-223
INSTRUCTION SET REFERENCE, V
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 j *is even*
THEN DEST[i+63:i] :=
RoundFPControl(DEST[i+63:i]*SRC3[i+63:i] - SRC2[i+63:i])
ELSE DEST[i+63:i] :=
RoundFPControl(DEST[i+63:i]*SRC3[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
VFMADDSUB132PD DEST, SRC2, SRC3 (EVEX encoded version, when src3 operand is a memory source)
(KL, VL) = (2, 128), (4, 256), (8, 512)
FOR j := 0 TO KL-1
i := j * 64
IF k1[j] OR *no writemask*
THEN
IF j *is even*
THEN
IF (EVEX.b = 1)
THEN
DEST[i+63:i] :=
RoundFPControl_MXCSR(DEST[i+63:i]*SRC3[63:0] - SRC2[i+63:i])
ELSE
DEST[i+63:i] :=
RoundFPControl_MXCSR(DEST[i+63:i]*SRC3[i+63:i] - SRC2[i+63:i])
FI;
ELSE
IF (EVEX.b = 1)
THEN
DEST[i+63:i] :=
RoundFPControl_MXCSR(DEST[i+63:i]*SRC3[63:0] + SRC2[i+63:i])
ELSE
DEST[i+63:i] :=
RoundFPControl_MXCSR(DEST[i+63:i]*SRC3[i+63:i] + SRC2[i+63:i])
FI;
FI
ELSE
IF *merging-masking*
; merging-masking
THEN *DEST[i+63:i] remains unchanged*
VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD—Fused Multiply-Alternating Add/Subtract of Packed Double Precision
5-224
Vol. 2C
INSTRUCTION SET REFERENCE, V
ELSE
; zeroing-masking
DEST[i+63:i] := 0
FI
FI;
ENDFOR
DEST[MAXVL-1:VL] := 0
VFMADDSUB213PD DEST, SRC2, SRC3 (EVEX encoded version, when src3 operand is a register)
(KL, VL) = (2, 128), (4, 256), (8, 512)
IF (VL = 512) AND (EVEX.b = 1)
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 * 64
IF k1[j] OR *no writemask*
THEN
IF j *is even*
THEN DEST[i+63:i] :=
RoundFPControl(SRC2[i+63:i]*DEST[i+63:i] - SRC3[i+63:i])
ELSE DEST[i+63:i] :=
RoundFPControl(SRC2[i+63:i]*DEST[i+63:i] + SRC3[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
VFMADDSUB213PD DEST, SRC2, SRC3 (EVEX encoded version, when src3 operand is a memory source)
(KL, VL) = (2, 128), (4, 256), (8, 512)
FOR j := 0 TO KL-1
i := j * 64
IF k1[j] OR *no writemask*
THEN
IF j *is even*
THEN
IF (EVEX.b = 1)
THEN
DEST[i+63:i] :=
RoundFPControl_MXCSR(SRC2[i+63:i]*DEST[i+63:i] - SRC3[63:0])
ELSE
DEST[i+63:i] :=
RoundFPControl_MXCSR(SRC2[i+63:i]*DEST[i+63:i] - SRC3[i+63:i])
FI;
ELSE
IF (EVEX.b = 1)
VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD—Fused Multiply-Alternating Add/Subtract of Packed Double Precision
Vol. 2C
5-225
INSTRUCTION SET REFERENCE, V
THEN
DEST[i+63:i] :=
RoundFPControl_MXCSR(SRC2[i+63:i]*DEST[i+63:i] + SRC3[63:0])
ELSE
DEST[i+63:i] :=
RoundFPControl_MXCSR(SRC2[i+63:i]*DEST[i+63:i] + SRC3[i+63:i])
FI;
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
VFMADDSUB231PD DEST, SRC2, SRC3 (EVEX encoded version, when src3 operand is a register)
(KL, VL) = (2, 128), (4, 256), (8, 512)
IF (VL = 512) AND (EVEX.b = 1)
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 * 64
IF k1[j] OR *no writemask*
THEN
IF j *is even*
THEN DEST[i+63:i] :=
RoundFPControl(SRC2[i+63:i]*SRC3[i+63:i] - DEST[i+63:i])
ELSE DEST[i+63:i] :=
RoundFPControl(SRC2[i+63:i]*SRC3[i+63:i] + DEST[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
VFMADDSUB231PD DEST, SRC2, SRC3 (EVEX encoded version, when src3 operand is a memory source)
(KL, VL) = (2, 128), (4, 256), (8, 512)
FOR j := 0 TO KL-1
i := j * 64
IF k1[j] OR *no writemask*
THEN
IF j *is even*
VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD—Fused Multiply-Alternating Add/Subtract of Packed Double Precision
5-226
Vol. 2C

 

 

 

 

 

 

 

Content      ..     94      95      96      97     ..