vmla

Vector Multiply Accumulate (VFP)

VMLA<c>.F32 <Sd>, <Sn>, <Sm>

Sd = Sd + (Sn * Sm).

Details

Vector Multiply Accumulate (VFP) computes Sn × Sm and adds the result to Sd, storing the final value back in Sd. The operation follows IEEE 754 semantics with rounding and exception handling controlled by FPSCR, updating floating-point exception flags but not ARM condition flags. Available in A32/T32 with VFP extension; execution is conditional based on the condition code suffix.

Pseudocode Operation

product ← FP_Multiply(Sn, Sm)
Sd ← FP_Add(Sd, product)
FPSCR ← updated with floating-point exception flags

Example

VMLA.F32 s0, s1, s2

Encoding

Binary Layout
cond
1110
0
D
00
Vn
Vd
10
10
N
0
M
0
Vm
 
Format VFP Arith
Opcode 0x0E000A00
Extension VFP (Float)

Operands

  • Sd
    Dest/Acc
  • Sn
    First source 32-bit floating-point register
  • Sm
    Second source 32-bit floating-point register

Reference (Arm AArch32 ISA)

Instruction Forms

Encoding Instruction ISA Bit pattern
0xF2000D10 VMLA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> A32 1111001 | 0 | 0 | D | 0 | sz | Vn | Vd | 1101 | N | 0 | M | 1 | Vm
0xF2000D50 VMLA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> A32 1111001 | 0 | 0 | D | 0 | sz | Vn | Vd | 1101 | N | 1 | M | 1 | Vm
0x0E000900 VMLA{<c>}{<q>}.F16 <Sd>, <Sn>, <Sm> A32 cond | 1110 | 0 | D | 00 | Vn | Vd | 10 | 01 | N | 0 | M | 0 | Vm
0x0E000A00 VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> A32 cond | 1110 | 0 | D | 00 | Vn | Vd | 10 | 10 | N | 0 | M | 0 | Vm
0x0E000B00 VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> A32 cond | 1110 | 0 | D | 00 | Vn | Vd | 10 | 11 | N | 0 | M | 0 | Vm
0xEF000D10 VMLA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> T32 111 | 0 | 11110 | D | 0 | sz | Vn | Vd | 1101 | N | 0 | M | 1 | Vm
0xEF000D50 VMLA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> T32 111 | 0 | 11110 | D | 0 | sz | Vn | Vd | 1101 | N | 1 | M | 1 | Vm
0xEE000900 VMLA{<c>}{<q>}.F16 <Sd>, <Sn>, <Sm> T32 11101110 | 0 | D | 00 | Vn | Vd | 10 | 01 | N | 0 | M | 0 | Vm
0xEE000A00 VMLA{<c>}{<q>}.F32 <Sd>, <Sn>, <Sm> T32 11101110 | 0 | D | 00 | Vn | Vd | 10 | 10 | N | 0 | M | 0 | Vm
0xEE000B00 VMLA{<c>}{<q>}.F64 <Dd>, <Dn>, <Dm> T32 11101110 | 0 | D | 00 | Vn | Vd | 10 | 11 | N | 0 | M | 0 | Vm
0xF2000900 VMLA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> A32 1111001 | 0 | 0 | D | size | Vn | Vd | 1001 | N | 0 | M | 0 | Vm
0xF2000940 VMLA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> A32 1111001 | 0 | 0 | D | size | Vn | Vd | 1001 | N | 1 | M | 0 | Vm
0xEF000900 VMLA{<c>}{<q>}.<dt> <Dd>, <Dn>, <Dm> T32 111 | 0 | 11110 | D | size | Vn | Vd | 1001 | N | 0 | M | 0 | Vm
0xEF000940 VMLA{<c>}{<q>}.<dt> <Qd>, <Qn>, <Qm> T32 111 | 0 | 11110 | D | size | Vn | Vd | 1001 | N | 1 | M | 0 | Vm

Description

Vector Multiply Accumulate multiplies corresponding elements in two vectors, and accumulates the results into the elements of the destination vector. Depending on settings in the CPACR, NSACR, HCPTR, and FPEXC registers, and the Security state and PE mode in which the instruction is executed, an attempt to execute the instruction might be undefined, or trapped to Hyp mode. For more information see Enabling Advanced SIMD and floating-point support.

Operation

if ConditionPassed() then
    EncodingSpecificOperations();  CheckAdvSIMDOrVFPEnabled(TRUE, advsimd);
    if advsimd then  // Advanced SIMD instruction
        for r = 0 to regs-1
            for e = 0 to elements-1
                product = FPMul(Elem[D[n+r],e,esize], Elem[D[m+r],e,esize], StandardFPSCRValue());
                addend = if add then product else FPNeg(product);
                Elem[D[d+r],e,esize] = FPAdd(Elem[D[d+r],e,esize], addend, StandardFPSCRValue());
    else             // VFP instruction
        case esize of
            when 16
                addend16 = (if add then FPMul(S[n]<15:0>, S[m]<15:0>, FPSCR[])
                            else FPNeg(FPMul(S[n]<15:0>, S[m]<15:0>, FPSCR[])));
                S[d] = Zeros(16) : FPAdd(S[d]<15:0>, addend16, FPSCR[]);
            when 32
                addend32 = (if add then FPMul(S[n], S[m], FPSCR[])
                            else FPNeg(FPMul(S[n], S[m], FPSCR[])));
                S[d] = FPAdd(S[d], addend32, FPSCR[]);
            when 64
                addend64 = (if add then FPMul(D[n], D[m], FPSCR[])
                            else FPNeg(FPMul(D[n], D[m], FPSCR[])));
                D[d] = FPAdd(D[d], addend64, FPSCR[]);