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
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;