fmla
SVE Floating-Point Fused Multiply-Add
FMLA <Zda>.<T>, <Pg>/M, <Zn>.<T>, <Zm>.<T>
Calculates (Zda + Zn * Zm) under predicate.
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
FMLA z0.s.T, p0/m/M, z1.s.T, z2.s.T
Encoding
Binary Layout
01100101
31:24
size
23:22
1
21
Zm
20:16
0
15
0
14
0
13
Pg
12:10
Zn
9:5
Zda
4:0
Operands
-
Zda
Dest/Addend -
Pg
Mask -
Zn
First source scalable vector register (SVE) -
Zm
Second source scalable vector register (SVE)
Related
Other forms of fmla
- fmla Vector Floating-Point Multiply-Accumulate
- fmla Floating-Point Multiply Accumulate (Half-Precision)
Across architectures
Fused Multiply-Add : how x86, ARM, RISC-V, and PowerISA each do this.
More in SVE
Reference
View in Arm A64 ISA Reference ↗
Arm A64 ISA
Instruction Forms
| Encoding | Instruction | ISA | Bit pattern | ||
|---|---|---|---|---|---|
| 0x5F001000 | FMLA <Hd>, <Hn>, <Vm>.H[<index>] | A64 | 01 | 0 | 11111 | 00 | L | M | Rm | 0 | 0 | 01 | H | 0 | Rn | Rd | ||
| 0x5F801000 | FMLA <V><d>, <V><n>, <Vm>.<Ts>[<index>] | A64 | 01 | 0 | 111111 | sz | L | M | Rm | 0 | 0 | 01 | H | 0 | Rn | Rd | ||
| 0x0F001000 | FMLA <Vd>.<T>, <Vn>.<T>, <Vm>.H[<index>] | A64 | 0 | Q | 0 | 01111 | 00 | L | M | Rm | 0 | 0 | 01 | H | 0 | Rn | Rd | ||
| 0x0F801000 | FMLA <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>] | A64 | 0 | Q | 0 | 011111 | sz | L | M | Rm | 0 | 0 | 01 | H | 0 | Rn | Rd | ||
| 0x0E400C00 | FMLA <Vd>.<T>, <Vn>.<T>, <Vm>.<T> | A64 | 0 | Q | 0 | 01110 | 0 | 10 | Rm | 00 | 001 | 1 | Rn | Rd | ||
| 0x0E20CC00 | FMLA <Vd>.<T>, <Vn>.<T>, <Vm>.<T> | A64 | 0 | Q | 0 | 01110 | 0 | sz | 1 | Rm | 11001 | 1 | Rn | Rd | ||
| 0x65200000 | FMLA <Zda>.<T>, <Pg>/M, <Zn>.<T>, <Zm>.<T> | A64 | 01100101 | size | 1 | Zm | 0 | 0 | 0 | Pg | Zn | Zda | ||
| 0x64200000 | FMLA <Zda>.H, <Zn>.H, <Zm>.H[<imm>] | A64 | 01100100 | 0 | i3h | 1 | i3l | Zm | 0000 | 0 | 0 | Zn | Zda | ||
| 0x64A00000 | FMLA <Zda>.S, <Zn>.S, <Zm>.S[<imm>] | A64 | 01100100 | 1 | 0 | 1 | i2 | Zm | 0000 | 0 | 0 | Zn | Zda | ||
| 0x64E00000 | FMLA <Zda>.D, <Zn>.D, <Zm>.D[<imm>] | A64 | 01100100 | 1 | 1 | 1 | i1 | Zm | 0000 | 0 | 0 | Zn | Zda | ||
| 0xC1101000 | FMLA ZA.H[<Wv>, <offs>{, VGx2}], { <Zn1>.H-<Zn2>.H }, <Zm>.H[<index>] | A64 | 110000010001 | Zm | 0 | Rv | 1 | i3h | Zn | 0 | 0 | i3l | off3 | ||
| 0xC1500000 | FMLA ZA.S[<Wv>, <offs>{, VGx2}], { <Zn1>.S-<Zn2>.S }, <Zm>.S[<index>] | A64 | 110000010101 | Zm | 0 | Rv | 0 | i2 | Zn | 0 | 0 | 0 | off3 | ||
| 0xC1D00000 | FMLA ZA.D[<Wv>, <offs>{, VGx2}], { <Zn1>.D-<Zn2>.D }, <Zm>.D[<index>] | A64 | 110000011101 | Zm | 0 | Rv | 00 | i1 | Zn | 0 | 0 | 0 | off3 | ||
| 0xC1109000 | FMLA ZA.H[<Wv>, <offs>{, VGx4}], { <Zn1>.H-<Zn4>.H }, <Zm>.H[<index>] | A64 | 110000010001 | Zm | 1 | Rv | 1 | i3h | Zn | 0 | 0 | 0 | i3l | off3 |
Description
Multiply the corresponding active floating-point elements of the first and second source vectors and add to 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;