umlal

Unsigned Multiply-Accumulate Long

UMLAL <Vd>.<Td>, <Vn>.<Ts>, <Vm>.<Ts>

Multiplies unsigned narrow vectors and adds to wide destination.

Details

Multiplies corresponding unsigned elements of two narrow SIMD vectors and adds the widened products to the existing contents of a wider destination register. This is an AArch64-only NEON instruction that performs zero-extended multiplication followed by accumulation on integer element types (8, 16, or 32 bits). Condition flags are not affected.

Pseudocode Operation

for i = 0 to (128 >> (size+1)) - 1 do
  op1 ← ZeroExtend(Vn[i], element_width)
  op2 ← ZeroExtend(Vm[i], element_width)
  Vd[i] ← Vd[i] + (op1 * op2)
end for

Example

UMLAL v0.4s.Td, v1.4s.Ts, v2.4s.Ts

Encoding

Binary Layout
0
Q
1
01110
size
1
Rm
10
0
000
Rn
Rd
 
Format SIMD Three Register Diff
Opcode 0x2E208000
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
0x2F002000 UMLAL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>] A64 0 | Q | 1 | 01111 | size | L | M | Rm | 0 | 0 | 10 | H | 0 | Rn | Rd
0x2E208000 UMLAL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb> A64 0 | Q | 1 | 01110 | size | 1 | Rm | 10 | 0 | 000 | Rn | Rd
0xC1C01010 UMLAL ZA.S[<Wv>, <offs1>:<offs2>], <Zn>.H, <Zm>.H[<index>] A64 110000011100 | Zm | i3h | Rv | 1 | i3l | Zn | 1 | 0 | off3
0xC1D01010 UMLAL ZA.S[<Wv>, <offs1>:<offs2>{, VGx2}], { <Zn1>.H-<Zn2>.H }, <Zm>.H[<index>] A64 110000011101 | Zm | 0 | Rv | 1 | i3h | Zn | 0 | 1 | 0 | i3l | off2
0xC1D09010 UMLAL ZA.S[<Wv>, <offs1>:<offs2>{, VGx4}], { <Zn1>.H-<Zn4>.H }, <Zm>.H[<index>] A64 110000011101 | Zm | 1 | Rv | 1 | i3h | Zn | 00 | 1 | 0 | i3l | off2
0xC1600C10 UMLAL ZA.S[<Wv>, <offs1>:<offs2>], <Zn>.H, <Zm>.H A64 110000010110 | Zm | 0 | Rv | 011 | Zn | 1 | 0 | off3
0xC1600810 UMLAL ZA.S[<Wv>, <offs1>:<offs2>{, VGx2}], { <Zn1>.H-<Zn2>.H }, <Zm>.H A64 110000010110 | Zm | 0 | Rv | 010 | Zn | 1 | 0 | 0 | off2
0xC1700810 UMLAL ZA.S[<Wv>, <offs1>:<offs2>{, VGx4}], { <Zn1>.H-<Zn4>.H }, <Zm>.H A64 110000010111 | Zm | 0 | Rv | 010 | Zn | 1 | 0 | 0 | off2
0xC1E00810 UMLAL ZA.S[<Wv>, <offs1>:<offs2>{, VGx2}], { <Zn1>.H-<Zn2>.H }, { <Zm1>.H-<Zm2>.H } A64 11000001111 | Zm | 00 | Rv | 010 | Zn | 0 | 1 | 0 | 0 | off2
0xC1E10810 UMLAL ZA.S[<Wv>, <offs1>:<offs2>{, VGx4}], { <Zn1>.H-<Zn4>.H }, { <Zm1>.H-<Zm4>.H } A64 11000001111 | Zm | 010 | Rv | 010 | Zn | 00 | 1 | 0 | 0 | off2

Description

Unsigned Multiply-Add Long (vector). This instruction multiplies the vector elements in the lower or upper half of the first source SIMD&FP register by the corresponding vector elements of the second source SIMD&FP register, and accumulates the results with the vector elements of the destination SIMD&FP register. The destination vector elements are twice as long as the elements that are multiplied. The UMLAL instruction extracts vector elements from the lower half of the first source register. The UMLAL2 instruction extracts vector elements from the upper half of the first source 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 = Vpart[n, part, datasize];
bits(datasize) operand2 = Vpart[m, part, datasize];
bits(2*datasize) operand3 = V[d, 2*datasize];
bits(2*datasize) result;
integer element1;
integer element2;
bits(2*esize) product;
bits(2*esize) accum;

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

V[d, 2*datasize] = result;