smlad

Signed Multiply Accumulate Dual

SMLAD{X}<c> <Rd>, <Rn>, <Rm>, <Ra>

Dual multiply add + accumulate.

Details

Multiplies two pairs of signed 16-bit values and adds the products, then adds the accumulator Ra: (Rn[31:16] × Rm[31:16]) + (Rn[15:0] × Rm[15:0]) + Ra, storing the 32-bit signed result in Rd. 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], 32) × SignExtend(Rm[15:0], 32)
  prod2 ← SignExtend(Rn[15:0], 32) × SignExtend(Rm[31:16], 32)
else
  prod1 ← SignExtend(Rn[31:16], 32) × SignExtend(Rm[31:16], 32)
  prod2 ← SignExtend(Rn[15:0], 32) × SignExtend(Rm[15:0], 32)
Rd ← prod1 + prod2 + Ra

Example

SMLAD r0, r1, r2, r5

Encoding

Binary Layout
cond
01110
000
Rd
Ra
Rm
00
0
1
Rn
 
Format Multiply
Opcode 0x07000010
Extension A32 (DSP)

Operands

  • Rd
    Destination general-purpose register
  • Rn
    First source / base general-purpose register
  • Rm
    Second source / offset general-purpose register
  • Ra
    Acc

Reference (Arm AArch32 ISA)

Instruction Forms

Encoding Instruction ISA Bit pattern
0x07000010 SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> A32 cond | 01110 | 000 | Rd | Ra | Rm | 00 | 0 | 1 | Rn
0xFB200000 SMLAD{<c>}{<q>} <Rd>, <Rn>, <Rm>, <Ra> T32 111110110 | 010 | Rn | Ra | Rd | 00 | 0 | 0 | Rm

Description

Signed Multiply Accumulate Dual performs two signed 16 x 16-bit multiplications. It adds the products to a 32-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. This instruction sets PSTATE.Q to 1 if the accumulate operation overflows. Overflow cannot occur during the multiplications.

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[a]);
    R[d] = result<31:0>;
    if result != SInt(result<31:0>) then  // Signed overflow
        PSTATE.Q = '1';