|
|
VFMADD132SD/VFMADD213SD/VFMADD231SD-Fused Multiply-Add of Scalar Double
Precision Floating-Point Values
Opcode/
Op/
64/32
CPUID
Description
Instruction
En
Bit Mode
Feature Flag
Support
VEX.LIG.66.0F38.W1 99 /r
A
V/V
FMA
Multiply scalar double precision floating-point
VFMADD132SD xmm1, xmm2,
value from xmm1 and xmm3/m64, add to xmm2
xmm3/m64
and put result in xmm1.
VEX.LIG.66.0F38.W1 A9 /r
A
V/V
FMA
Multiply scalar double precision floating-point
VFMADD213SD xmm1, xmm2,
value from xmm1 and xmm2, add to xmm3/m64
xmm3/m64
and put result in xmm1.
VEX.LIG.66.0F38.W1 B9 /r
A
V/V
FMA
Multiply scalar double precision floating-point
VFMADD231SD xmm1, xmm2,
value from xmm2 and xmm3/m64, add to xmm1
xmm3/m64
and put result in xmm1.
EVEX.LLIG.66.0F38.W1 99 /r
B
V/V
AVX512F
Multiply scalar double precision floating-point
VFMADD132SD xmm1 {k1}{z}, xmm2,
OR AVX10.1
value from xmm1 and xmm3/m64, add to xmm2
xmm3/m64{er}
and put result in xmm1.
EVEX.LLIG.66.0F38.W1 A9 /r
B
V/V
AVX512F
Multiply scalar double precision floating-point
VFMADD213SD xmm1 {k1}{z}, xmm2,
OR AVX10.1
value from xmm1 and xmm2, add to xmm3/m64
xmm3/m64{er}
and put result in xmm1.
EVEX.LLIG.66.0F38.W1 B9 /r
B
V/V
AVX512F
Multiply scalar double precision floating-point
VFMADD231SD xmm1 {k1}{z}, xmm2,
OR AVX10.1
value from xmm2 and xmm3/m64, add to xmm1
xmm3/m64{er}
and put 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.
VFMADD132SD/VFMADD213SD/VFMADD231SD-Fused Multiply-Add of Scalar Double Precision Floating-Point Values
Vol. 2C
5-226
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-227
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-49, “Type E3 Class Exception Conditions.”
VFMADD132SD/VFMADD213SD/VFMADD231SD-Fused Multiply-Add of Scalar Double Precision Floating-Point Values
Vol. 2C
5-228
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
VFMADD132SH xmm1{k1}{z}, xmm2,
OR AVX10.1
xmm3/m16, add to xmm2, and store the result in
xmm3/m16 {er}
xmm1.
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,
OR AVX10.1
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
VFMADD231SH xmm1{k1}{z}, xmm2,
OR AVX10.1
xmm3/m16, add to xmm1, and store the result in
xmm3/m16 {er}
xmm1.
EVEX.LLIG.66.MAP6.W0 9D /r
A
V/V
AVX512_FP16
Multiply FP16 values from xmm1 and
VFNMADD132SH xmm1{k1}{z},
OR AVX10.1
xmm3/m16, and negate the value. Add this value
xmm2, xmm3/m16 {er}
to 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},
OR AVX10.1
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
VFNMADD231SH xmm1{k1}{z},
OR AVX10.1
xmm3/m16, and negate the value. Add this value
xmm2, xmm3/m16 {er}
to 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-6.
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-6. 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-229
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
VF[,N]MADD[132,213,231]SH-Fused Multiply-Add of Scalar FP16 Values
Vol. 2C
5-230
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-49, “Type E3 Class Exception Conditions.”
VF[,N]MADD[132,213,231]SH-Fused Multiply-Add of Scalar FP16 Values
Vol. 2C
5-231
VFMADD132SS/VFMADD213SS/VFMADD231SS-Fused Multiply-Add of Scalar Single Precision
Floating-Point Values
Opcode/
Op /
64/32
CPUID
Description
Instruction
En
Bit Mode
Feature Flag
Support
VEX.LIG.66.0F38.W0 99 /r
A
V/V
FMA
Multiply scalar single precision floating-point
VFMADD132SS xmm1, xmm2,
value from xmm1 and xmm3/m32, add to xmm2
xmm3/m32
and put result in xmm1.
VEX.LIG.66.0F38.W0 A9 /r
A
V/V
FMA
Multiply scalar single precision floating-point
VFMADD213SS xmm1, xmm2,
value from xmm1 and xmm2, add to xmm3/m32
xmm3/m32
and put result in xmm1.
VEX.LIG.66.0F38.W0 B9 /r
A
V/V
FMA
Multiply scalar single precision floating-point
VFMADD231SS xmm1, xmm2,
value from xmm2 and xmm3/m32, add to xmm1
xmm3/m32
and put result in xmm1.
EVEX.LLIG.66.0F38.W0 99 /r
B
V/V
AVX512F
Multiply scalar single precision floating-point
VFMADD132SS xmm1 {k1}{z}, xmm2,
OR AVX10.1
value from xmm1 and xmm3/m32, add to xmm2
xmm3/m32{er}
and put result in xmm1.
EVEX.LLIG.66.0F38.W0 A9 /r
B
V/V
AVX512F
Multiply scalar single precision floating-point
VFMADD213SS xmm1 {k1}{z}, xmm2,
OR AVX10.1
value from xmm1 and xmm2, add to xmm3/m32
xmm3/m32{er}
and put result in xmm1.
EVEX.LLIG.66.0F38.W0 B9 /r
B
V/V
AVX512F
Multiply scalar single precision floating-point
VFMADD231SS xmm1 {k1}{z}, xmm2,
OR AVX10.1
value from xmm2 and xmm3/m32, add to xmm1
xmm3/m32{er}
and put 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.
EVEX encoded version: The low doubleword element of the destination is updated according to the writemask.
VFMADD132SS/VFMADD213SS/VFMADD231SS-Fused Multiply-Add of Scalar Single Precision Floating-Point Values
Vol. 2C
5-232
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-233
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-49, “Type E3 Class Exception Conditions.”
VFMADD132SS/VFMADD213SS/VFMADD231SS-Fused Multiply-Add of Scalar Single Precision Floating-Point Values
Vol. 2C
5-234
VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD-Fused Multiply-Alternating
Add/Subtract of Packed Double Precision Floating-Point Values
Opcode/
Op /
64/32
CPUID Feature
Description
Instruction
En
Bit Mode
Flag
Support
VEX.128.66.0F38.W1 96 /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMADDSUB132PD xmm1, xmm2,
values from xmm1 and xmm3/mem,
xmm3/m128
add/subtract elements in xmm2 and put result
in xmm1.
VEX.128.66.0F38.W1 A6 /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMADDSUB213PD xmm1, xmm2,
values from xmm1 and xmm2, add/subtract
xmm3/m128
elements in xmm3/mem and put result in xmm1.
VEX.128.66.0F38.W1 B6 /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMADDSUB231PD xmm1, xmm2,
values from xmm2 and xmm3/mem,
xmm3/m128
add/subtract elements in xmm1 and put result
in xmm1.
VEX.256.66.0F38.W1 96 /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMADDSUB132PD ymm1, ymm2,
values from ymm1 and ymm3/mem,
ymm3/m256
add/subtract elements in ymm2 and put result
in ymm1.
VEX.256.66.0F38.W1 A6 /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMADDSUB213PD ymm1, ymm2,
values from ymm1 and ymm2, add/subtract
ymm3/m256
elements in ymm3/mem and put result in ymm1.
VEX.256.66.0F38.W1 B6 /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMADDSUB231PD ymm1, ymm2,
values from ymm2 and ymm3/mem,
ymm3/m256
add/subtract elements in ymm1 and put result
in ymm1.
EVEX.128.66.0F38.W1 A6 /r
B
V/V
(AVX512VL AND
Multiply packed double precision floating-point
VFMADDSUB213PD xmm1 {k1}{z},
AVX512F) OR
values from xmm1 and xmm2, add/subtract
xmm2, xmm3/m128/m64bcst
AVX10.1
elements in xmm3/m128/m64bcst and put
result in xmm1 subject to writemask k1.
EVEX.128.66.0F38.W1 B6 /r
B
V/V
(AVX512VL AND
Multiply packed double precision floating-point
VFMADDSUB231PD xmm1 {k1}{z},
AVX512F) OR
values from xmm2 and xmm3/m128/m64bcst,
xmm2, xmm3/m128/m64bcst
AVX10.1
add/subtract elements in xmm1 and put result
in xmm1 subject to writemask k1.
EVEX.128.66.0F38.W1 96 /r
B
V/V
(AVX512VL AND
Multiply packed double precision floating-point
VFMADDSUB132PD xmm1 {k1}{z},
AVX512F) OR
values from xmm1 and xmm3/m128/m64bcst,
xmm2, xmm3/m128/m64bcst
AVX10.1
add/subtract elements in xmm2 and put result
in xmm1 subject to writemask k1.
EVEX.256.66.0F38.W1 A6 /r
B
V/V
(AVX512VL AND
Multiply packed double precision floating-point
VFMADDSUB213PD ymm1 {k1}{z},
AVX512F) OR
values from ymm1 and ymm2, add/subtract
ymm2, ymm3/m256/m64bcst
AVX10.1
elements in ymm3/m256/m64bcst and put
result in ymm1 subject to writemask k1.
EVEX.256.66.0F38.W1 B6 /r
B
V/V
(AVX512VL AND
Multiply packed double precision floating-point
VFMADDSUB231PD ymm1 {k1}{z},
AVX512F) OR
values from ymm2 and ymm3/m256/m64bcst,
ymm2, ymm3/m256/m64bcst
AVX10.1
add/subtract elements in ymm1 and put result
in ymm1 subject to writemask k1.
EVEX.256.66.0F38.W1 96 /r
B
V/V
(AVX512VL AND
Multiply packed double precision floating-point
VFMADDSUB132PD ymm1 {k1}{z},
AVX512F) OR
values from ymm1 and ymm3/m256/m64bcst,
ymm2, ymm3/m256/m64bcst
AVX10.1
add/subtract 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-235
Opcode/
Op /
64/32
CPUID Feature
Description
Instruction
En
Bit Mode
Flag
Support
EVEX.512.66.0F38.W1 A6 /r
B
V/V
AVX512F
Multiply packed double precision floating-point
VFMADDSUB213PD zmm1 {k1}{z},
OR AVX10.1
values from zmm1and zmm2, add/subtract
zmm2, zmm3/m512/m64bcst{er}
elements in 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
VFMADDSUB231PD zmm1 {k1}{z},
OR AVX10.1
values from zmm2 and zmm3/m512/m64bcst,
zmm2, zmm3/m512/m64bcst{er}
add/subtract 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
VFMADDSUB132PD zmm1 {k1}{z},
OR AVX10.1
values from zmm1 and zmm3/m512/m64bcst,
zmm2, zmm3/m512/m64bcst{er}
add/subtract 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
Vol. 2C
5-236
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/VFMADDSUB213PD/VFMADDSUB231PD-Fused Multiply-Alternating Add/Subtract of Packed Double Precision
Vol. 2C
5-237
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);
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;
VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD-Fused Multiply-Alternating Add/Subtract of Packed Double Precision
Vol. 2C
5-238
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 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
VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD-Fused Multiply-Alternating Add/Subtract of Packed Double Precision
Vol. 2C
5-239
DEST[i+63:i] :=
RoundFPControl_MXCSR(SRC2[i+63:i]*DEST[i+63:i] - SRC3[i+63:i])
FI;
ELSE
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;
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
VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD-Fused Multiply-Alternating Add/Subtract of Packed Double Precision
Vol. 2C
5-240
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*
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 (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;
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
Intel C/C++ Compiler Intrinsic Equivalent
VFMADDSUBxxxPD __m512d _mm512_fmaddsub_pd(__m512d a, __m512d b, __m512d c);
VFMADDSUBxxxPD __m512d _mm512_fmaddsub_round_pd(__m512d a, __m512d b, __m512d c, int r);
VFMADDSUBxxxPD __m512d _mm512_mask_fmaddsub_pd(__m512d a, __mmask8 k, __m512d b, __m512d c);
VFMADDSUBxxxPD __m512d _mm512_maskz_fmaddsub_pd(__mmask8 k, __m512d a, __m512d b, __m512d c);
VFMADDSUBxxxPD __m512d _mm512_mask3_fmaddsub_pd(__m512d a, __m512d b, __m512d c, __mmask8 k);
VFMADDSUBxxxPD __m512d _mm512_mask_fmaddsub_round_pd(__m512d a, __mmask8 k, __m512d b, __m512d c, int r);
VFMADDSUBxxxPD __m512d _mm512_maskz_fmaddsub_round_pd(__mmask8 k, __m512d a, __m512d b, __m512d c, int r);
VFMADDSUBxxxPD __m512d _mm512_mask3_fmaddsub_round_pd(__m512d a, __m512d b, __m512d c, __mmask8 k, int r);
VFMADDSUBxxxPD __m256d _mm256_mask_fmaddsub_pd(__m256d a, __mmask8 k, __m256d b, __m256d c);
VFMADDSUBxxxPD __m256d _mm256_maskz_fmaddsub_pd(__mmask8 k, __m256d a, __m256d b, __m256d c);
VFMADDSUBxxxPD __m256d _mm256_mask3_fmaddsub_pd(__m256d a, __m256d b, __m256d c, __mmask8 k);
VFMADDSUBxxxPD __m128d _mm_mask_fmaddsub_pd(__m128d a, __mmask8 k, __m128d b, __m128d c);
VFMADDSUBxxxPD __m128d _mm_maskz_fmaddsub_pd(__mmask8 k, __m128d a, __m128d b, __m128d c);
VFMADDSUBxxxPD __m128d _mm_mask3_fmaddsub_pd(__m128d a, __m128d b, __m128d c, __mmask8 k);
VFMADDSUBxxxPD __m128d _mm_fmaddsub_pd (__m128d a, __m128d b, __m128d c);
VFMADDSUBxxxPD __m256d _mm256_fmaddsub_pd (__m256d a, __m256d b, __m256d c);
VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD-Fused Multiply-Alternating Add/Subtract of Packed Double Precision
Vol. 2C
5-241
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-48, “Type E2 Class Exception Conditions.”
VFMADDSUB132PD/VFMADDSUB213PD/VFMADDSUB231PD-Fused Multiply-Alternating Add/Subtract of Packed Double Precision
Vol. 2C
5-242
VFMADDSUB132PH/VFMADDSUB213PH/VFMADDSUB231PH-Fused Multiply-Alternating
Add/Subtract of Packed FP16 Values
Opcode/
Op/
64/32
CPUID Feature
Description
Instruction
En
Bit Mode
Flag
Support
EVEX.128.66.MAP6.W0 96 /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from xmm1 and
VFMADDSUB132PH xmm1{k1}{z},
AND AVX512VL)
xmm3/m128/m16bcst, add/subtract elements in
xmm2, xmm3/m128/m16bcst
OR AVX10.1
xmm2, and store the result in xmm1 subject to
writemask k1.
EVEX.256.66.MAP6.W0 96 /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from ymm1 and
VFMADDSUB132PH ymm1{k1}{z},
AND AVX512VL)
ymm3/m256/m16bcst, add/subtract elements in
ymm2, ymm3/m256/m16bcst
OR AVX10.1
ymm2, and store the result in ymm1 subject to
writemask k1.
EVEX.512.66.MAP6.W0 96 /r
A
V/V
AVX512_FP16
Multiply packed FP16 values from zmm1 and
VFMADDSUB132PH zmm1{k1}{z},
OR AVX10.1
zmm3/m512/m16bcst, add/subtract elements in
zmm2, zmm3/m512/m16bcst {er}
zmm2, and store the result in zmm1 subject to
writemask k1.
EVEX.128.66.MAP6.W0 A6 /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from xmm1 and
VFMADDSUB213PH xmm1{k1}{z},
AND AVX512VL)
xmm2, add/subtract elements in
xmm2, xmm3/m128/m16bcst
OR AVX10.1
xmm3/m128/m16bcst, and store the result in
xmm1 subject to writemask k1.
EVEX.256.66.MAP6.W0 A6 /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from ymm1 and
VFMADDSUB213PH ymm1{k1}{z},
AND AVX512VL)
ymm2, add/subtract elements in
ymm2, ymm3/m256/m16bcst
OR AVX10.1
ymm3/m256/m16bcst, and store the result in
ymm1 subject to writemask k1.
EVEX.512.66.MAP6.W0 A6 /r
A
V/V
AVX512_FP16
Multiply packed FP16 values from zmm1 and
VFMADDSUB213PH zmm1{k1}{z},
OR AVX10.1
zmm2, add/subtract elements in
zmm2, zmm3/m512/m16bcst {er}
zmm3/m512/m16bcst, and store the result in
zmm1 subject to writemask k1.
EVEX.128.66.MAP6.W0 B6 /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from xmm2 and
VFMADDSUB231PH xmm1{k1}{z},
AND AVX512VL)
xmm3/m128/m16bcst, add/subtract elements in
xmm2, xmm3/m128/m16bcst
OR AVX10.1
xmm1, and store the result in xmm1 subject to
writemask k1.
EVEX.256.66.MAP6.W0 B6 /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from ymm2 and
VFMADDSUB231PH ymm1{k1}{z},
AND AVX512VL)
ymm3/m256/m16bcst, add/subtract elements in
ymm2, ymm3/m256/m16bcst
OR AVX10.1
ymm1, and store the result in ymm1 subject to
writemask k1.
EVEX.512.66.MAP6.W0 B6 /r
A
V/V
AVX512_FP16
Multiply packed FP16 values from zmm2 and
VFMADDSUB231PH zmm1{k1}{z},
OR AVX10.1
zmm3/m512/m16bcst, add/subtract elements in
zmm2, zmm3/m512/m16bcst {er}
zmm1, and store the result in zmm1 subject to
writemask k1.
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
VFMADDSUB132PH/VFMADDSUB213PH/VFMADDSUB231PH-Fused Multiply-Alternating Add/Subtract of Packed FP16 Values
Vol. 2C
5-243
Description
This instruction performs a packed multiply-add (odd elements) or multiply-subtract (even elements) 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 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-10.
The destination elements are updated according to the writemask.
Table 5-7. VFMADDSUB[132,213,231]PH Notation for Odd and Even Elements
Notation
Odd Elements
Even Elements
132
dest = dest*src3+src2
dest = dest*src3-src2
231
dest = src2*src3+dest
dest = src2*src3-dest
213
dest = src2*dest+src3
dest = src2*dest-src3
Operation
VFMADDSUB132PH 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 *j is even*:
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
VFMADDSUB132PH 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 *j is even*:
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
VFMADDSUB132PH/VFMADDSUB213PH/VFMADDSUB231PH-Fused Multiply-Alternating Add/Subtract of Packed FP16 Values
Vol. 2C
5-244
// else dest.fp16[j] remains unchanged
DEST[MAXVL-1:VL] := 0
VFMADDSUB213PH 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 *j is even*:
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
VFMADDSUB213PH 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 *j is even*:
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
VFMADDSUB132PH/VFMADDSUB213PH/VFMADDSUB231PH-Fused Multiply-Alternating Add/Subtract of Packed FP16 Values
Vol. 2C
5-245
VFMADDSUB231PH 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 *j is even:
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
VFMADDSUB231PH 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 *j is even*:
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
VFMADDSUB132PH/VFMADDSUB213PH/VFMADDSUB231PH-Fused Multiply-Alternating Add/Subtract of Packed FP16 Values
Vol. 2C
5-246
Intel C/C++ Compiler Intrinsic Equivalent
VFMADDSUB132PH, VFMADDSUB213PH, and VFMADDSUB231PH:
__m128h _mm_fmaddsub_ph (__m128h a, __m128h b, __m128h c);
__m128h _mm_mask_fmaddsub_ph (__m128h a, __mmask8 k, __m128h b, __m128h c);
__m128h _mm_mask3_fmaddsub_ph (__m128h a, __m128h b, __m128h c, __mmask8 k);
__m128h _mm_maskz_fmaddsub_ph (__mmask8 k, __m128h a, __m128h b, __m128h c);
__m256h _mm256_fmaddsub_ph (__m256h a, __m256h b, __m256h c);
__m256h _mm256_mask_fmaddsub_ph (__m256h a, __mmask16 k, __m256h b, __m256h c);
__m256h _mm256_mask3_fmaddsub_ph (__m256h a, __m256h b, __m256h c, __mmask16 k);
__m256h _mm256_maskz_fmaddsub_ph (__mmask16 k, __m256h a, __m256h b, __m256h c);
__m512h _mm512_fmaddsub_ph (__m512h a, __m512h b, __m512h c);
__m512h _mm512_mask_fmaddsub_ph (__m512h a, __mmask32 k, __m512h b, __m512h c);
__m512h _mm512_mask3_fmaddsub_ph (__m512h a, __m512h b, __m512h c, __mmask32 k);
__m512h _mm512_maskz_fmaddsub_ph (__mmask32 k, __m512h a, __m512h b, __m512h c);
__m512h _mm512_fmaddsub_round_ph (__m512h a, __m512h b, __m512h c, const int rounding);
__m512h _mm512_mask_fmaddsub_round_ph (__m512h a, __mmask32 k, __m512h b, __m512h c, const int rounding);
__m512h _mm512_mask3_fmaddsub_round_ph (__m512h a, __m512h b, __m512h c, __mmask32 k, const int rounding);
__m512h _mm512_maskz_fmaddsub_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-48, “Type E2 Class Exception Conditions.”
VFMADDSUB132PH/VFMADDSUB213PH/VFMADDSUB231PH-Fused Multiply-Alternating Add/Subtract of Packed FP16 Values
Vol. 2C
5-247
VFMADDSUB132PS/VFMADDSUB213PS/VFMADDSUB231PS-Fused Multiply-Alternating
Add/Subtract of Packed Single Precision Floating-Point Values
Opcode/
Op /
64/32
CPUID Feature
Description
Instruction
En
Bit Mode
Flag
Support
VEX.128.66.0F38.W0 96 /r
A
V/V
FMA
Multiply packed single precision floating-point
VFMADDSUB132PS xmm1, xmm2,
values from xmm1 and xmm3/mem, add/subtract
xmm3/m128
elements in xmm2 and put result in xmm1.
VEX.128.66.0F38.W0 A6 /r
A
V/V
FMA
Multiply packed single precision floating-point
VFMADDSUB213PS xmm1, xmm2,
values from xmm1 and xmm2, add/subtract
xmm3/m128
elements in xmm3/mem and put result in xmm1.
VEX.128.66.0F38.W0 B6 /r
A
V/V
FMA
Multiply packed single precision floating-point
VFMADDSUB231PS xmm1, xmm2,
values from xmm2 and xmm3/mem, add/subtract
xmm3/m128
elements in xmm1 and put result in xmm1.
VEX.256.66.0F38.W0 96 /r
A
V/V
FMA
Multiply packed single precision floating-point
VFMADDSUB132PS ymm1, ymm2,
values from ymm1 and ymm3/mem, add/subtract
ymm3/m256
elements in ymm2 and put result in ymm1.
VEX.256.66.0F38.W0 A6 /r
A
V/V
FMA
Multiply packed single precision floating-point
VFMADDSUB213PS ymm1, ymm2,
values from ymm1 and ymm2, add/subtract
ymm3/m256
elements in ymm3/mem and put result in ymm1.
VEX.256.66.0F38.W0 B6 /r
A
V/V
FMA
Multiply packed single precision floating-point
VFMADDSUB231PS ymm1, ymm2,
values from ymm2 and ymm3/mem, add/subtract
ymm3/m256
elements in ymm1 and put result in ymm1.
EVEX.128.66.0F38.W0 A6 /r
B
V/V
(AVX512VL AND
Multiply packed single precision floating-point
VFMADDSUB213PS xmm1 {k1}{z},
AVX512F) OR
values from xmm1 and xmm2, add/subtract
xmm2, xmm3/m128/m32bcst
AVX10.1
elements in xmm3/m128/m32bcst and put result in
xmm1 subject to writemask k1.
EVEX.128.66.0F38.W0 B6 /r
B
V/V
(AVX512VL AND
Multiply packed single precision floating-point
VFMADDSUB231PS xmm1 {k1}{z},
AVX512F) OR
values from xmm2 and xmm3/m128/m32bcst,
xmm2, xmm3/m128/m32bcst
AVX10.1
add/subtract elements in xmm1 and put result in
xmm1 subject to writemask k1.
EVEX.128.66.0F38.W0 96 /r
B
V/V
(AVX512VL AND
Multiply packed single precision floating-point
VFMADDSUB132PS xmm1 {k1}{z},
AVX512F) OR
values from xmm1 and xmm3/m128/m32bcst,
xmm2, xmm3/m128/m32bcst
AVX10.1
add/subtract elements in zmm2 and put result in
xmm1 subject to writemask k1.
EVEX.256.66.0F38.W0 A6 /r
B
V/V
(AVX512VL AND
Multiply packed single precision floating-point
VFMADDSUB213PS ymm1 {k1}{z},
AVX512F) OR
values from ymm1 and ymm2, add/subtract
ymm2, ymm3/m256/m32bcst
AVX10.1
elements in ymm3/m256/m32bcst and put result in
ymm1 subject to writemask k1.
EVEX.256.66.0F38.W0 B6 /r
B
V/V
(AVX512VL AND
Multiply packed single precision floating-point
VFMADDSUB231PS ymm1 {k1}{z},
AVX512F) OR
values from ymm2 and ymm3/m256/m32bcst,
ymm2, ymm3/m256/m32bcst
AVX10.1
add/subtract elements in ymm1 and put result in
ymm1 subject to writemask k1.
EVEX.256.66.0F38.W0 96 /r
B
V/V
(AVX512VL AND
Multiply packed single precision floating-point
VFMADDSUB132PS ymm1 {k1}{z},
AVX512F) OR
values from ymm1 and ymm3/m256/m32bcst,
ymm2, ymm3/m256/m32bcst
AVX10.1
add/subtract elements in ymm2 and put result in
ymm1 subject to writemask k1.
VFMADDSUB132PS/VFMADDSUB213PS/VFMADDSUB231PS-Fused Multiply-Alternating Add/Subtract of Packed Single Precision
Vol. 2C
5-248
Opcode/
Op /
64/32
CPUID Feature
Description
Instruction
En
Bit Mode
Flag
Support
EVEX.512.66.0F38.W0 A6 /r
B
V/V
AVX512F
Multiply packed single precision floating-point
VFMADDSUB213PS zmm1 {k1}{z},
OR AVX10.1
values from zmm1 and zmm2, add/subtract
zmm2, zmm3/m512/m32bcst{er}
elements in zmm3/m512/m32bcst and put result in
zmm1 subject to writemask k1.
EVEX.512.66.0F38.W0 B6 /r
B
V/V
AVX512F
Multiply packed single precision floating-point
VFMADDSUB231PS zmm1 {k1}{z},
OR AVX10.1
values from zmm2 and zmm3/m512/m32bcst,
zmm2, zmm3/m512/m32bcst{er}
add/subtract elements in zmm1 and put result in
zmm1 subject to writemask k1.
EVEX.512.66.0F38.W0 96 /r
B
V/V
AVX512F
Multiply packed single precision floating-point
VFMADDSUB132PS zmm1 {k1}{z},
OR AVX10.1
values from zmm1 and zmm3/m512/m32bcst,
zmm2, zmm3/m512/m32bcst{er}
add/subtract 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
VFMADDSUB132PS: Multiplies the four, eight or sixteen packed single precision floating-point values from the first
source operand to the corresponding packed single precision floating-point values in the third source operand.
From the infinite precision intermediate result, adds the odd single precision floating-point elements and subtracts
the even single precision floating-point values in the second source operand, performs rounding and stores the
resulting packed single precision floating-point values to the destination operand (first source operand).
VFMADDSUB213PS: Multiplies the four, eight or sixteen packed single precision floating-point values from the
second source operand to the corresponding packed single precision floating-point values in the first source
operand. From the infinite precision intermediate result, adds the odd single precision floating-point elements and
subtracts the even single precision floating-point values in the third source operand, performs rounding and stores
the resulting packed single precision floating-point values to the destination operand (first source operand).
VFMADDSUB231PS: Multiplies the four, eight or sixteen packed single precision floating-point values from the
second source operand to the corresponding packed single precision floating-point values in the third source
operand. From the infinite precision intermediate result, adds the odd single precision floating-point elements and
subtracts the even single precision floating-point values in the first source operand, performs rounding and stores
the resulting packed single 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 32-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.
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.
VFMADDSUB132PS/VFMADDSUB213PS/VFMADDSUB231PS-Fused Multiply-Alternating Add/Subtract of Packed Single Precision
Vol. 2C
5-249
Operation
In the operations below, “*” and “+” symbols represent multiplication and addition with infinite precision inputs and outputs (no
rounding).
VFMADDSUB132PS DEST, SRC2, SRC3
IF (VEX.128) THEN
MAXNUM :=2
ELSEIF (VEX.256)
MAXNUM := 4
FI
For i = 0 to MAXNUM -1{
n := 64*i;
DEST[n+31:n] := RoundFPControl_MXCSR(DEST[n+31:n]*SRC3[n+31:n] - SRC2[n+31:n])
DEST[n+63:n+32] := RoundFPControl_MXCSR(DEST[n+63:n+32]*SRC3[n+63:n+32] + SRC2[n+63:n+32])
}
IF (VEX.128) THEN
DEST[MAXVL-1:128] := 0
ELSEIF (VEX.256)
DEST[MAXVL-1:256] := 0
FI
VFMADDSUB213PS DEST, SRC2, SRC3
IF (VEX.128) THEN
MAXNUM := 2
ELSEIF (VEX.256)
MAXNUM := 4
FI
For i = 0 to MAXNUM -1{
n := 64*i;
DEST[n+31:n] := RoundFPControl_MXCSR(SRC2[n+31:n]*DEST[n+31:n] - SRC3[n+31:n])
DEST[n+63:n+32] := RoundFPControl_MXCSR(SRC2[n+63:n+32]*DEST[n+63:n+32] + SRC3[n+63:n+32])
}
IF (VEX.128) THEN
DEST[MAXVL-1:128] := 0
ELSEIF (VEX.256)
DEST[MAXVL-1:256] := 0
FI
VFMADDSUB231PS DEST, SRC2, SRC3
IF (VEX.128) THEN
MAXNUM := 2
ELSEIF (VEX.256)
MAXNUM := 4
FI
For i = 0 to MAXNUM -1{
n := 64*i;
DEST[n+31:n] := RoundFPControl_MXCSR(SRC2[n+31:n]*SRC3[n+31:n] - DEST[n+31:n])
DEST[n+63:n+32] :=RoundFPControl_MXCSR(SRC2[n+63:n+32]*SRC3[n+63:n+32] + DEST[n+63:n+32])
}
IF (VEX.128) THEN
DEST[MAXVL-1:128] := 0
ELSEIF (VEX.256)
DEST[MAXVL-1:256] := 0
FI
VFMADDSUB132PS/VFMADDSUB213PS/VFMADDSUB231PS-Fused Multiply-Alternating Add/Subtract of Packed Single Precision
Vol. 2C
5-250
VFMADDSUB132PS 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
IF j *is even*
THEN DEST[i+31:i] :=
RoundFPControl(DEST[i+31:i]*SRC3[i+31:i] - SRC2[i+31:i])
ELSE DEST[i+31:i] :=
RoundFPControl(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
VFMADDSUB132PS 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 j *is even*
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 (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])
VFMADDSUB132PS/VFMADDSUB213PS/VFMADDSUB231PS-Fused Multiply-Alternating Add/Subtract of Packed Single Precision
Vol. 2C
5-251
FI;
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
VFMADDSUB213PS 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
IF j *is even*
THEN DEST[i+31:i] :=
RoundFPControl(SRC2[i+31:i]*DEST[i+31:i] - SRC3[i+31:i])
ELSE DEST[i+31:i] :=
RoundFPControl(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
VFMADDSUB213PS 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 j *is even*
THEN
IF (EVEX.b = 1)
THEN
DEST[i+31:i] :=
RoundFPControl_MXCSR(SRC2[i+31:i]*DEST[i+31:i] - SRC3[31:0])
VFMADDSUB132PS/VFMADDSUB213PS/VFMADDSUB231PS-Fused Multiply-Alternating Add/Subtract of Packed Single Precision
Vol. 2C
5-252
ELSE
DEST[i+31:i] :=
RoundFPControl_MXCSR(SRC2[i+31:i]*DEST[i+31:i] - SRC3[i+31:i])
FI;
ELSE
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;
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
VFMADDSUB231PS 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
IF j *is even*
THEN DEST[i+31:i] :=
RoundFPControl(SRC2[i+31:i]*SRC3[i+31:i] - DEST[i+31:i])
ELSE DEST[i+31:i] :=
RoundFPControl(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
VFMADDSUB231PS DEST, SRC2, SRC3 (EVEX encoded version, when src3 operand is a memory source)
(KL, VL) = (4, 128), (8, 256), (16, 512)
VFMADDSUB132PS/VFMADDSUB213PS/VFMADDSUB231PS-Fused Multiply-Alternating Add/Subtract of Packed Single Precision
Vol. 2C
5-253
FOR j := 0 TO KL-1
i := j * 32
IF k1[j] OR *no writemask*
THEN
IF j *is even*
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 (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;
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
VFMADDSUBxxxPS __m512 _mm512_fmaddsub_ps(__m512 a, __m512 b, __m512 c);
VFMADDSUBxxxPS __m512 _mm512_fmaddsub_round_ps(__m512 a, __m512 b, __m512 c, int r);
VFMADDSUBxxxPS __m512 _mm512_mask_fmaddsub_ps(__m512 a, __mmask16 k, __m512 b, __m512 c);
VFMADDSUBxxxPS __m512 _mm512_maskz_fmaddsub_ps(__mmask16 k, __m512 a, __m512 b, __m512 c);
VFMADDSUBxxxPS __m512 _mm512_mask3_fmaddsub_ps(__m512 a, __m512 b, __m512 c, __mmask16 k);
VFMADDSUBxxxPS __m512 _mm512_mask_fmaddsub_round_ps(__m512 a, __mmask16 k, __m512 b, __m512 c, int r);
VFMADDSUBxxxPS __m512 _mm512_maskz_fmaddsub_round_ps(__mmask16 k, __m512 a, __m512 b, __m512 c, int r);
VFMADDSUBxxxPS __m512 _mm512_mask3_fmaddsub_round_ps(__m512 a, __m512 b, __m512 c, __mmask16 k, int r);
VFMADDSUBxxxPS __m256 _mm256_mask_fmaddsub_ps(__m256 a, __mmask8 k, __m256 b, __m256 c);
VFMADDSUBxxxPS __m256 _mm256_maskz_fmaddsub_ps(__mmask8 k, __m256 a, __m256 b, __m256 c);
VFMADDSUBxxxPS __m256 _mm256_mask3_fmaddsub_ps(__m256 a, __m256 b, __m256 c, __mmask8 k);
VFMADDSUBxxxPS __m128 _mm_mask_fmaddsub_ps(__m128 a, __mmask8 k, __m128 b, __m128 c);
VFMADDSUBxxxPS __m128 _mm_maskz_fmaddsub_ps(__mmask8 k, __m128 a, __m128 b, __m128 c);
VFMADDSUBxxxPS __m128 _mm_mask3_fmaddsub_ps(__m128 a, __m128 b, __m128 c, __mmask8 k);
VFMADDSUBxxxPS __m128 _mm_fmaddsub_ps (__m128 a, __m128 b, __m128 c);
VFMADDSUBxxxPS __m256 _mm256_fmaddsub_ps (__m256 a, __m256 b, __m256 c);
VFMADDSUB132PS/VFMADDSUB213PS/VFMADDSUB231PS-Fused Multiply-Alternating Add/Subtract of Packed Single Precision
Vol. 2C
5-254
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-48, “Type E2 Class Exception Conditions.”
VFMADDSUB132PS/VFMADDSUB213PS/VFMADDSUB231PS-Fused Multiply-Alternating Add/Subtract of Packed Single Precision
Vol. 2C
5-255
VFMSUB132PD/VFMSUB213PD/VFMSUB231PD-Fused Multiply-Subtract of Packed Double
Precision Floating-Point Values
Opcode/
Op/
64/32
CPUID Feature
Description
Instruction
En
bit Mode
Flag
Support
VEX.128.66.0F38.W1 9A /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMSUB132PD xmm1, xmm2,
values from xmm1 and xmm3/mem, subtract xmm2
xmm3/m128
and put result in xmm1.
VEX.128.66.0F38.W1 AA /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMSUB213PD xmm1, xmm2,
values from xmm1 and xmm2, subtract xmm3/mem
xmm3/m128
and put result in xmm1.
VEX.128.66.0F38.W1 BA /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMSUB231PD xmm1, xmm2,
values from xmm2 and xmm3/mem, subtract xmm1
xmm3/m128
and put result in xmm1.
VEX.256.66.0F38.W1 9A /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMSUB132PD ymm1, ymm2,
values from ymm1 and ymm3/mem, subtract ymm2
ymm3/m256
and put result in ymm1.
VEX.256.66.0F38.W1 AA /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMSUB213PD ymm1, ymm2,
values from ymm1 and ymm2, subtract ymm3/mem
ymm3/m256
and put result in ymm1.
VEX.256.66.0F38.W1 BA /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMSUB231PD ymm1, ymm2,
values from ymm2 and ymm3/mem, subtract ymm1
ymm3/m256
and put result in ymm1.S
EVEX.128.66.0F38.W1 9A /r
B
V/V
(AVX512VL AND
Multiply packed double precision floating-point
VFMSUB132PD xmm1 {k1}{z},
AVX512F) OR
values from xmm1 and xmm3/m128/m64bcst,
xmm2, xmm3/m128/m64bcst
AVX10.1
subtract xmm2 and put result in xmm1 subject to
writemask k1.
EVEX.128.66.0F38.W1 AA /r
B
V/V
(AVX512VL AND
Multiply packed double precision floating-point
VFMSUB213PD xmm1 {k1}{z},
AVX512F) OR
values from xmm1 and xmm2, subtract
xmm2, xmm3/m128/m64bcst
AVX10.1
xmm3/m128/m64bcst and put result in xmm1
subject to writemask k1.
EVEX.128.66.0F38.W1 BA /r
B
V/V
(AVX512VL AND
Multiply packed double precision floating-point
VFMSUB231PD xmm1 {k1}{z},
AVX512F) OR
values from xmm2 and xmm3/m128/m64bcst,
xmm2, xmm3/m128/m64bcst
AVX10.1
subtract xmm1 and put result in xmm1 subject to
writemask k1.
EVEX.256.66.0F38.W1 9A /r
B
V/V
(AVX512VL AND
Multiply packed double precision floating-point
VFMSUB132PD ymm1 {k1}{z},
AVX512F) OR
values from ymm1 and ymm3/m256/m64bcst,
ymm2, ymm3/m256/m64bcst
AVX10.1
subtract ymm2 and put result in ymm1 subject to
writemask k1.
EVEX.256.66.0F38.W1 AA /r
B
V/V
(AVX512VL AND
Multiply packed double precision floating-point
VFMSUB213PD ymm1 {k1}{z},
AVX512F) OR
values from ymm1 and ymm2, subtract
ymm2, ymm3/m256/m64bcst
AVX10.1
ymm3/m256/m64bcst and put result in ymm1
subject to writemask k1.
EVEX.256.66.0F38.W1 BA /r
B
V/V
(AVX512VL AND
Multiply packed double precision floating-point
VFMSUB231PD ymm1 {k1}{z},
AVX512F) OR
values from ymm2 and ymm3/m256/m64bcst,
ymm2, ymm3/m256/m64bcst
AVX10.1
subtract ymm1 and put result in ymm1 subject to
writemask k1.
VFMSUB132PD/VFMSUB213PD/VFMSUB231PD-Fused Multiply-Subtract of Packed Double Precision Floating-Point Values
Vol. 2C
5-256
Opcode/
Op/
64/32
CPUID Feature
Description
Instruction
En
bit Mode
Flag
Support
EVEX.512.66.0F38.W1 9A /r
B
V/V
AVX512F
Multiply packed double precision floating-point
VFMSUB132PD zmm1 {k1}{z},
OR AVX10.1
values from zmm1 and zmm3/m512/m64bcst,
zmm2, zmm3/m512/m64bcst{er}
subtract zmm2 and put result in zmm1 subject to
writemask k1.
EVEX.512.66.0F38.W1 AA /r
B
V/V
AVX512F
Multiply packed double precision floating-point
VFMSUB213PD zmm1 {k1}{z},
OR AVX10.1
values from zmm1 and zmm2, subtract
zmm2, zmm3/m512/m64bcst{er}
zmm3/m512/m64bcst and put result in zmm1
subject to writemask k1.
EVEX.512.66.0F38.W1 BA /r
B
V/V
AVX512F
Multiply packed double precision floating-point
VFMSUB231PD zmm1 {k1}{z},
OR AVX10.1
values from zmm2 and zmm3/m512/m64bcst,
zmm2, zmm3/m512/m64bcst{er}
subtract zmm1 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
Performs a set of SIMD multiply-subtract computation on packed double precision floating-point values using three
source operands and writes the multiply-subtract 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.
VFMSUB132PD: 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. From
the infinite precision intermediate result, subtracts 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).
VFMSUB213PD: 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.
From the infinite precision intermediate result, subtracts 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).
VFMSUB231PD: 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. From the
infinite precision intermediate result, subtracts 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) 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.
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.
VFMSUB132PD/VFMSUB213PD/VFMSUB231PD-Fused Multiply-Subtract of Packed Double Precision Floating-Point Values
Vol. 2C
5-257
Operation
In the operations below, “*” and “-” symbols represent multiplication and subtraction with infinite precision inputs and outputs (no
rounding).
VFMSUB132PD DEST, SRC2, SRC3 (VEX Encoded Versions)
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
VFMSUB213PD DEST, SRC2, SRC3 (VEX Encoded Versions)
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
VFMSUB231PD DEST, SRC2, SRC3 (VEX Encoded Versions)
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
VFMSUB132PD DEST, SRC2, SRC3 (EVEX Encoded Versions, When SRC3 Operand is a Register)
(KL, VL) = (2, 128), (4, 256), (8, 512)
VFMSUB132PD/VFMSUB213PD/VFMSUB231PD-Fused Multiply-Subtract of Packed Double Precision Floating-Point Values
Vol. 2C
5-258
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
VFMSUB132PD DEST, SRC2, SRC3 (EVEX Encoded Versions, 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
VFMSUB132PD/VFMSUB213PD/VFMSUB231PD-Fused Multiply-Subtract of Packed Double Precision Floating-Point Values
Vol. 2C
5-259
VFMSUB213PD DEST, SRC2, SRC3 (EVEX Encoded Versions, 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]*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
VFMSUB213PD DEST, SRC2, SRC3 (EVEX Encoded Versions, 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])
+31:i])
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
VFMSUB132PD/VFMSUB213PD/VFMSUB231PD-Fused Multiply-Subtract of Packed Double Precision Floating-Point Values
Vol. 2C
5-260
VFMSUB231PD DEST, SRC2, SRC3 (EVEX Encoded Versions, 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
VFMSUB231PD DEST, SRC2, SRC3 (EVEX Encoded Versions, 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
VFMSUB132PD/VFMSUB213PD/VFMSUB231PD-Fused Multiply-Subtract of Packed Double Precision Floating-Point Values
Vol. 2C
5-261
Intel C/C++ Compiler Intrinsic Equivalent
VFMSUBxxxPD __m512d _mm512_fmsub_pd(__m512d a, __m512d b, __m512d c);
VFMSUBxxxPD __m512d _mm512_fmsub_round_pd(__m512d a, __m512d b, __m512d c, int r);
VFMSUBxxxPD __m512d _mm512_mask_fmsub_pd(__m512d a, __mmask8 k, __m512d b, __m512d c);
VFMSUBxxxPD __m512d _mm512_maskz_fmsub_pd(__mmask8 k, __m512d a, __m512d b, __m512d c);
VFMSUBxxxPD __m512d _mm512_mask3_fmsub_pd(__m512d a, __m512d b, __m512d c, __mmask8 k);
VFMSUBxxxPD __m512d _mm512_mask_fmsub_round_pd(__m512d a, __mmask8 k, __m512d b, __m512d c, int r);
VFMSUBxxxPD __m512d _mm512_maskz_fmsub_round_pd(__mmask8 k, __m512d a, __m512d b, __m512d c, int r);
VFMSUBxxxPD __m512d _mm512_mask3_fmsub_round_pd(__m512d a, __m512d b, __m512d c, __mmask8 k, int r);
VFMSUBxxxPD __m256d _mm256_mask_fmsub_pd(__m256d a, __mmask8 k, __m256d b, __m256d c);
VFMSUBxxxPD __m256d _mm256_maskz_fmsub_pd(__mmask8 k, __m256d a, __m256d b, __m256d c);
VFMSUBxxxPD __m256d _mm256_mask3_fmsub_pd(__m256d a, __m256d b, __m256d c, __mmask8 k);
VFMSUBxxxPD __m128d _mm_mask_fmsub_pd(__m128d a, __mmask8 k, __m128d b, __m128d c);
VFMSUBxxxPD __m128d _mm_maskz_fmsub_pd(__mmask8 k, __m128d a, __m128d b, __m128d c);
VFMSUBxxxPD __m128d _mm_mask3_fmsub_pd(__m128d a, __m128d b, __m128d c, __mmask8 k);
VFMSUBxxxPD __m128d _mm_fmsub_pd (__m128d a, __m128d b, __m128d c);
VFMSUBxxxPD __m256d _mm256_fmsub_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-48, “Type E2 Class Exception Conditions.”
VFMSUB132PD/VFMSUB213PD/VFMSUB231PD-Fused Multiply-Subtract of Packed Double Precision Floating-Point Values
Vol. 2C
5-262
VF[,N]MSUB[132,213,231]PH-Fused Multiply-Subtract of Packed FP16 Values
Opcode/
Op/
64/32
CPUID Feature
Description
Instruction
En
Bit Mode
Flag
Support
EVEX.128.66.MAP6.W0 9A /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from xmm1 and
VFMSUB132PH xmm1{k1}{z}, xmm2,
AND AVX512VL)
xmm3/m128/m16bcst, subtract xmm2, and store
xmm3/m128/m16bcst
OR AVX10.1
the result in xmm1 subject to writemask k1.
EVEX.256.66.MAP6.W0 9A /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from ymm1 and
VFMSUB132PH ymm1{k1}{z}, ymm2,
AND AVX512VL)
ymm3/m256/m16bcst, subtract ymm2, and store
ymm3/m256/m16bcst
OR AVX10.1
the result in ymm1 subject to writemask k1.
EVEX.512.66.MAP6.W0 9A /r
A
V/V
AVX512_FP16
Multiply packed FP16 values from zmm1 and
VFMSUB132PH zmm1{k1}{z}, zmm2,
OR AVX10.1
zmm3/m512/m16bcst, subtract zmm2, and store
zmm3/m512/m16bcst {er}
the result in zmm1 subject to writemask k1.
EVEX.128.66.MAP6.W0 AA /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from xmm1 and
VFMSUB213PH xmm1{k1}{z}, xmm2,
AND AVX512VL)
xmm2, subtract xmm3/m128/m16bcst, and store
xmm3/m128/m16bcst
OR AVX10.1
the result in xmm1 subject to writemask k1.
EVEX.256.66.MAP6.W0 AA /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from ymm1 and
VFMSUB213PH ymm1{k1}{z}, ymm2,
AND AVX512VL)
ymm2, subtract ymm3/m256/m16bcst, and store
ymm3/m256/m16bcst
OR AVX10.1
the result in ymm1 subject to writemask k1.
EVEX.512.66.MAP6.W0 AA /r
A
V/V
AVX512_FP16
Multiply packed FP16 values from zmm1 and
VFMSUB213PH zmm1{k1}{z}, zmm2,
OR AVX10.1
zmm2, subtract zmm3/m512/m16bcst, and store
zmm3/m512/m16bcst {er}
the result in zmm1 subject to writemask k1.
EVEX.128.66.MAP6.W0 BA /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from xmm2 and
VFMSUB231PH xmm1{k1}{z}, xmm2,
AND AVX512VL)
xmm3/m128/m16bcst, subtract xmm1, and store
xmm3/m128/m16bcst
OR AVX10.1
the result in xmm1 subject to writemask k1.
EVEX.256.66.MAP6.W0 BA /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from ymm2 and
VFMSUB231PH ymm1{k1}{z}, ymm2,
AND AVX512VL)
ymm3/m256/m16bcst, subtract ymm1, and store
ymm3/m256/m16bcst
OR AVX10.1
the result in ymm1 subject to writemask k1.
EVEX.512.66.MAP6.W0 BA /r
A
V/V
AVX512_FP16
Multiply packed FP16 values from zmm2 and
VFMSUB231PH zmm1{k1}{z}, zmm2,
OR AVX10.1
zmm3/m512/m16bcst, subtract zmm1, and store
zmm3/m512/m16bcst {er}
the result in zmm1 subject to writemask k1.
EVEX.128.66.MAP6.W0 9E /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from xmm1 and
VFNMSUB132PH xmm1{k1}{z},
AND AVX512VL)
xmm3/m128/m16bcst, and negate the value.
xmm2, xmm3/m128/m16bcst
OR AVX10.1
Subtract xmm2 from this value, and store the
result in xmm1 subject to writemask k1.
EVEX.256.66.MAP6.W0 9E /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from ymm1 and
VFNMSUB132PH ymm1{k1}{z},
AND AVX512VL)
ymm3/m256/m16bcst, and negate the value.
ymm2, ymm3/m256/m16bcst
OR AVX10.1
Subtract ymm2 from this value, and store the
result in ymm1 subject to writemask k1.
EVEX.512.66.MAP6.W0 9E /r
A
V/V
AVX512_FP16
Multiply packed FP16 values from zmm1 and
VFNMSUB132PH zmm1{k1}{z},
OR AVX10.1
zmm3/m512/m16bcst, and negate the value.
zmm2, zmm3/m512/m16bcst {er}
Subtract zmm2 from this value, and store the
result in zmm1 subject to writemask k1.
EVEX.128.66.MAP6.W0 AE /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from xmm1 and
VFNMSUB213PH xmm1{k1}{z},
AND AVX512VL)
xmm2, and negate the value. Subtract
xmm2, xmm3/m128/m16bcst
OR AVX10.1
xmm3/m128/m16bcst from this value, and store
the result in xmm1 subject to writemask k1.
EVEX.256.66.MAP6.W0 AE /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from ymm1 and
VFNMSUB213PH ymm1{k1}{z},
AND AVX512VL)
ymm2, and negate the value. Subtract
ymm2, ymm3/m256/m16bcst
OR AVX10.1
ymm3/m256/m16bcst from this value, and store
the result in ymm1 subject to writemask k1.
VF[,N]MSUB[132,213,231]PH-Fused Multiply-Subtract of Packed FP16 Values
Vol. 2C
5-263
Opcode/
Op/
64/32
CPUID Feature
Description
Instruction
En
Bit Mode
Flag
Support
EVEX.512.66.MAP6.W0 AE /r
A
V/V
AVX512_FP16
Multiply packed FP16 values from zmm1 and
VFNMSUB213PH zmm1{k1}{z},
OR AVX10.1
zmm2, and negate the value. Subtract
zmm2, zmm3/m512/m16bcst {er}
zmm3/m512/m16bcst from this value, and store
the result in zmm1 subject to writemask k1.
EVEX.128.66.MAP6.W0 BE /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from xmm2 and
VFNMSUB231PH xmm1{k1}{z},
AND AVX512VL)
xmm3/m128/m16bcst, and negate the value.
xmm2, xmm3/m128/m16bcst
OR AVX10.1
Subtract xmm1 from this value, and store the
result in xmm1 subject to writemask k1.
EVEX.256.66.MAP6.W0 BE /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from ymm2 and
VFNMSUB231PH ymm1{k1}{z},
AND AVX512VL)
ymm3/m256/m16bcst, and negate the value.
ymm2, ymm3/m256/m16bcst
OR AVX10.1
Subtract ymm1 from this value, and store the
result in ymm1 subject to writemask k1.
EVEX.512.66.MAP6.W0 BE /r
A
V/V
AVX512_FP16
Multiply packed FP16 values from zmm2 and
VFNMSUB231PH zmm1{k1}{z},
OR AVX10.1
zmm3/m512/m16bcst, and negate the value.
zmm2, zmm3/m512/m16bcst {er}
Subtract zmm1 from this value, and store the
result in zmm1 subject to writemask k1.
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-subtract or a negated multiply-subtract 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 subtract the remaining operand from the negated
infinite precision intermediate product. 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-8.
The destination elements are updated according to the writemask.
Table 5-8. VF[,N]MSUB[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]MSUB[132,213,231]PH-Fused Multiply-Subtract of Packed FP16 Values
Vol. 2C
5-264
Operation
VF[,N]MSUB132PH 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]MSUB132PH 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
VF[,N]MSUB[132,213,231]PH-Fused Multiply-Subtract of Packed FP16 Values
Vol. 2C
5-265
VF[,N]MSUB213PH 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]MSUB213PH 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]MSUB[132,213,231]PH-Fused Multiply-Subtract of Packed FP16 Values
Vol. 2C
5-266
VF[,N]MSUB231PH 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]MSUB231PH 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
VF[,N]MSUB[132,213,231]PH-Fused Multiply-Subtract of Packed FP16 Values
Vol. 2C
5-267
Intel C/C++ Compiler Intrinsic Equivalent
VFMSUB132PH, VFMSUB213PH, and VFMSUB231PH:
__m128h _mm_fmsub_ph (__m128h a, __m128h b, __m128h c);
__m128h _mm_mask_fmsub_ph (__m128h a, __mmask8 k, __m128h b, __m128h c);
__m128h _mm_mask3_fmsub_ph (__m128h a, __m128h b, __m128h c, __mmask8 k);
__m128h _mm_maskz_fmsub_ph (__mmask8 k, __m128h a, __m128h b, __m128h c);
__m256h _mm256_fmsub_ph (__m256h a, __m256h b, __m256h c);
__m256h _mm256_mask_fmsub_ph (__m256h a, __mmask16 k, __m256h b, __m256h c);
__m256h _mm256_mask3_fmsub_ph (__m256h a, __m256h b, __m256h c, __mmask16 k);
__m256h _mm256_maskz_fmsub_ph (__mmask16 k, __m256h a, __m256h b, __m256h c);
__m512h _mm512_fmsub_ph (__m512h a, __m512h b, __m512h c);
__m512h _mm512_mask_fmsub_ph (__m512h a, __mmask32 k, __m512h b, __m512h c);
__m512h _mm512_mask3_fmsub_ph (__m512h a, __m512h b, __m512h c, __mmask32 k);
__m512h _mm512_maskz_fmsub_ph (__mmask32 k, __m512h a, __m512h b, __m512h c);
__m512h _mm512_fmsub_round_ph (__m512h a, __m512h b, __m512h c, const int rounding);
__m512h _mm512_mask_fmsub_round_ph (__m512h a, __mmask32 k, __m512h b, __m512h c, const int rounding);
__m512h _mm512_mask3_fmsub_round_ph (__m512h a, __m512h b, __m512h c, __mmask32 k, const int rounding);
__m512h _mm512_maskz_fmsub_round_ph (__mmask32 k, __m512h a, __m512h b, __m512h c, const int rounding);
VFNMSUB132PH, VFNMSUB213PH, and VFNMSUB231PH:
__m128h _mm_fnmsub_ph (__m128h a, __m128h b, __m128h c);
__m128h _mm_mask_fnmsub_ph (__m128h a, __mmask8 k, __m128h b, __m128h c);
__m128h _mm_mask3_fnmsub_ph (__m128h a, __m128h b, __m128h c, __mmask8 k);
__m128h _mm_maskz_fnmsub_ph (__mmask8 k, __m128h a, __m128h b, __m128h c);
__m256h _mm256_fnmsub_ph (__m256h a, __m256h b, __m256h c);
__m256h _mm256_mask_fnmsub_ph (__m256h a, __mmask16 k, __m256h b, __m256h c);
__m256h _mm256_mask3_fnmsub_ph (__m256h a, __m256h b, __m256h c, __mmask16 k);
__m256h _mm256_maskz_fnmsub_ph (__mmask16 k, __m256h a, __m256h b, __m256h c);
__m512h _mm512_fnmsub_ph (__m512h a, __m512h b, __m512h c);
__m512h _mm512_mask_fnmsub_ph (__m512h a, __mmask32 k, __m512h b, __m512h c);
__m512h _mm512_mask3_fnmsub_ph (__m512h a, __m512h b, __m512h c, __mmask32 k);
__m512h _mm512_maskz_fnmsub_ph (__mmask32 k, __m512h a, __m512h b, __m512h c);
__m512h _mm512_fnmsub_round_ph (__m512h a, __m512h b, __m512h c, const int rounding);
__m512h _mm512_mask_fnmsub_round_ph (__m512h a, __mmask32 k, __m512h b, __m512h c, const int rounding);
__m512h _mm512_mask3_fnmsub_round_ph (__m512h a, __m512h b, __m512h c, __mmask32 k, const int rounding);
__m512h _mm512_maskz_fnmsub_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-48, “Type E2 Class Exception Conditions.”
VF[,N]MSUB[132,213,231]PH-Fused Multiply-Subtract of Packed FP16 Values
Vol. 2C
5-268
VFMSUB132PS/VFMSUB213PS/VFMSUB231PS-Fused Multiply-Subtract of Packed Single
Precision Floating-Point Values
Opcode/
Op/
64/32
CPUID Feature
Description
Instruction
En
Bit Mode
Flag
Support
VEX.128.66.0F38.W0 9A /r
A
V/V
FMA
Multiply packed single precision floating-point
VFMSUB132PS xmm1, xmm2,
values from xmm1 and xmm3/mem, subtract
xmm3/m128
xmm2 and put result in xmm1.
VEX.128.66.0F38.W0 AA /r
A
V/V
FMA
Multiply packed single precision floating-point
VFMSUB213PS xmm1, xmm2,
values from xmm1 and xmm2, subtract
xmm3/m128
xmm3/mem and put result in xmm1.
VEX.128.66.0F38.W0 BA /r
A
V/V
FMA
Multiply packed single precision floating-point
VFMSUB231PS xmm1, xmm2,
values from xmm2 and xmm3/mem, subtract
xmm3/m128
xmm1 and put result in xmm1.
VEX.256.66.0F38.W0 9A /r
A
V/V
FMA
Multiply packed single precision floating-point
VFMSUB132PS ymm1, ymm2,
values from ymm1 and ymm3/mem, subtract
ymm3/m256
ymm2 and put result in ymm1.
VEX.256.66.0F38.W0 AA /r
A
V/V
FMA
Multiply packed single precision floating-point
VFMSUB213PS ymm1, ymm2,
values from ymm1 and ymm2, subtract
ymm3/m256
ymm3/mem and put result in ymm1.
VEX.256.66.0F38.0 BA /r
A
V/V
FMA
Multiply packed single precision floating-point
VFMSUB231PS ymm1, ymm2,
values from ymm2 and ymm3/mem, subtract
ymm3/m256
ymm1 and put result in ymm1.
EVEX.128.66.0F38.W0 9A /r
B
V/V
(AVX512VL AND
Multiply packed single precision floating-point
VFMSUB132PS xmm1 {k1}{z},
AVX512F) OR
values from xmm1 and xmm3/m128/m32bcst,
xmm2, xmm3/m128/m32bcst
AVX10.1
subtract xmm2 and put result in xmm1.
EVEX.128.66.0F38.W0 AA /r
B
V/V
(AVX512VL AND
Multiply packed single precision floating-point
VFMSUB213PS xmm1 {k1}{z},
AVX512F) OR
values from xmm1 and xmm2, subtract
xmm2, xmm3/m128/m32bcst
AVX10.1
xmm3/m128/m32bcst and put result in xmm1.
EVEX.128.66.0F38.W0 BA /r
B
V/V
(AVX512VL AND
Multiply packed single precision floating-point
VFMSUB231PS xmm1 {k1}{z},
AVX512F) OR
values from xmm2 and xmm3/m128/m32bcst,
xmm2, xmm3/m128/m32bcst
AVX10.1
subtract xmm1 and put result in xmm1.
EVEX.256.66.0F38.W0 9A /r
B
V/V
(AVX512VL AND
Multiply packed single precision floating-point
VFMSUB132PS ymm1 {k1}{z},
AVX512F) OR
values from ymm1 and ymm3/m256/m32bcst,
ymm2, ymm3/m256/m32bcst
AVX10.1
subtract ymm2 and put result in ymm1.
EVEX.256.66.0F38.W0 AA /r
B
V/V
(AVX512VL AND
Multiply packed single precision floating-point
VFMSUB213PS ymm1 {k1}{z},
AVX512F) OR
values from ymm1 and ymm2, subtract
ymm2, ymm3/m256/m32bcst
AVX10.1
ymm3/m256/m32bcst and put result in ymm1.
EVEX.256.66.0F38.W0 BA /r
B
V/V
(AVX512VL AND
Multiply packed single precision floating-point
VFMSUB231PS ymm1 {k1}{z},
AVX512F) OR
values from ymm2 and ymm3/m256/m32bcst,
ymm2, ymm3/m256/m32bcst
AVX10.1
subtract ymm1 and put result in ymm1.
EVEX.512.66.0F38.W0 9A /r
B
V/V
AVX512F OR
Multiply packed single precision floating-point
VFMSUB132PS zmm1 {k1}{z},
AVX10.1
values from zmm1 and zmm3/m512/m32bcst,
zmm2, zmm3/m512/m32bcst{er}
subtract zmm2 and put result in zmm1.
EVEX.512.66.0F38.W0 AA /r
B
V/V
AVX512F OR
Multiply packed single precision floating-point
VFMSUB213PS zmm1 {k1}{z},
AVX10.1
values from zmm1 and zmm2, subtract
zmm2, zmm3/m512/m32bcst{er}
zmm3/m512/m32bcst and put result in zmm1.
EVEX.512.66.0F38.W0 BA /r
B
V/V
AVX512F OR
Multiply packed single precision floating-point
VFMSUB231PS zmm1 {k1}{z},
AVX10.1
values from zmm2 and zmm3/m512/m32bcst,
zmm2, zmm3/m512/m32bcst{er}
subtract zmm1 and put result in zmm1.
VFMSUB132PS/VFMSUB213PS/VFMSUB231PS-Fused Multiply-Subtract of Packed Single Precision Floating-Point Values
Vol. 2C
5-269
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-subtract computation on packed single precision floating-point values using three
source operands and writes the multiply-subtract 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.
VFMSUB132PS: 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. From the infinite precision intermediate result, subtracts 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).
VFMSUB213PS: 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. From the infinite precision intermediate result, subtracts the four, eight or sixteen packed single precision
floating-point values in the third 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).
VFMSUB231PS: Multiplies the four, eight or sixteen packed single precision floating-point values from the second
source to the four, eight or sixteen packed single precision floating-point values in the third source operand. From
the infinite precision intermediate result, subtracts 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) 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 32-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.
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 subtraction with infinite precision inputs and outputs (no
rounding).
VFMSUB132PS/VFMSUB213PS/VFMSUB231PS-Fused Multiply-Subtract of Packed Single Precision Floating-Point Values
Vol. 2C
5-270
VFMSUB132PS 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 := 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
ELSEIF (VEX.256)
DEST[MAXVL-1:256] := 0
FI
VFMSUB213PS 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 := 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
VFMSUB231PS 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 := 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
VFMSUB132PS/VFMSUB213PS/VFMSUB231PS-Fused Multiply-Subtract of Packed Single Precision Floating-Point Values
Vol. 2C
5-271
VFMSUB132PS 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
FI
FI;
ENDFOR
DEST[MAXVL-1:VL] := 0
VFMSUB132PS 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
VFMSUB132PS/VFMSUB213PS/VFMSUB231PS-Fused Multiply-Subtract of Packed Single Precision Floating-Point Values
Vol. 2C
5-272
VFMSUB213PS 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_MXCSR(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
VFMSUB213PS 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
VFMSUB132PS/VFMSUB213PS/VFMSUB231PS-Fused Multiply-Subtract of Packed Single Precision Floating-Point Values
Vol. 2C
5-273
VFMSUB231PS 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_MXCSR(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
VFMSUB231PS 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]*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
VFMSUB132PS/VFMSUB213PS/VFMSUB231PS-Fused Multiply-Subtract of Packed Single Precision Floating-Point Values
Vol. 2C
5-274
Intel C/C++ Compiler Intrinsic Equivalent
VFMSUBxxxPS __m512 _mm512_fmsub_ps(__m512 a, __m512 b, __m512 c);
VFMSUBxxxPS __m512 _mm512_fmsub_round_ps(__m512 a, __m512 b, __m512 c, int r);
VFMSUBxxxPS __m512 _mm512_mask_fmsub_ps(__m512 a, __mmask16 k, __m512 b, __m512 c);
VFMSUBxxxPS __m512 _mm512_maskz_fmsub_ps(__mmask16 k, __m512 a, __m512 b, __m512 c);
VFMSUBxxxPS __m512 _mm512_mask3_fmsub_ps(__m512 a, __m512 b, __m512 c, __mmask16 k);
VFMSUBxxxPS __m512 _mm512_mask_fmsub_round_ps(__m512 a, __mmask16 k, __m512 b, __m512 c, int r);
VFMSUBxxxPS __m512 _mm512_maskz_fmsub_round_ps(__mmask16 k, __m512 a, __m512 b, __m512 c, int r);
VFMSUBxxxPS __m512 _mm512_mask3_fmsub_round_ps(__m512 a, __m512 b, __m512 c, __mmask16 k, int r);
VFMSUBxxxPS __m256 _mm256_mask_fmsub_ps(__m256 a, __mmask8 k, __m256 b, __m256 c);
VFMSUBxxxPS __m256 _mm256_maskz_fmsub_ps(__mmask8 k, __m256 a, __m256 b, __m256 c);
VFMSUBxxxPS __m256 _mm256_mask3_fmsub_ps(__m256 a, __m256 b, __m256 c, __mmask8 k);
VFMSUBxxxPS __m128 _mm_mask_fmsub_ps(__m128 a, __mmask8 k, __m128 b, __m128 c);
VFMSUBxxxPS __m128 _mm_maskz_fmsub_ps(__mmask8 k, __m128 a, __m128 b, __m128 c);
VFMSUBxxxPS __m128 _mm_mask3_fmsub_ps(__m128 a, __m128 b, __m128 c, __mmask8 k);
VFMSUBxxxPS __m128 _mm_fmsub_ps (__m128 a, __m128 b, __m128 c);
VFMSUBxxxPS __m256 _mm256_fmsub_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-48, “Type E2 Class Exception Conditions.”
VFMSUB132PS/VFMSUB213PS/VFMSUB231PS-Fused Multiply-Subtract of Packed Single Precision Floating-Point Values
Vol. 2C
5-275
VFMSUB132SD/VFMSUB213SD/VFMSUB231SD-Fused Multiply-Subtract of Scalar Double
Precision Floating-Point Values
Opcode/
Op /
64/32
CPUID Feature
Description
Instruction
En
Bit Mode
Flag
Support
VEX.LIG.66.0F38.W1 9B /r
A
V/V
FMA
Multiply scalar double precision floating-point value
VFMSUB132SD xmm1, xmm2,
from xmm1 and xmm3/m64, subtract xmm2 and
xmm3/m64
put result in xmm1.
VEX.LIG.66.0F38.W1 AB /r
A
V/V
FMA
Multiply scalar double precision floating-point value
VFMSUB213SD xmm1, xmm2,
from xmm1 and xmm2, subtract xmm3/m64 and
xmm3/m64
put result in xmm1.
VEX.LIG.66.0F38.W1 BB /r
A
V/V
FMA
Multiply scalar double precision floating-point value
VFMSUB231SD xmm1, xmm2,
from xmm2 and xmm3/m64, subtract xmm1 and
xmm3/m64
put result in xmm1.
EVEX.LLIG.66.0F38.W1 9B /r
B
V/V
AVX512F
Multiply scalar double precision floating-point value
VFMSUB132SD xmm1 {k1}{z},
OR AVX10.1
from xmm1 and xmm3/m64, subtract xmm2 and
xmm2, xmm3/m64{er}
put result in xmm1.
EVEX.LLIG.66.0F38.W1 AB /r
B
V/V
AVX512F
Multiply scalar double precision floating-point value
VFMSUB213SD xmm1 {k1}{z},
OR AVX10.1
from xmm1 and xmm2, subtract xmm3/m64 and
xmm2, xmm3/m64{er}
put result in xmm1.
EVEX.LLIG.66.0F38.W1 BB /r
B
V/V
AVX512F
Multiply scalar double precision floating-point value
VFMSUB231SD xmm1 {k1}{z},
OR AVX10.1
from xmm2 and xmm3/m64, subtract xmm1 and
xmm2, xmm3/m64{er}
put 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-subtract computation on the low packed double precision floating-point values using
three source operands and writes the multiply-subtract result in the destination operand. The destination operand
is also the first source operand. The second operand must be a XMM register. The third source operand can be a
XMM register or a 64-bit memory location.
VFMSUB132SD: Multiplies the low packed double precision floating-point value from the first source operand to the
low packed double precision floating-point value in the third source operand. From the infinite precision interme-
diate result, subtracts the low packed double precision floating-point values in the second source operand,
performs rounding and stores the resulting packed double precision floating-point value to the destination operand
(first source operand).
VFMSUB213SD: Multiplies the low packed double precision floating-point value from the second source operand to
the low packed double precision floating-point value in the first source operand. From the infinite precision inter-
mediate result, subtracts the low packed double precision floating-point value in the third source operand,
performs rounding and stores the resulting packed double precision floating-point value to the destination operand
(first source operand).
VFMSUB231SD: Multiplies the low packed double precision floating-point value from the second source to the low
packed double precision floating-point value in the third source operand. From the infinite precision intermediate
result, subtracts the low packed double precision floating-point value in the first source operand, performs
rounding and stores the resulting packed double precision floating-point value to the destination operand (first
source operand).
VFMSUB132SD/VFMSUB213SD/VFMSUB231SD-Fused Multiply-Subtract of Scalar Double Precision Floating-Point Values
Vol. 2C
5-276
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.
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).
VFMSUB132SD 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
VFMSUB213SD 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
VFMSUB132SD/VFMSUB213SD/VFMSUB231SD-Fused Multiply-Subtract of Scalar Double Precision Floating-Point Values
Vol. 2C
5-277
VFMSUB231SD 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
VFMSUB132SD DEST, SRC2, SRC3 (VEX encoded version)
DEST[63:0] := RoundFPControl_MXCSR(DEST[63:0]*SRC3[63:0] - SRC2[63:0])
DEST[127:64] := DEST[127:64]
DEST[MAXVL-1:128] := 0
VFMSUB213SD DEST, SRC2, SRC3 (VEX encoded version)
DEST[63:0] := RoundFPControl_MXCSR(SRC2[63:0]*DEST[63:0] - SRC3[63:0])
DEST[127:64] := DEST[127:64]
DEST[MAXVL-1:128] := 0
VFMSUB231SD DEST, SRC2, SRC3 (VEX encoded version)
DEST[63:0] := RoundFPControl_MXCSR(SRC2[63:0]*SRC3[63:0] - DEST[63:0])
DEST[127:64] := DEST[127:64]
DEST[MAXVL-1:128] := 0
Intel C/C++ Compiler Intrinsic Equivalent
VFMSUBxxxSD __m128d _mm_fmsub_round_sd(__m128d a, __m128d b, __m128d c, int r);
VFMSUBxxxSD __m128d _mm_mask_fmsub_sd(__m128d a, __mmask8 k, __m128d b, __m128d c);
VFMSUBxxxSD __m128d _mm_maskz_fmsub_sd(__mmask8 k, __m128d a, __m128d b, __m128d c);
VFMSUBxxxSD __m128d _mm_mask3_fmsub_sd(__m128d a, __m128d b, __m128d c, __mmask8 k);
VFMSUBxxxSD __m128d _mm_mask_fmsub_round_sd(__m128d a, __mmask8 k, __m128d b, __m128d c, int r);
VFMSUBxxxSD __m128d _mm_maskz_fmsub_round_sd(__mmask8 k, __m128d a, __m128d b, __m128d c, int r);
VFMSUBxxxSD __m128d _mm_mask3_fmsub_round_sd(__m128d a, __m128d b, __m128d c, __mmask8 k, int r);
VFMSUBxxxSD __m128d _mm_fmsub_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-49, “Type E3 Class Exception Conditions.”
VFMSUB132SD/VFMSUB213SD/VFMSUB231SD-Fused Multiply-Subtract of Scalar Double Precision Floating-Point Values
Vol. 2C
5-278
VF[,N]MSUB[132,213,231]SH-Fused Multiply-Subtract of Scalar FP16 Values
Opcode/
Op/
64/32
CPUID Feature
Description
Instruction
En
Bit Mode
Flag
Support
EVEX.LLIG.66.MAP6.W0 9B /r
A
V/V
AVX512_FP16
Multiply FP16 values from xmm1 and
VFMSUB132SH xmm1{k1}{z}, xmm2,
OR AVX10.1
xmm3/m16, subtract xmm2, and store the result
xmm3/m16 {er}
in xmm1 subject to writemask k1.
EVEX.LLIG.66.MAP6.W0 AB /r
A
V/V
AVX512_FP16
Multiply FP16 values from xmm1 and xmm2,
VFMSUB213SH xmm1{k1}{z}, xmm2,
OR AVX10.1
subtract xmm3/m16, and store the result in
xmm3/m16 {er}
xmm1 subject to writemask k1.
EVEX.LLIG.66.MAP6.W0 BB /r
A
V/V
AVX512_FP16
Multiply FP16 values from xmm2 and
VFMSUB231SH xmm1{k1}{z}, xmm2,
OR AVX10.1
xmm3/m16, subtract xmm1, and store the result
xmm3/m16 {er}
in xmm1 subject to writemask k1.
EVEX.LLIG.66.MAP6.W0 9F /r
A
V/V
AVX512_FP16
Multiply FP16 values from xmm1 and
VFNMSUB132SH xmm1{k1}{z},
OR AVX10.1
xmm3/m16, and negate the value. Subtract
xmm2, xmm3/m16 {er}
xmm2 from this value, and store the result in
xmm1 subject to writemask k1.
EVEX.LLIG.66.MAP6.W0 AF /r
A
V/V
AVX512_FP16
Multiply FP16 values from xmm1 and xmm2, and
VFNMSUB213SH xmm1{k1}{z},
OR AVX10.1
negate the value. Subtract xmm3/m16 from this
xmm2, xmm3/m16 {er}
value, and store the result in xmm1 subject to
writemask k1.
EVEX.LLIG.66.MAP6.W0 BF /r
A
V/V
AVX512_FP16
Multiply FP16 values from xmm2 and
VFNMSUB231SH xmm1{k1}{z},
OR AVX10.1
xmm3/m16, and negate the value. Subtract
xmm2, xmm3/m16 {er}
xmm1 from this value, and store the result in
xmm1 subject to writemask k1.
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
This instruction performs a scalar multiply-subtract or negated multiply-subtract 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 subtract the remaining operand from the
negated infinite precision intermediate product. The notation’ “132”, “213” and “231” indicate the use of the oper-
ands in ±A * B - C, where each digit corresponds to the operand number, with the destination being operand 1;
see Table 5-9.
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-9. VF[,N]MSUB[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]MSUB[132,213,231]SH-Fused Multiply-Subtract of Scalar FP16 Values
Vol. 2C
5-279
Operation
VF[,N]MSUB132SH 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]MSUB213SH 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]MSUB231SH 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
VF[,N]MSUB[132,213,231]SH-Fused Multiply-Subtract of Scalar FP16 Values
Vol. 2C
5-280
Intel C/C++ Compiler Intrinsic Equivalent
VFMSUB132SH, VFMSUB213SH, and VFMSUB231SH:
__m128h _mm_fmsub_round_sh (__m128h a, __m128h b, __m128h c, const int rounding);
__m128h _mm_mask_fmsub_round_sh (__m128h a, __mmask8 k, __m128h b, __m128h c, const int rounding);
__m128h _mm_mask3_fmsub_round_sh (__m128h a, __m128h b, __m128h c, __mmask8 k, const int rounding);
__m128h _mm_maskz_fmsub_round_sh (__mmask8 k, __m128h a, __m128h b, __m128h c, const int rounding);
__m128h _mm_fmsub_sh (__m128h a, __m128h b, __m128h c);
__m128h _mm_mask_fmsub_sh (__m128h a, __mmask8 k, __m128h b, __m128h c);
__m128h _mm_mask3_fmsub_sh (__m128h a, __m128h b, __m128h c, __mmask8 k);
__m128h _mm_maskz_fmsub_sh (__mmask8 k, __m128h a, __m128h b, __m128h c);
VFNMSUB132SH, VFNMSUB213SH, and VFNMSUB231SH:
__m128h _mm_fnmsub_round_sh (__m128h a, __m128h b, __m128h c, const int rounding);
__m128h _mm_mask_fnmsub_round_sh (__m128h a, __mmask8 k, __m128h b, __m128h c, const int rounding);
__m128h _mm_mask3_fnmsub_round_sh (__m128h a, __m128h b, __m128h c, __mmask8 k, const int rounding);
__m128h _mm_maskz_fnmsub_round_sh (__mmask8 k, __m128h a, __m128h b, __m128h c, const int rounding);
__m128h _mm_fnmsub_sh (__m128h a, __m128h b, __m128h c);
__m128h _mm_mask_fnmsub_sh (__m128h a, __mmask8 k, __m128h b, __m128h c);
__m128h _mm_mask3_fnmsub_sh (__m128h a, __m128h b, __m128h c, __mmask8 k);
__m128h _mm_maskz_fnmsub_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-49, “Type E3 Class Exception Conditions.”
VF[,N]MSUB[132,213,231]SH-Fused Multiply-Subtract of Scalar FP16 Values
Vol. 2C
5-281
VFMSUB132SS/VFMSUB213SS/VFMSUB231SS-Fused Multiply-Subtract of Scalar Single
Precision Floating-Point Values
Opcode/
Op /
64/32
CPUID Feature
Description
Instruction
En
Bit Mode
Flag
Support
VEX.LIG.66.0F38.W0 9B /r
A
V/V
FMA
Multiply scalar single precision floating-point value
VFMSUB132SS xmm1, xmm2,
from xmm1 and xmm3/m32, subtract xmm2 and put
xmm3/m32
result in xmm1.
VEX.LIG.66.0F38.W0 AB /r
A
V/V
FMA
Multiply scalar single precision floating-point value
VFMSUB213SS xmm1, xmm2,
from xmm1 and xmm2, subtract xmm3/m32 and put
xmm3/m32
result in xmm1.
VEX.LIG.66.0F38.W0 BB /r
A
V/V
FMA
Multiply scalar single precision floating-point value
VFMSUB231SS xmm1, xmm2,
from xmm2 and xmm3/m32, subtract xmm1 and put
xmm3/m32
result in xmm1.
EVEX.LLIG.66.0F38.W0 9B /r
B
V/V
AVX512F
Multiply scalar single precision floating-point value
VFMSUB132SS xmm1 {k1}{z},
OR AVX10.1
from xmm1 and xmm3/m32, subtract xmm2 and put
xmm2, xmm3/m32{er}
result in xmm1.
EVEX.LLIG.66.0F38.W0 AB /r
B
V/V
AVX512F
Multiply scalar single precision floating-point value
VFMSUB213SS xmm1 {k1}{z},
OR AVX10.1
from xmm1 and xmm2, subtract xmm3/m32 and put
xmm2, xmm3/m32{er}
result in xmm1.
EVEX.LLIG.66.0F38.W0 BB /r
B
V/V
AVX512F
Multiply scalar single precision floating-point value
VFMSUB231SS xmm1 {k1}{z},
OR AVX10.1
from xmm2 and xmm3/m32, subtract xmm1 and put
xmm2, 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-subtract computation on the low packed single precision floating-point values using
three source operands and writes the multiply-subtract result in the destination operand. The destination operand
is also the first source operand. The second operand must be a XMM register. The third source operand can be a
XMM register or a 32-bit memory location.
VFMSUB132SS: Multiplies the low packed single precision floating-point value from the first source operand to the
low packed single precision floating-point value in the third source operand. From the infinite precision interme-
diate result, subtracts the low packed single precision floating-point values in the second source operand, performs
rounding and stores the resulting packed single precision floating-point value to the destination operand (first
source operand).
VFMSUB213SS: Multiplies the low packed single precision floating-point value from the second source operand to
the low packed single precision floating-point value in the first source operand. From the infinite precision interme-
diate result, subtracts the low packed single precision floating-point value in the third source operand, performs
rounding and stores the resulting packed single precision floating-point value to the destination operand (first
source operand).
VFMSUB231SS: Multiplies the low packed single precision floating-point value from the second source to the low
packed single precision floating-point value in the third source operand. From the infinite precision intermediate
result, subtracts the low packed single precision floating-point value in the first source operand, performs rounding
and stores the resulting packed single precision floating-point value to the destination operand (first source
operand).
VFMSUB132SS/VFMSUB213SS/VFMSUB231SS-Fused Multiply-Subtract of Scalar Single Precision Floating-Point Values
Vol. 2C
5-282
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.
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 subtraction with infinite precision inputs and outputs (no
rounding).
VFMSUB132SS 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
VFMSUB213SS 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
VFMSUB132SS/VFMSUB213SS/VFMSUB231SS-Fused Multiply-Subtract of Scalar Single Precision Floating-Point Values
Vol. 2C
5-283
VFMSUB231SS 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[63: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
VFMSUB132SS 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
VFMSUB213SS 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
VFMSUB231SS 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
VFMSUBxxxSS __m128 _mm_fmsub_round_ss(__m128 a, __m128 b, __m128 c, int r);
VFMSUBxxxSS __m128 _mm_mask_fmsub_ss(__m128 a, __mmask8 k, __m128 b, __m128 c);
VFMSUBxxxSS __m128 _mm_maskz_fmsub_ss(__mmask8 k, __m128 a, __m128 b, __m128 c);
VFMSUBxxxSS __m128 _mm_mask3_fmsub_ss(__m128 a, __m128 b, __m128 c, __mmask8 k);
VFMSUBxxxSS __m128 _mm_mask_fmsub_round_ss(__m128 a, __mmask8 k, __m128 b, __m128 c, int r);
VFMSUBxxxSS __m128 _mm_maskz_fmsub_round_ss(__mmask8 k, __m128 a, __m128 b, __m128 c, int r);
VFMSUBxxxSS __m128 _mm_mask3_fmsub_round_ss(__m128 a, __m128 b, __m128 c, __mmask8 k, int r);
VFMSUBxxxSS __m128 _mm_fmsub_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-49, “Type E3 Class Exception Conditions.”
VFMSUB132SS/VFMSUB213SS/VFMSUB231SS-Fused Multiply-Subtract of Scalar Single Precision Floating-Point Values
Vol. 2C
5-284
VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD-Fused Multiply-Alternating
Subtract/Add of Packed Double Precision Floating-Point Values
Opcode/
Op /
64/32
CPUID Feature
Description
Instruction
En
Bit Mode
Flag
Support
VEX.128.66.0F38.W1 97 /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMSUBADD132PD xmm1, xmm2,
values from xmm1 and xmm3/mem,
xmm3/m128
subtract/add elements in xmm2 and put result
in xmm1.
VEX.128.66.0F38.W1 A7 /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMSUBADD213PD xmm1, xmm2,
values from xmm1 and xmm2, subtract/add
xmm3/m128
elements in xmm3/mem and put result in xmm1.
VEX.128.66.0F38.W1 B7 /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMSUBADD231PD xmm1, xmm2,
values from xmm2 and xmm3/mem,
xmm3/m128
subtract/add elements in xmm1 and put result
in xmm1.
VEX.256.66.0F38.W1 97 /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMSUBADD132PD ymm1, ymm2,
values from ymm1 and ymm3/mem,
ymm3/m256
subtract/add elements in ymm2 and put result
in ymm1.
VEX.256.66.0F38.W1 A7 /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMSUBADD213PD ymm1, ymm2,
values from ymm1 and ymm2, subtract/add
ymm3/m256
elements in ymm3/mem and put result in ymm1.
VEX.256.66.0F38.W1 B7 /r
A
V/V
FMA
Multiply packed double precision floating-point
VFMSUBADD231PD ymm1, ymm2,
values from ymm2 and ymm3/mem,
ymm3/m256
subtract/add elements in ymm1 and put result
in ymm1.
EVEX.128.66.0F38.W1 97 /r
B
V/V
(AVX512VL AND
Multiply packed double precision floating-point
VFMSUBADD132PD xmm1 {k1}{z},
AVX512F) OR
values from xmm1 and xmm3/m128/m64bcst,
xmm2, xmm3/m128/m64bcst
AVX10.1
subtract/add elements in xmm2 and put result
in xmm1 subject to writemask k1.
EVEX.128.66.0F38.W1 A7 /r
B
V/V
(AVX512VL AND
Multiply packed double precision floating-point
VFMSUBADD213PD xmm1 {k1}{z},
AVX512F) OR
values from xmm1 and xmm2, subtract/add
xmm2, xmm3/m128/m64bcst
AVX10.1
elements in xmm3/m128/m64bcst and put
result in xmm1 subject to writemask k1.
EVEX.128.66.0F38.W1 B7 /r
B
V/V
(AVX512VL AND
Multiply packed double precision floating-point
VFMSUBADD231PD xmm1 {k1}{z},
AVX512F) OR
values from xmm2 and xmm3/m128/m64bcst,
xmm2, xmm3/m128/m64bcst
AVX10.1
subtract/add elements in xmm1 and put result
in xmm1 subject to writemask k1.
EVEX.256.66.0F38.W1 97 /r
B
V/V
(AVX512VL AND
Multiply packed double precision floating-point
VFMSUBADD132PD ymm1 {k1}{z},
AVX512F) OR
values from ymm1 and ymm3/m256/m64bcst,
ymm2, ymm3/m256/m64bcst
AVX10.1
subtract/add elements in ymm2 and put result
in ymm1 subject to writemask k1.
EVEX.256.66.0F38.W1 A7 /r
B
V/V
(AVX512VL AND
Multiply packed double precision floating-point
VFMSUBADD213PD ymm1 {k1}{z},
AVX512F) OR
values from ymm1 and ymm2, subtract/add
ymm2, ymm3/m256/m64bcst
AVX10.1
elements in ymm3/m256/m64bcst and put
result in ymm1 subject to writemask k1.
EVEX.256.66.0F38.W1 B7 /r
B
V/V
(AVX512VL AND
Multiply packed double precision floating-point
VFMSUBADD231PD ymm1 {k1}{z},
AVX512F) OR
values from ymm2 and ymm3/m256/m64bcst,
ymm2, ymm3/m256/m64bcst
AVX10.1
subtract/add elements in ymm1 and put result
in ymm1 subject to writemask k1.
VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD-Fused Multiply-Alternating Subtract/Add of Packed Double Precision
Vol. 2C
5-285
Opcode/
Op /
64/32
CPUID Feature
Description
Instruction
En
Bit Mode
Flag
Support
EVEX.512.66.0F38.W1 97 /r
B
V/V
AVX512F
Multiply packed double precision floating-point
VFMSUBADD132PD zmm1 {k1}{z},
OR AVX10.1
values from zmm1 and zmm3/m512/m64bcst,
zmm2, zmm3/m512/m64bcst{er}
subtract/add elements in zmm2 and put result in
zmm1 subject to writemask k1.
EVEX.512.66.0F38.W1 A7 /r
B
V/V
AVX512F
Multiply packed double precision floating-point
VFMSUBADD213PD zmm1 {k1}{z},
OR AVX10.1
values from zmm1 and zmm2, subtract/add
zmm2, zmm3/m512/m64bcst{er}
elements in zmm3/m512/m64bcst and put
result in zmm1 subject to writemask k1.
EVEX.512.66.0F38.W1 B7 /r
B
V/V
AVX512F
Multiply packed double precision floating-point
VFMSUBADD231PD zmm1 {k1}{z},
OR AVX10.1
values from zmm2 and zmm3/m512/m64bcst,
zmm2, zmm3/m512/m64bcst{er}
subtract/add elements in zmm1 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
VFMSUBADD132PD: 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, subtracts the odd double precision floating-point elements and adds 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).
VFMSUBADD213PD: 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, subtracts the odd double precision floating-point elements and adds 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).
VFMSUBADD231PD: 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, subtracts the odd double precision floating-point elements and adds 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.
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
VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD-Fused Multiply-Alternating Subtract/Add of Packed Double Precision
Vol. 2C
5-286
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).
VFMSUBADD132PD 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
VFMSUBADD213PD 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
VFMSUBADD231PD 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
VFMSUBADD132PD 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*
VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD-Fused Multiply-Alternating Subtract/Add of Packed Double Precision
Vol. 2C
5-287
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
VFMSUBADD132PD 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*
ELSE
; zeroing-masking
DEST[i+63:i] := 0
FI
FI;
ENDFOR
DEST[MAXVL-1:VL] := 0
VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD-Fused Multiply-Alternating Subtract/Add of Packed Double Precision
Vol. 2C
5-288
VFMSUBADD213PD 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
VFMSUBADD213PD 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)
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])
VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD-Fused Multiply-Alternating Subtract/Add of Packed Double Precision
Vol. 2C
5-289
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
VFMSUBADD231PD 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
VFMSUBADD231PD 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]*SRC3[63:0] + DEST[i+63:i])
ELSE
VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD-Fused Multiply-Alternating Subtract/Add of Packed Double Precision
Vol. 2C
5-290
DEST[i+63:i] :=
RoundFPControl_MXCSR(SRC2[i+63:i]*SRC3[i+63:i] + DEST[i+63:i])
FI;
ELSE
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;
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
Intel C/C++ Compiler Intrinsic Equivalent
VFMSUBADDxxxPD __m512d _mm512_fmsubadd_pd(__m512d a, __m512d b, __m512d c);
VFMSUBADDxxxPD __m512d _mm512_fmsubadd_round_pd(__m512d a, __m512d b, __m512d c, int r);
VFMSUBADDxxxPD __m512d _mm512_mask_fmsubadd_pd(__m512d a, __mmask8 k, __m512d b, __m512d c);
VFMSUBADDxxxPD __m512d _mm512_maskz_fmsubadd_pd(__mmask8 k, __m512d a, __m512d b, __m512d c);
VFMSUBADDxxxPD __m512d _mm512_mask3_fmsubadd_pd(__m512d a, __m512d b, __m512d c, __mmask8 k);
VFMSUBADDxxxPD __m512d _mm512_mask_fmsubadd_round_pd(__m512d a, __mmask8 k, __m512d b, __m512d c, int r);
VFMSUBADDxxxPD __m512d _mm512_maskz_fmsubadd_round_pd(__mmask8 k, __m512d a, __m512d b, __m512d c, int r);
VFMSUBADDxxxPD __m512d _mm512_mask3_fmsubadd_round_pd(__m512d a, __m512d b, __m512d c, __mmask8 k, int r);
VFMSUBADDxxxPD __m256d _mm256_mask_fmsubadd_pd(__m256d a, __mmask8 k, __m256d b, __m256d c);
VFMSUBADDxxxPD __m256d _mm256_maskz_fmsubadd_pd(__mmask8 k, __m256d a, __m256d b, __m256d c);
VFMSUBADDxxxPD __m256d _mm256_mask3_fmsubadd_pd(__m256d a, __m256d b, __m256d c, __mmask8 k);
VFMSUBADDxxxPD __m128d _mm_mask_fmsubadd_pd(__m128d a, __mmask8 k, __m128d b, __m128d c);
VFMSUBADDxxxPD __m128d _mm_maskz_fmsubadd_pd(__mmask8 k, __m128d a, __m128d b, __m128d c);
VFMSUBADDxxxPD __m128d _mm_mask3_fmsubadd_pd(__m128d a, __m128d b, __m128d c, __mmask8 k);
VFMSUBADDxxxPD __m128d _mm_fmsubadd_pd (__m128d a, __m128d b, __m128d c);
VFMSUBADDxxxPD __m256d _mm256_fmsubadd_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-48, “Type E2 Class Exception Conditions.”
VFMSUBADD132PD/VFMSUBADD213PD/VFMSUBADD231PD-Fused Multiply-Alternating Subtract/Add of Packed Double Precision
Vol. 2C
5-291
VFMSUBADD132PH/VFMSUBADD213PH/VFMSUBADD231PH-Fused Multiply-Alternating
Subtract/Add of Packed FP16 Values
Opcode/
Op/
64/32
CPUID Feature
Description
Instruction
En
Bit Mode
Flag
Support
EVEX.128.66.MAP6.W0 97 /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from xmm1 and
VFMSUBADD132PH xmm1{k1}{z},
AND AVX512VL)
xmm3/m128/m16bcst, subtract/add elements in
xmm2, xmm3/m128/m16bcst
OR AVX10.1
xmm2, and store the result in xmm1 subject to
writemask k1.
EVEX.256.66.MAP6.W0 97 /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from ymm1 and
VFMSUBADD132PH ymm1{k1}{z},
AND AVX512VL)
ymm3/m256/m16bcst, subtract/add elements in
ymm2, ymm3/m256/m16bcst
OR AVX10.1
ymm2, and store the result in ymm1 subject to
writemask k1.
EVEX.512.66.MAP6.W0 97 /r
A
V/V
AVX512_FP16
Multiply packed FP16 values from zmm1 and
VFMSUBADD132PH zmm1{k1}{z},
OR AVX10.1
zmm3/m512/m16bcst, subtract/add elements in
zmm2, zmm3/m512/m16bcst {er}
zmm2, and store the result in zmm1 subject to
writemask k1.
EVEX.128.66.MAP6.W0 A7 /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from xmm1 and
VFMSUBADD213PH xmm1{k1}{z},
AND AVX512VL)
xmm2, subtract/add elements in
xmm2, xmm3/m128/m16bcst
OR AVX10.1
xmm3/m128/m16bcst, and store the result in
xmm1 subject to writemask k1.
EVEX.256.66.MAP6.W0 A7 /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from ymm1 and
VFMSUBADD213PH ymm1{k1}{z},
AND AVX512VL)
ymm2, subtract/add elements in
ymm2, ymm3/m256/m16bcst
OR AVX10.1
ymm3/m256/m16bcst, and store the result in
ymm1 subject to writemask k1.
EVEX.512.66.MAP6.W0 A7 /r
A
V/V
AVX512_FP16
Multiply packed FP16 values from zmm1 and
VFMSUBADD213PH zmm1{k1}{z},
OR AVX10.1
zmm2, subtract/add elements in
zmm2, zmm3/m512/m16bcst {er}
zmm3/m512/m16bcst, and store the result in
zmm1 subject to writemask k1.
EVEX.128.66.MAP6.W0 B7 /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from xmm2 and
VFMSUBADD231PH xmm1{k1}{z},
AND AVX512VL)
xmm3/m128/m16bcst, subtract/add elements in
xmm2, xmm3/m128/m16bcst
OR AVX10.1
xmm1, and store the result in xmm1 subject to
writemask k1.
EVEX.256.66.MAP6.W0 B7 /r
A
V/V
(AVX512_FP16
Multiply packed FP16 values from ymm2 and
VFMSUBADD231PH ymm1{k1}{z},
AND AVX512VL)
ymm3/m256/m16bcst, subtract/add elements in
ymm2, ymm3/m256/m16bcst
OR AVX10.1
ymm1, and store the result in ymm1 subject to
writemask k1.
EVEX.512.66.MAP6.W0 B7 /r
A
V/V
AVX512_FP16
Multiply packed FP16 values from zmm2 and
VFMSUBADD231PH zmm1{k1}{z},
OR AVX10.1
zmm3/m512/m16bcst, subtract/add elements in
zmm2, zmm3/m512/m16bcst {er}
zmm1, and store the result in zmm1 subject to
writemask k1.
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
VFMSUBADD132PH/VFMSUBADD213PH/VFMSUBADD231PH-Fused Multiply-Alternating Subtract/Add of Packed FP16 Values
Vol. 2C
5-292
Description
This instruction performs a packed multiply-add (even elements) or multiply-subtract (odd elements) 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 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-10.
The destination elements are updated according to the writemask.
Table 5-10. VFMSUBADD[132,213,231]PH Notation for Odd and Even Elements
Notation
Odd Elements
Even Elements
132
dest = dest*src3-src2
dest = dest*src3+src2
231
dest = src2*src3-dest
dest = src2*src3+dest
213
dest = src2*dest-src3
dest = src2*dest+src3
Operation
VFMSUBADD132PH 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 *j is even*:
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
VFMSUBADD132PH 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 *j is even*:
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
VFMSUBADD132PH/VFMSUBADD213PH/VFMSUBADD231PH-Fused Multiply-Alternating Subtract/Add of Packed FP16 Values
Vol. 2C
5-293
|