smlaltb

Signed Multiply Accumulate Long (Top x Bottom)

SMLALTB<c> <RdLo>, <RdHi>, <Rn>, <Rm>

Accumulates (Rn.T * Rm.B) into 64-bit pair.

Details

Signed Multiply Accumulate Long (Top × Bottom) multiplies the top 16 bits of Rn by the bottom 16 bits of Rm, treating both as signed, and accumulates the 32-bit result into the 64-bit value formed by RdHi:RdLo. This A32 DSP extension instruction does not update condition flags and is not available in AArch64.

Pseudocode Operation

operand1 ← SignExtend(Rn[31:16], 32);
operand2 ← SignExtend(Rm[15:0], 32);
result ← operand1 * operand2;
RdHi:RdLo ← RdHi:RdLo + result;

Example

SMLALTB r1, r0, r1, r2

Encoding

Binary Layout
cond
00010
10
0
RdHi
RdLo
Rm
1
0
1
0
Rn
 
Format Multiply
Opcode 0x014000A0
Extension A32 (DSP)

Operands

  • RdLo
    Lo
  • RdHi
    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
0x014000A0 SMLALTB{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm> A32 cond | 00010 | 10 | 0 | RdHi | RdLo | Rm | 1 | 0 | 1 | 0 | Rn
0xFBC000A0 SMLALTB{<c>}{<q>} <RdLo>, <RdHi>, <Rn>, <Rm> T32 111110111 | 100 | Rn | RdLo | RdHi | 10 | 1 | 0 | Rm

Description

Signed Multiply Accumulate Long (halfwords) multiplies two signed 16-bit values to produce a 32-bit value, and accumulates this with a 64-bit value. The multiply acts on two signed 16-bit quantities, taken from either the bottom or the top half of their respective source registers. The other halves of these source registers are ignored. The 32-bit product is sign-extended and accumulated with a 64-bit accumulate value. 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();
    operand1 = if n_high then R[n]<31:16> else R[n]<15:0>;
    operand2 = if m_high then R[m]<31:16> else R[m]<15:0>;
    result = SInt(operand1) * SInt(operand2) + SInt(R[dHi]:R[dLo]);
    R[dHi] = result<63:32>;
    R[dLo] = result<31:0>;