smlald

Signed Multiply Accumulate Long Dual

SMLALD{X}<c> <RdLo>, <RdHi>, <Rn>, <Rm>

Dual multiply add + 64-bit accumulate.

Details

Multiplies two pairs of signed 16-bit values and adds the products to a 64-bit accumulator: (Rn[31:16] × Rm[31:16]) + (Rn[15:0] × Rm[15:0]) + (RdHi:RdLo), storing the 64-bit signed result in RdHi:RdLo. The {X} variant swaps operands of one multiply. Does not update condition flags. A32 DSP extension only.

Pseudocode Operation

if X then
  prod1 ← SignExtend(Rn[31:16], 64) × SignExtend(Rm[15:0], 64)
  prod2 ← SignExtend(Rn[15:0], 64) × SignExtend(Rm[31:16], 64)
else
  prod1 ← SignExtend(Rn[31:16], 64) × SignExtend(Rm[31:16], 64)
  prod2 ← SignExtend(Rn[15:0], 64) × SignExtend(Rm[15:0], 64)
accum ← (RdHi << 32) | RdLo
result ← prod1 + prod2 + accum
RdHi ← result[63:32]
RdLo ← result[31:0]

Example

SMLALD r1, r0, r1, r2

Encoding

Binary Layout
cond
01110
100
RdHi
RdLo
Rm
00
0
1
Rn
 
Format Multiply
Opcode 0x07400010
Extension A32 (DSP)

Operands

  • RdLo
    Dest Lo
  • RdHi
    Dest Hi
  • Rn
    First source / base general-purpose register
  • Rm
    Second source / offset general-purpose register

Reference (Arm AArch32 ISA)

Instruction Forms

Encoding Instruction ISA Bit pattern
0x07400010 SMLALD{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm> A32 cond | 01110 | 100 | RdHi | RdLo | Rm | 00 | 0 | 1 | Rn
0xFBC000C0 SMLALD{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm> T32 111110111 | 100 | Rn | RdLo | RdHi | 110 | 0 | Rm

Description

Signed Multiply Accumulate Long Dual performs two signed 16 x 16-bit multiplications. It adds the products to a 64-bit accumulate operand. Optionally, the instruction can exchange the halfwords of the second operand before performing the arithmetic. This produces top x bottom and bottom x top multiplication. Overflow is possible during this instruction, but only as a result of the 64-bit addition. This overflow is not detected if it occurs. Instead, the result wraps around modulo 264.

Operation

if ConditionPassed() then
    EncodingSpecificOperations();
    operand2 = if m_swap then ROR(R[m],16) else R[m];
    product1 = SInt(R[n]<15:0>) * SInt(operand2<15:0>);
    product2 = SInt(R[n]<31:16>) * SInt(operand2<31:16>);
    result = product1 + product2 + SInt(R[dHi]:R[dLo]);
    R[dHi] = result<63:32>;
    R[dLo] = result<31:0>;