fmls

Vector Floating-Point Multiply-Subtract

FMLS <Vd>.<T>, <Vn>.<T>, <Vm>.<T>

Multiplies and subtracts from destination (Vd = Vd - Vn * Vm).

Details

Multiplies corresponding floating-point elements from two source vectors and subtracts the product from the destination vector: Vd[i] = Vd[i] − Vn[i] × Vm[i] per element. Floating-point exceptions (invalid operation, overflow, underflow, inexact) may be signaled per IEEE 754 semantics; no integer flags are affected. Available in 32-bit and 64-bit floating-point forms (sz controls element width) on AArch64 with NEON/ASIMD extension.

Pseudocode Operation

for i = 0 to elements_in_vector-1:
  element_size = 32 if sz==0 else 64
  product = Vn[element][element_size-1:0] * Vm[element][element_size-1:0]
  Vd[element][element_size-1:0] = Vd[element][element_size-1:0] - product

Example

FMLS v0.4s.T, v1.4s.T, v2.4s.T

Encoding

Binary Layout
0
Q
0
01110
1
sz
1
Rm
11001
1
Rn
Rd
 
Format SIMD Three Register
Opcode 0x0EA0CC00
Extension NEON (SIMD)

Operands

  • Vd
    Dest/Acc
  • 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;