6.2.2. Multiply and divide instructions

The multiply instructions provided are broadly similar to those in ARMv7-A, but with the ability to perform 64-bit multiplies in a single instruction.

Table 6.2. Multiplication operations in assembly language

Opcode Description
Multiply instructions
MADDMultiply add
MNEGMultiply negate
MSUB Multiply subtract
SMADDL Signed multiply-add long
SMNEGL Signed multiply-negate long
SMSUBL Signed multiply-subtract long
SMULHSigned multiply returning high half
SMULLSigned multiply long
UMADDLUnsigned multiply-add long
UMNEGL Unsigned multiply-negate long
UMSUBLUnsigned multiply-subtract long
UMULHUnsigned multiply returning high half
UMULLUnsigned multiply long
Divide instructions
SDIVSigned divide
UDIVUnsigned divide

There are multiply instructions that operate on 32-bit or 64-bit values and return a result of the same size as the operands. For example, two 64-bit registers can be multiplied to produce a 64-bit result with the MUL instruction.

  MUL X0, X1, X2           // X0 = X1 * X2

There is also the ability to add or subtract an accumulator value in a third source register, using the MADD or MSUB instructions.

The MNEG instruction can be used to negate the result, for example:

  MNEG X0, X1, X2           // X0 = -(X1 * X2)

Additionally, there are a range of multiply instructions that produce a long result, that is, multiplying two 32-bit numbers and generating a 64-bit result. There are both signed and unsigned variants of these long multiplies (UMULL, SMULL). There are also options to accumulate a value from another register (UMADDL, SMADDL) or to negate (UMNEGL, SMNEGL).

Including 32-bit and 64-bit multiply with optional accumulation give a result size the same size as the operands:

Widening multiply, that is signed and unsigned, with accumulation gives a single 64-bit result:

A 64 × 64 to 128-bit multiply requires a sequence of two instructions to generate a pair of 64-bit result registers:


The list contains no 32 × 64 options. You cannot directly multiply a 32-bit W register by a 64-bit X register.

The ARMv8-A architecture has support for signed and unsigned division of 32-bit and 64-bit sized values. For example:

  UDIV W0, W1, W2          // W0 = W1 / W2 (unsigned, 32-bit divide)
  SDIV X0, X1, X2          // X0 = X1 / X2 (signed, 64-bit divide)

Overflow and divide-by-zero are not trapped:

Copyright © 2015 ARM. All rights reserved.ARM DEN0024A