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