smlal

Signed Multiply-Accumulate Long

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

Multiplies signed narrow vectors and adds to wide destination.

Details

Multiplies corresponding signed 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 sign-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 ← SignExtend(Vn[i], element_width)
  op2 ← SignExtend(Vm[i], element_width)
  Vd[i] ← Vd[i] + (op1 * op2)
end for

Example

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

Encoding

Binary Layout
0
Q
0
01110
size
1
Rm
10
0
000
Rn
Rd
 
Format SIMD Three Register Diff
Opcode 0x0E208000
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
0x0F002000 SMLAL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Ts>[<index>] A64 0 | Q | 0 | 01111 | size | L | M | Rm | 0 | 0 | 10 | H | 0 | Rn | Rd
0x0E208000 SMLAL{2} <Vd>.<Ta>, <Vn>.<Tb>, <Vm>.<Tb> A64 0 | Q | 0 | 01110 | size | 1 | Rm | 10 | 0 | 000 | Rn | Rd
0xC1C01000 SMLAL ZA.S[<Wv>, <offs1>:<offs2>], <Zn>.H, <Zm>.H[<index>] A64 110000011100 | Zm | i3h | Rv | 1 | i3l | Zn | 0 | 0 | off3
0xC1D01000 SMLAL ZA.S[<Wv>, <offs1>:<offs2>{, VGx2}], { <Zn1>.H-<Zn2>.H }, <Zm>.H[<index>] A64 110000011101 | Zm | 0 | Rv | 1 | i3h | Zn | 0 | 0 | 0 | i3l | off2
0xC1D09000 SMLAL ZA.S[<Wv>, <offs1>:<offs2>{, VGx4}], { <Zn1>.H-<Zn4>.H }, <Zm>.H[<index>] A64 110000011101 | Zm | 1 | Rv | 1 | i3h | Zn | 00 | 0 | 0 | i3l | off2
0xC1600C00 SMLAL ZA.S[<Wv>, <offs1>:<offs2>], <Zn>.H, <Zm>.H A64 110000010110 | Zm | 0 | Rv | 011 | Zn | 0 | 0 | off3
0xC1600800 SMLAL ZA.S[<Wv>, <offs1>:<offs2>{, VGx2}], { <Zn1>.H-<Zn2>.H }, <Zm>.H A64 110000010110 | Zm | 0 | Rv | 010 | Zn | 0 | 0 | 0 | off2
0xC1700800 SMLAL ZA.S[<Wv>, <offs1>:<offs2>{, VGx4}], { <Zn1>.H-<Zn4>.H }, <Zm>.H A64 110000010111 | Zm | 0 | Rv | 010 | Zn | 0 | 0 | 0 | off2
0xC1E00800 SMLAL ZA.S[<Wv>, <offs1>:<offs2>{, VGx2}], { <Zn1>.H-<Zn2>.H }, { <Zm1>.H-<Zm2>.H } A64 11000001111 | Zm | 00 | Rv | 010 | Zn | 0 | 0 | 0 | 0 | off2
0xC1E10800 SMLAL ZA.S[<Wv>, <offs1>:<offs2>{, VGx4}], { <Zn1>.H-<Zn4>.H }, { <Zm1>.H-<Zm4>.H } A64 11000001111 | Zm | 010 | Rv | 010 | Zn | 00 | 0 | 0 | 0 | off2

Description

Signed Multiply-Add Long (vector). This instruction multiplies corresponding signed integer values in the lower or upper half of the vectors of the two source SIMD&FP registers, 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 SMLAL instruction extracts each source vector from the lower half of each source register. The SMLAL2 instruction extracts each source vector from the upper half of each 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;