smlal

Signed Multiply-Accumulate Long

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

Multiplies signed narrow vectors and adds to wide destination.

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
31
Q
30
0
29
01110
28:24
size
23:22
1
21
Rm
20:16
10
15:14
0
13
000
12:10
Rn
9:5
Rd
4:0
 
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

Related

Other forms of smlal

  • smlal Signed Multiply Accumulate Long (Thumb)

More in NEON (SIMD)

Reference

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;