# VFMSUB132PH/VFNMSUB132PH/VFMSUB213PH/VFNMSUB213PH/VFMSUB231PH/VFNMSUB231PH — Fused Multiply-Subtract of Packed FP16 Values

Instruction En Bit Mode Flag Support Instruction En Bit Mode Flag Support 64/32 CPUID Feature Instruction En Bit Mode Flag CPUID Feature Instruction En Bit Mode Flag Op/ 64/32 CPUID Feature Instruction En Bit Mode Flag 64/32 CPUID Feature Instruction En Bit Mode Flag CPUID Feature Instruction En Bit Mode Flag Op/ 64/32 CPUID Feature |  | Support |  | Description
--- | --- | --- | --- | ---
EVEX.128.66.MAP6.W0 9A /r VFMSUB132PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst | A | V/V | AVX512-FP16 AVX512VL | Multiply packed FP16 values from xmm1 and xmm3/m128/m16bcst, subtract xmm2, and store the result in xmm1 subject to writemask k1.
EVEX.256.66.MAP6.W0 9A /r VFMSUB132PH ymm1{k1}{z}, ymm2, ymm3/m256/m16bcst | A | V/V | AVX512-FP16 AVX512VL | Multiply packed FP16 values from ymm1 and ymm3/m256/m16bcst, subtract ymm2, and store the result in ymm1 subject to writemask k1.
EVEX.512.66.MAP6.W0 9A /r VFMSUB132PH zmm1{k1}{z}, zmm2, zmm3/m512/m16bcst {er} | A | V/V | AVX512-FP16 | Multiply packed FP16 values from zmm1 and zmm3/m512/m16bcst, subtract zmm2, and store the result in zmm1 subject to writemask k1.
EVEX.128.66.MAP6.W0 AA /r VFMSUB213PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst | A | V/V | AVX512-FP16 AVX512VL | Multiply packed FP16 values from xmm1 and xmm2, subtract xmm3/m128/m16bcst, and store the result in xmm1 subject to writemask k1.
EVEX.256.66.MAP6.W0 AA /r VFMSUB213PH ymm1{k1}{z}, ymm2, ymm3/m256/m16bcst | A | V/V | AVX512-FP16 AVX512VL | Multiply packed FP16 values from ymm1 and ymm2, subtract ymm3/m256/m16bcst, and store the result in ymm1 subject to writemask k1.
EVEX.512.66.MAP6.W0 AA /r VFMSUB213PH zmm1{k1}{z}, zmm2, zmm3/m512/m16bcst {er} | A | V/V | AVX512-FP16 | Multiply packed FP16 values from zmm1 and zmm2, subtract zmm3/m512/m16bcst, and store the result in zmm1 subject to writemask k1.
EVEX.128.66.MAP6.W0 BA /r VFMSUB231PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst | A | V/V | AVX512-FP16 AVX512VL | Multiply packed FP16 values from xmm2 and xmm3/m128/m16bcst, subtract xmm1, and store the result in xmm1 subject to writemask k1.
EVEX.256.66.MAP6.W0 BA /r VFMSUB231PH ymm1{k1}{z}, ymm2, ymm3/m256/m16bcst | A | V/V | AVX512-FP16 AVX512VL | Multiply packed FP16 values from ymm2 and ymm3/m256/m16bcst, subtract ymm1, and store the result in ymm1 subject to writemask k1.
EVEX.512.66.MAP6.W0 BA /r VFMSUB231PH zmm1{k1}{z}, zmm2, zmm3/m512/m16bcst {er} | A | V/V | AVX512-FP16 | Multiply packed FP16 values from zmm2 and zmm3/m512/m16bcst, subtract zmm1, and store the result in zmm1 subject to writemask k1.
EVEX.128.66.MAP6.W0 9E /r VFNMSUB132PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst | A | V/V | AVX512-FP16 AVX512VL | Multiply packed FP16 values from xmm1 and xmm3/m128/m16bcst, and negate the value. Subtract xmm2 from this value, and store the result in xmm1 subject to writemask k1.
EVEX.256.66.MAP6.W0 9E /r VFNMSUB132PH ymm1{k1}{z}, ymm2, ymm3/m256/m16bcst | A | V/V | AVX512-FP16 AVX512VL | Multiply packed FP16 values from ymm1 and ymm3/m256/m16bcst, and negate the value. Subtract ymm2 from this value, and store the result in ymm1 subject to writemask k1.
EVEX.512.66.MAP6.W0 9E /r VFNMSUB132PH zmm1{k1}{z}, zmm2, zmm3/m512/m16bcst {er} | A | V/V | AVX512-FP16 | Multiply packed FP16 values from zmm1 and zmm3/m512/m16bcst, and negate the value. Subtract zmm2 from this value, and store the result in zmm1 subject to writemask k1.
EVEX.128.66.MAP6.W0 AE /r VFNMSUB213PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst | A | V/V | AVX512-FP16 AVX512VL | Multiply packed FP16 values from xmm1 and xmm2, and negate the value. Subtract xmm3/m128/m16bcst from this value, and store the result in xmm1 subject to writemask k1.
EVEX.256.66.MAP6.W0 AE /r VFNMSUB213PH ymm1{k1}{z}, ymm2, ymm3/m256/m16bcst | A | V/V | AVX512-FP16 AVX512VL | Multiply packed FP16 values from ymm1 and ymm2, and negate the value. Subtract ymm3/m256/m16bcst from this value, and store the result in ymm1 subject to writemask k1.
EVEX.512.66.MAP6.W0 AE /r VFNMSUB213PH zmm1{k1}{z}, zmm2, zmm3/m512/m16bcst {er} | A | V/V | AVX512-FP16 | Multiply packed FP16 values from zmm1 and zmm2, and negate the value. Subtract zmm3/m512/m16bcst from this value, and store the result in zmm1 subject to writemask k1.
EVEX.128.66.MAP6.W0 BE /r VFNMSUB231PH xmm1{k1}{z}, xmm2, xmm3/m128/m16bcst | A | V/V | AVX512-FP16 AVX512VL | Multiply packed FP16 values from xmm2 and xmm3/m128/m16bcst, and negate the value. Subtract xmm1 from this value, and store the result in xmm1 subject to writemask k1.
EVEX.256.66.MAP6.W0 BE /r VFNMSUB231PH ymm1{k1}{z}, ymm2, ymm3/m256/m16bcst | A | V/V | AVX512-FP16 AVX512VL | Multiply packed FP16 values from ymm2 and ymm3/m256/m16bcst, and negate the value. Subtract ymm1 from this value, and store the result in ymm1 subject to writemask k1.
EVEX.512.66.MAP6.W0 BE /r VFNMSUB231PH zmm1{k1}{z}, zmm2, zmm3/m512/m16bcst {er} | A | V/V | AVX512-FP16 | Multiply packed FP16 values from zmm2 and zmm3/m512/m16bcst, and negate the value. 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-6.

The destination elements are updated according to the writemask.

Notation | Operands
--- | ---
132 | dest = ± dest*src3-src2
231 | dest = ± src2*src3-dest
213 | dest = ± src2*dest-src3

Table 5-6. VF[,N]MSUB[132,213,231]PH Notation for Operands

### 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]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]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

### 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-46, “Type E2 Class Exception Conditions.”