vfmadd132sh

Fused Multiply-Add Scalar Half-Precision (132)

VFMADD132SH xmm1 {k1}, xmm2, xmm3/m16

Scalar FMA (Dest * Src2 + Src1) for FP16.

Details

Performs fused multiply-add on scalar half-precision (FP16) values: multiplies the destination by src2, adds src1, and stores result in destination. The '132' form computes (dest × src2) + src1. Uses EVEX encoding with optional masking and exception suppression. Single rounding applied to the final result per MXCSR[15:13].

Pseudocode Operation

if (k1[0] || !masking_enabled) {
  dest[0:15] ← (dest[0:15] ×FP16 src2[0:15]) +FP16 src1[0:15];
} else {
  dest[0:15] ← preserve_or_zero(dest[0:15]);
}
dest[16:127] ← 0;

Example

VFMADD132SH xmm1, xmm2, xmm3/m16

Encoding

Binary Layout
EVEX
+0
99
+4
 
Format EVEX
Opcode EVEX.LLIG.66.MAP6.W0 99 /r
Extension AVX-512-FP16

Operands

  • dest
    128-bit XMM SIMD register
  • src1
    128-bit XMM SIMD register
  • src2
    128-bit XMM SIMD register or Memory operand

Reference (Intel® SDM)

Instruction Forms

Opcode Instruction Op/En 64/32-bit Mode CPUID Description
EVEX.LLIG.66.MAP6.W0 99 /r VFMADD132SH xmm1{k1}{z}, xmm2, xmm3/m16 {er} A V/V AVX512_FP16 OR AVX10.1 Multiply FP16 values from xmm1 and xmm3/m16, add to xmm2, and store the result in xmm1.
EVEX.LLIG.66.MAP6.W0 A9 /r VFMADD213SH xmm1{k1}{z}, xmm2, xmm3/m16 {er} A V/V AVX512_FP16 OR AVX10.1 Multiply FP16 values from xmm1 and xmm2, add to xmm3/m16, and store the result in xmm1.
EVEX.LLIG.66.MAP6.W0 B9 /r VFMADD231SH xmm1{k1}{z}, xmm2, xmm3/m16 {er} A V/V AVX512_FP16 OR AVX10.1 Multiply FP16 values from xmm2 and xmm3/m16, add to xmm1, and store the result in xmm1.
EVEX.LLIG.66.MAP6.W0 9D /r VFNMADD132SH xmm1{k1}{z}, xmm2, xmm3/m16 {er} A V/V AVX512_FP16 OR AVX10.1 Multiply FP16 values from xmm1 and xmm3/m16, and negate the value. Add this value to xmm2, and store the result in xmm1.
EVEX.LLIG.66.MAP6.W0 AD /r VFNMADD213SH xmm1{k1}{z}, xmm2, xmm3/m16 {er} A V/V AVX512_FP16 OR AVX10.1 Multiply FP16 values from xmm1 and xmm2, and negate the value. Add this value to xmm3/m16, and store the result in xmm1.
EVEX.LLIG.66.MAP6.W0 BD /r VFNMADD231SH xmm1{k1}{z}, xmm2, xmm3/m16 {er} A V/V AVX512_FP16 OR AVX10.1 Multiply FP16 values from xmm2 and xmm3/m16, and negate the value. Add this value to xmm1, and store the result in xmm1.

Instruction Operand Encoding

Op/En Tuple Type 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 corresponding remaining operand. The notation’ “132”, “213” and “231” indicate the use of the operands in ±A * B + C, where each digit corresponds to the operand number, with the destination being operand 1; see Table 5-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);

Exceptions

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