fmls

Floating-Point Multiply Subtract (Half-Precision)

FMLS <Vd>.8H, <Vn>.8H, <Vm>.8H

Fused multiply-subtract on half-precision vectors.

Details

Fused multiply-subtract: for each half-precision element, computes Vd - (Vn × Vm) and writes to Vd. Operates on 8 half-precision (16-bit) values in 128-bit vectors with a single rounding step. Vd is both source and destination (accumulator). No condition flags are set; exception behavior follows FPCR settings. Requires FEAT_FP16 extension; AArch64-only.

Pseudocode Operation

for i = 0 to 7
  Vd[i*16 +: 16] ← FP16_Sub(Vd[i*16 +: 16], FP16_Mul(Vn[i*16 +: 16], Vm[i*16 +: 16]))

Example

FMLS v0.4s.8H, v1.4s.8H, v2.4s.8H

Encoding

Binary Layout
0
Q
0
01110
1
10
Rm
00
001
1
Rn
Rd
 
Format NEON FP16
Opcode 0x0EC00C00
Extension FEAT_FP16 (NEON)

Operands

  • Vd
    Destination SIMD/FP vector register
  • Vn
    First source SIMD/FP vector register
  • Vm
    Second source SIMD/FP vector register

Reference (Arm A64 ISA)

Instruction Forms

Encoding Instruction ISA Bit pattern
0x5F005000 FMLS <Hd>, <Hn>, <Vm>.H[<index>] A64 01 | 0 | 11111 | 00 | L | M | Rm | 0 | 1 | 01 | H | 0 | Rn | Rd
0x5F805000 FMLS <V><d>, <V><n>, <Vm>.<Ts>[<index>] A64 01 | 0 | 111111 | sz | L | M | Rm | 0 | 1 | 01 | H | 0 | Rn | Rd
0x0F005000 FMLS <Vd>.<T>, <Vn>.<T>, <Vm>.H[<index>] A64 0 | Q | 0 | 01111 | 00 | L | M | Rm | 0 | 1 | 01 | H | 0 | Rn | Rd
0x0F805000 FMLS <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>] A64 0 | Q | 0 | 011111 | sz | L | M | Rm | 0 | 1 | 01 | H | 0 | Rn | Rd
0x0EC00C00 FMLS <Vd>.<T>, <Vn>.<T>, <Vm>.<T> A64 0 | Q | 0 | 01110 | 1 | 10 | Rm | 00 | 001 | 1 | Rn | Rd
0x0EA0CC00 FMLS <Vd>.<T>, <Vn>.<T>, <Vm>.<T> A64 0 | Q | 0 | 01110 | 1 | sz | 1 | Rm | 11001 | 1 | Rn | Rd
0x65202000 FMLS <Zda>.<T>, <Pg>/M, <Zn>.<T>, <Zm>.<T> A64 01100101 | size | 1 | Zm | 0 | 0 | 1 | Pg | Zn | Zda
0x64200400 FMLS <Zda>.H, <Zn>.H, <Zm>.H[<imm>] A64 01100100 | 0 | i3h | 1 | i3l | Zm | 0000 | 0 | 1 | Zn | Zda
0x64A00400 FMLS <Zda>.S, <Zn>.S, <Zm>.S[<imm>] A64 01100100 | 1 | 0 | 1 | i2 | Zm | 0000 | 0 | 1 | Zn | Zda
0x64E00400 FMLS <Zda>.D, <Zn>.D, <Zm>.D[<imm>] A64 01100100 | 1 | 1 | 1 | i1 | Zm | 0000 | 0 | 1 | Zn | Zda
0xC1101010 FMLS ZA.H[<Wv>, <offs>{, VGx2}], { <Zn1>.H-<Zn2>.H }, <Zm>.H[<index>] A64 110000010001 | Zm | 0 | Rv | 1 | i3h | Zn | 0 | 1 | i3l | off3
0xC1500010 FMLS ZA.S[<Wv>, <offs>{, VGx2}], { <Zn1>.S-<Zn2>.S }, <Zm>.S[<index>] A64 110000010101 | Zm | 0 | Rv | 0 | i2 | Zn | 0 | 1 | 0 | off3
0xC1D00010 FMLS ZA.D[<Wv>, <offs>{, VGx2}], { <Zn1>.D-<Zn2>.D }, <Zm>.D[<index>] A64 110000011101 | Zm | 0 | Rv | 00 | i1 | Zn | 0 | 1 | 0 | off3
0xC1109010 FMLS ZA.H[<Wv>, <offs>{, VGx4}], { <Zn1>.H-<Zn4>.H }, <Zm>.H[<index>] A64 110000010001 | Zm | 1 | Rv | 1 | i3h | Zn | 0 | 0 | 1 | i3l | off3

Description

Floating-point fused Multiply-Subtract from accumulator (vector). This instruction multiplies corresponding floating-point values in the vectors in the two source SIMD&FP registers, negates the product, adds the result to the corresponding vector element of the destination SIMD&FP register, and writes the result to the destination SIMD&FP register. A floating-point exception can be generated by this instruction. Depending on the settings in FPCR, the exception results in either a flag being set in FPSR, or a synchronous exception being generated. For more information, see Floating-point exception traps. Depending on the settings in the CPACR_EL1, CPTR_EL2, and CPTR_EL3 registers, and the current Security state and Exception level, an attempt to execute the instruction might be trapped.

Operation

CheckFPAdvSIMDEnabled64();
bits(datasize) operand1 = V[n, datasize];
bits(datasize) operand2 = V[m, datasize];
bits(datasize) operand3 = V[d, datasize];
bits(datasize) result;
bits(esize) element1;
bits(esize) element2;

for e = 0 to elements-1
    element1 = Elem[operand1, e, esize];
    element2 = Elem[operand2, e, esize];
    if sub_op then element1 = FPNeg(element1, FPCR);
    Elem[result, e, esize] = FPMulAdd(Elem[operand3, e, esize], element1, element2, FPCR);

V[d, datasize] = result;