fmls

SVE Floating-Point Fused Multiply-Subtract

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

FMLS 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
1
13
Pg
12:10
Zn
9:5
Zda
4:0
 
Format SVE FP Ternary
Opcode 0x65202000
Extension SVE

Operands

  • Zda
    Dest/Minuend
  • Pg
    Mask
  • Zn
    First source scalable vector register (SVE)
  • Zm
    Second source scalable vector register (SVE)

Related

Other forms of fmls

  • fmls Vector Floating-Point Multiply-Subtract
  • fmls Floating-Point Multiply Subtract (Half-Precision)

More in SVE

Reference

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;