fmls
SVE Floating-Point Fused Multiply-Subtract
FMLS <Zda>.<T>, <Pg>/M, <Zn>.<T>, <Zm>.<T>
Calculates (Zda - Zn * Zm) under predicate.
Details
SVE floating-point fused multiply-subtract instruction that computes Zda - (Zn × Zm) for each element under predicate control, with a single rounding step at the end. Inactive elements (where the predicate is false) are left unchanged in the destination. This instruction performs true fused operation with only one rounding error, unlike separate multiply and subtract instructions. NZCV flags are not affected.
Pseudocode Operation
for i = 0 to VL/element_size-1:
if Pg[i] then
Zda[i] ← Zda[i] - (Zn[i] × Zm[i])
else
Zda[i] ← Zda[i]
Example
FMLS z0.s.T, p0/m/M, z1.s.T, z2.s.T
Encoding
Binary Layout
01100101
size
1
Zm
0
0
1
Pg
Zn
Zda
Operands
-
Zda
Dest/Minuend -
Pg
Mask -
Zn
First source scalable vector register (SVE) -
Zm
Second source scalable vector register (SVE)
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
Multiply the corresponding active floating-point elements of the first and second source vectors and subtract from elements of the third source (addend) vector without intermediate rounding. Destructively place the results in the destination and third source (addend) vector. Inactive elements in the destination vector register remain unmodified.
Operation
CheckSVEEnabled();
constant integer VL = CurrentVL;
constant integer PL = VL DIV 8;
constant integer elements = VL DIV esize;
bits(PL) mask = P[g, PL];
bits(VL) operand1 = if AnyActiveElement(mask, esize) then Z[n, VL] else Zeros(VL);
bits(VL) operand2 = if AnyActiveElement(mask, esize) then Z[m, VL] else Zeros(VL);
bits(VL) operand3 = Z[da, VL];
bits(VL) result;
for e = 0 to elements-1
if ActivePredicateElement(mask, e, esize) then
bits(esize) element1 = Elem[operand1, e, esize];
bits(esize) element2 = Elem[operand2, e, esize];
bits(esize) element3 = Elem[operand3, e, esize];
if op1_neg then element1 = FPNeg(element1, FPCR);
if op3_neg then element3 = FPNeg(element3, FPCR);
Elem[result, e, esize] = FPMulAdd(element3, element1, element2, FPCR);
else
Elem[result, e, esize] = Elem[operand3, e, esize];
Z[da, VL] = result;