mla

Vector Multiply-Accumulate

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

Multiplies elements and adds to destination (Vd = Vd + Vn * Vm).

Details

Multiplies corresponding elements of Vn and Vm, then adds the products to the corresponding elements of Vd, storing results back in Vd. Operates on integer elements of size determined by the size field (8, 16, or 32 bits). The Q bit determines operation width (64-bit for Q=0, 128-bit for Q=1). No condition flags are affected. AArch64 NEON extension.

Pseudocode Operation

for i = 0 to (128 >> (if Q then 0 else 1)) - 1 step esize:
  Vd[i +: esize] ← Vd[i +: esize] + (Vn[i +: esize] * Vm[i +: esize]);

Example

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

Encoding

Binary Layout
0
Q
0
01110
size
1
Rm
10010
1
Rn
Rd
 
Format SIMD Three Register
Opcode 0x0E209400
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
0x2F000000 MLA <Vd>.<T>, <Vn>.<T>, <Vm>.<Ts>[<index>] A64 0 | Q | 1 | 01111 | size | L | M | Rm | 0 | 0 | 00 | H | 0 | Rn | Rd
0x0E209400 MLA <Vd>.<T>, <Vn>.<T>, <Vm>.<T> A64 0 | Q | 0 | 01110 | size | 1 | Rm | 10010 | 1 | Rn | Rd
0x04004000 MLA <Zda>.<T>, <Pg>/M, <Zn>.<T>, <Zm>.<T> A64 00000100 | size | 0 | Zm | 01 | 0 | Pg | Zn | Zda
0x44200800 MLA <Zda>.H, <Zn>.H, <Zm>.H[<imm>] A64 01000100 | 0 | i3h | 1 | i3l | Zm | 00001 | 0 | Zn | Zda
0x44A00800 MLA <Zda>.S, <Zn>.S, <Zm>.S[<imm>] A64 01000100 | 1 | 0 | 1 | i2 | Zm | 00001 | 0 | Zn | Zda
0x44E00800 MLA <Zda>.D, <Zn>.D, <Zm>.D[<imm>] A64 01000100 | 1 | 1 | 1 | i1 | Zm | 00001 | 0 | Zn | Zda

Description

Multiply-Add to accumulator (vector). This instruction multiplies corresponding elements in the vectors of the two source SIMD&FP registers, and accumulates the results with the vector elements of the destination SIMD&FP register. 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;
bits(esize) product;

for e = 0 to elements-1
    element1 = Elem[operand1, e, esize];
    element2 = Elem[operand2, e, esize];
    product = (UInt(element1)*UInt(element2))<esize-1:0>;
    if sub_op then
        Elem[result, e, esize] = Elem[operand3, e, esize] - product;
    else
        Elem[result, e, esize] = Elem[operand3, e, esize] + product;

V[d, datasize] = result;