Summary: Splices two vectors based on the last active element of the first.

SVE Splice Vectors concatenates Zdn and Zm, then extracts a contiguous segment starting from the element position immediately after the last active element in Zdn (as determined by Pg), storing the result back in Zdn. This is used to splice vector sequences. No condition flags are affected. This is an AArch64-only SVE instruction requiring SVE support.

integer esize = 8 << UInt(sz);
integer elements = VL / esize;
integer last_active = -1;
for e = 0 to elements-1
  if Pg[e] == '1' then
    last_active = e;
integer start_pos = last_active + 1;
for e = 0 to elements-1
  if (start_pos + e) < elements then
    Zdn[e * esize +: esize] = Zdn[(start_pos + e) * esize +: esize];
  else
    Zdn[e * esize +: esize] = Zm[(start_pos + e - elements) * esize +: esize];


Summary: Looks up elements in a vector table using indices.

Zd

Destination scalable vector register (SVE)

SVE Table Lookup performs a vector table lookup where Zn acts as a table and Zm contains indices; Zd receives the looked-up elements. Out-of-range indices produce zero. This operation is element-wise and unpredicated. No condition flags are affected. This is an AArch64-only SVE instruction requiring SVE support.

integer esize = 8 << UInt(sz);
integer elements = VL / esize;
for e = 0 to elements-1
  integer index = UInt(Zm[e * esize +: esize]);
  if index < elements then
    Zd[e * esize +: esize] = Zn[index * esize +: esize];
  else
    Zd[e * esize +: esize] = 0;


Summary: Interleaves even elements from two vectors.

Zn

First source scalable vector register (SVE)

Zm

Second source scalable vector register (SVE)

SVE Transpose 1 interleaves elements from Zn and Zm, selecting even-indexed elements (0, 2, 4, ...) from the conceptual concatenation of Zn and Zm, placing them into Zd. This is an unpredicated operation commonly used for data rearrangement. No condition flags are affected. This is an AArch64-only SVE instruction requiring SVE support.

integer esize = 8 << UInt(sz);
integer elements = VL / esize;
for e = 0 to elements-1
  integer src_index = 2 * e;
  if src_index < elements then
    Zd[e * esize +: esize] = Zn[src_index * esize +: esize];
  else
    Zd[e * esize +: esize] = Zm[(src_index - elements) * esize +: esize];


Summary: Interleaves odd elements from two vectors.

SVE Transpose 2 interleaves elements from Zn and Zm, selecting odd-indexed elements (1, 3, 5, ...) from the conceptual concatenation of Zn and Zm, placing them into Zd. This is an unpredicated operation commonly used for data rearrangement. No condition flags are affected. This is an AArch64-only SVE instruction requiring SVE support.

integer esize = 8 << UInt(sz);
integer elements = VL / esize;
for e = 0 to elements-1
  integer src_index = 2 * e + 1;
  if src_index < elements then
    Zd[e * esize +: esize] = Zn[src_index * esize +: esize];
  else
    Zd[e * esize +: esize] = Zm[(src_index - elements) * esize +: esize];


Summary: Selects even elements from concatenated vectors.

SVE Unzip 1 deinterlaces the concatenation of Zn and Zm by selecting even-indexed elements (0, 2, 4, ...) and packing them into Zd. This is the inverse of a zip/transpose operation. This is an unpredicated operation. No condition flags are affected. This is an AArch64-only SVE instruction requiring SVE support.


Summary: Selects odd elements from concatenated vectors.

SVE Unzip 2 deinterlaces the concatenation of Zn and Zm by selecting odd-indexed elements (1, 3, 5, ...) and packing them into Zd. This is the inverse of a zip/transpose operation. This is an unpredicated operation. No condition flags are affected. This is an AArch64-only SVE instruction requiring SVE support.


Summary: Interleaves elements from the lower halves.

Interleaves elements from the lower halves of two SVE vectors, placing odd-indexed elements from Zn and even-indexed elements from Zm into alternating positions in Zd. This is a data-permutation instruction that does not modify condition flags. Execution is restricted to AArch64 with the SVE extension enabled.

for i = 0 to VL/esize-1 step 2
  Zd[i, esize] ← Zn[i/2, esize]
  Zd[i+1, esize] ← Zm[i/2, esize]


Summary: Interleaves elements from the upper halves.

Interleaves elements from the upper halves of two SVE vectors, placing odd-indexed elements from the upper half of Zn and even-indexed elements from the upper half of Zm into alternating positions in Zd. This is a data-permutation instruction that does not modify condition flags. Execution is restricted to AArch64 with the SVE extension enabled.

half ← VL / (2 * esize)
for i = 0 to VL/esize-1 step 2
  Zd[i, esize] ← Zn[half + i/2, esize]
  Zd[i+1, esize] ← Zm[half + i/2, esize]


Summary: Shifts elements left under predicate.

Performs element-wise logical shift left on SVE vector elements under predicate control, where the shift amount for each element comes from the corresponding element of Zm. Only elements where the corresponding predicate bit is 1 are updated; others are left unchanged. No condition flags are affected. This is an AArch64-only SVE instruction requiring SVE support.

for i = 0 to VL/esize-1 do
  if Pg[i] then
    shift_amount ← Zm[i*esize +: esize] AND (esize*8-1)
    Zdn[i*esize +: esize] ← Zdn[i*esize +: esize] << shift_amount
  else
    // element unchanged
endfor


Summary: Shifts elements right logically under predicate.

Performs element-wise logical shift right on SVE vector elements under predicate control, where the shift amount for each element comes from the corresponding element of Zm. Shifted-in bits are zeros. Only elements where the corresponding predicate bit is 1 are updated; others are left unchanged. No condition flags are affected. This is an AArch64-only SVE instruction requiring SVE support.

for i = 0 to VL/esize-1 do
  if Pg[i] then
    shift_amount ← Zm[i*esize +: esize] AND (esize*8-1)
    Zdn[i*esize +: esize] ← Zdn[i*esize +: esize] >> shift_amount
  else
    // element unchanged
endfor


Summary: Shifts elements right arithmetically under predicate.

Performs element-wise arithmetic shift right on SVE vector elements under predicate control, where the shift amount for each element comes from the corresponding element of Zm. The sign bit is replicated into shifted-in positions. Only elements where the corresponding predicate bit is 1 are updated; others are left unchanged. No condition flags are affected. This is an AArch64-only SVE instruction requiring SVE support.

for i = 0 to VL/esize-1 do
  if Pg[i] then
    shift_amount ← Zm[i*esize +: esize] AND (esize*8-1)
    Zdn[i*esize +: esize] ← Zdn[i*esize +: esize] >>> shift_amount
  else
    // element unchanged
endfor


Summary: Loads words from non-contiguous addresses (Scatter-Gather).

LD1W { <Zt>.S }, <Pg>/Z, [<Xn|SP>, <Zm>.S, SXTW #<shift>]

Zt

Transfer scalable vector register (SVE load/store)

Xn

First source / base 64-bit integer register

Performs a scatter-gather load of 32-bit words from non-contiguous memory addresses computed by adding scaled vector indices to a base address. Elements are loaded only where the corresponding predicate bit in Pg is set; inactive elements in Zt are zeroed. Does not modify condition flags. Execution restricted to AArch64 with SVE extension; may generate memory-access exceptions.

for i = 0 to VL/32-1
  if Pg[i] == 1
    addr ← Xn + (Zm[i] << shift)
    Zt[i, 32] ← [addr, 32]
  else
    Zt[i, 32] ← 0


Summary: Stores words to non-contiguous addresses.

ST1W { <Zt>.S }, <Pg>, [<Xn|SP>, <Zm>.S, SXTW #<shift>]

Performs a scatter-gather store of 32-bit words from Zt to non-contiguous memory addresses computed by adding scaled vector indices to a base address. Elements are stored only where the corresponding predicate bit in Pg is set. Does not modify condition flags. Execution restricted to AArch64 with SVE extension; may generate memory-access exceptions.

for i = 0 to VL/32-1
  if Pg[i] == 1
    addr ← Xn + (Zm[i] << shift)
    [addr, 32] ← Zt[i, 32]


Summary: Sets predicate bits where elements are equal.

Performs element-wise equality comparison of signed or unsigned integers in Zn and Zm, setting predicate bits in Pd where elements are equal. Inactive lanes (where Pg is 0) are zeroed in Pd. Does not modify condition flags. Execution restricted to AArch64 with SVE extension.

for i = 0 to VL/esize-1
  if Pg[i] == 1
    Pd[i] ← (Zn[i, esize] == Zm[i, esize]) ? 1 : 0
  else
    Pd[i] ← 0


Summary: Sets predicate bits where Zn > Zm.

Performs element-wise signed greater-than comparison of integers in Zn and Zm, setting predicate bits in Pd where Zn > Zm. Inactive lanes (where Pg is 0) are zeroed in Pd. Does not modify condition flags. Execution restricted to AArch64 with SVE extension.

for i = 0 to VL/esize-1
  if Pg[i] == 1
    Pd[i] ← (Zn[i, esize] signed> Zm[i, esize]) ? 1 : 0
  else
    Pd[i] ← 0


Summary: Sets predicate bits where float elements are equal.

Performs element-wise floating-point equality comparison in Zn and Zm, setting predicate bits in Pd where elements are equal. Inactive lanes (where Pg is 0) are zeroed in Pd. NaN comparisons always return false. Does not modify condition flags. Execution restricted to AArch64 with SVE extension.


Summary: Sets predicate bits where float Zn > Zm.

Performs element-wise floating-point greater-than comparison in Zn and Zm, setting predicate bits in Pd where Zn > Zm. Inactive lanes (where Pg is 0) are zeroed in Pd. NaN comparisons always return false. Does not modify condition flags. Execution restricted to AArch64 with SVE extension.

for i = 0 to VL/esize-1
  if Pg[i] == 1
    Pd[i] ← (Zn[i, esize] > Zm[i, esize]) ? 1 : 0
  else
    Pd[i] ← 0


Summary: Adds two half-precision floating-point vectors.

Adds corresponding half-precision (16-bit) floating-point elements from two NEON vector registers and stores the results in the destination register. Eight elements are processed in parallel. The operation follows IEEE 754 half-precision semantics. No condition flags are set. This is an AArch64 instruction requiring the FEAT_FP16 extension for half-precision floating-point support.


Summary: Subtracts two half-precision floating-point vectors.

Subtracts half-precision floating-point elements in Vm from corresponding elements in Vn, writing results to Vd. Operates on 8 half-precision (16-bit) floating-point values packed in 128-bit vectors. No condition flags are set by this instruction; floating-point exceptions are determined by FPCR settings. Requires FEAT_FP16 extension; AArch64-only.


Summary: Multiplies two half-precision floating-point vectors.

Multiplies half-precision floating-point elements in Vn by corresponding elements in Vm, writing results to Vd. Operates on 8 half-precision (16-bit) floating-point values packed in 128-bit vectors. No condition flags are affected; floating-point exceptions follow FPCR rounding and exception control settings. Requires FEAT_FP16 extension; AArch64-only.


Summary: Divides two half-precision floating-point vectors.

Divides half-precision floating-point elements in Vn by corresponding elements in Vm, writing quotients to Vd. Operates on 8 half-precision (16-bit) floating-point values packed in 128-bit vectors. No condition flags are affected; division by zero and other floating-point exceptions depend on FPCR settings. Requires FEAT_FP16 extension; AArch64-only.


Summary: Finds max of half-precision vectors.

Computes the maximum of half-precision floating-point elements in Vn and Vm element-wise, writing results to Vd. Operates on 8 half-precision (16-bit) values in 128-bit vectors, with NaN handling per IEEE 754 semantics (FPCR controls exact behavior). No condition flags are set; floating-point exceptions depend on FPCR. Requires FEAT_FP16 extension; AArch64-only.


Summary: Finds min of half-precision vectors.

Computes the minimum of half-precision floating-point elements in Vn and Vm element-wise, writing results to Vd. Operates on 8 half-precision (16-bit) values in 128-bit vectors, with NaN handling per IEEE 754 semantics (FPCR controls exact behavior). No condition flags are set; floating-point exceptions depend on FPCR. Requires FEAT_FP16 extension; AArch64-only.


Floating-Point Multiply Accumulate (Half-Precision)

Summary: Fused multiply-add on half-precision vectors.

Fused multiply-add on half-precision (FP16) vectors. Computes Vd = Vd + (Vn × Vm) for each 16-bit element, with intermediate results computed in higher precision and rounded only once to FP16. Requires FEAT_FP16 extension. Condition flags (N, Z, C, V) are not affected; floating-point exceptions may be generated per IEEE 754 semantics.

for i = 0 to 7 do
  element = Vd.H[i] + (Vn.H[i] × Vm.H[i])
  Vd.H[i] = FPRound(element, FP16)
endfor


Floating-Point Multiply Subtract (Half-Precision)

Summary: Fused multiply-subtract on half-precision vectors.

Fused multiply-subtract: for each half-precision element, computes Vd - (Vn × Vm) and writes to Vd. Operates on 8 half-precision (16-bit) values in 128-bit vectors with a single rounding step. Vd is both source and destination (accumulator). No condition flags are set; exception behavior follows FPCR settings. Requires FEAT_FP16 extension; AArch64-only.


Floating-Point Absolute Value (Half-Precision)

Summary: Absolute value of half-precision vector.

Computes the absolute value (clear sign bit) of each half-precision floating-point element in Vn, writing results to Vd. Operates on 8 half-precision (16-bit) values in a 128-bit vector; this is a bitwise operation that does not raise floating-point exceptions. No condition flags are affected. Requires FEAT_FP16 extension; AArch64-only.


Summary: Negates half-precision vector.

Negates each half-precision floating-point element in Vn by flipping the sign bit, writing results to Vd. Operates on 8 half-precision (16-bit) values in a 128-bit vector; this is a bitwise operation that does not raise floating-point exceptions. No condition flags are affected. Requires FEAT_FP16 extension; AArch64-only.


Floating-Point Square Root (Half-Precision)

Summary: Square root of half-precision vector.

Computes the square root of each half-precision (FP16) floating-point element in the source vector and places the results in the destination vector. This is a NEON SIMD operation requiring FEAT_FP16 support. Condition flags are not affected; exceptions may be raised for invalid operands or overflow.

for i = 0 to 7
  Vd.H[i] ← FP16_SquareRoot(Vn.H[i])
endfor


Floating-Point Convert Long (Half to Single)

Summary: Converts Half-precision (Bottom) to Single-precision.

Converts the lower 4 half-precision (FP16) floating-point values from the source vector to single-precision (FP32) and writes them to the destination vector. Requires FEAT_FP16. Condition flags are not affected; may raise floating-point exceptions during conversion.

for i = 0 to 3
  Vd.S[i] ← FP16_to_FP32(Vn.H[i])
endfor


Floating-Point Convert Long High (Half to Single)

Summary: Converts Half-precision (Top) to Single-precision.

Converts the upper 4 half-precision (FP16) floating-point values from the source vector to single-precision (FP32) and writes them to the destination vector. Requires FEAT_FP16. Condition flags are not affected; may raise floating-point exceptions during conversion.

for i = 0 to 3
  Vd.S[i] ← FP16_to_FP32(Vn.H[i+4])
endfor


Floating-Point Convert Narrow (Single to Half)

Summary: Converts Single-precision to Half-precision (Bottom).

Converts the lower 4 single-precision (FP32) floating-point values from the source vector to half-precision (FP16) and writes them to the lower half of the destination vector. Requires FEAT_FP16. Condition flags are not affected; may raise floating-point exceptions during conversion.

for i = 0 to 3
  Vd.H[i] ← FP32_to_FP16(Vn.S[i])
endfor


Floating-Point Convert Narrow High (Single to Half)

Summary: Converts Single-precision to Half-precision (Top).

Converts 4 single-precision (FP32) floating-point values from the source vector to half-precision (FP16) and writes them to the upper half of the destination vector. Requires FEAT_FP16. Condition flags are not affected; may raise floating-point exceptions during conversion.

for i = 0 to 3
  Vd.H[i+4] ← FP32_to_FP16(Vn.S[i])
endfor


Summary: Dot product of signed integers (AArch64 NEON).

Signed dot product of 16 bytes viewed as 4 groups of 4 signed bytes, accumulating 32-bit signed integer results into Vd. Computes Vd[i] = Vd[i] + (Vn[4i] × Vm[4i]) + (Vn[4i+1] × Vm[4i+1]) + (Vn[4i+2] × Vm[4i+2]) + (Vn[4i+3] × Vm[4i+3]) for each 32-bit lane. Requires FEAT_DotProd. Condition flags are not affected.

for i = 0 to 3 do
  sum ← 0
  for j = 0 to 3 do
    sum ← sum + SignExtend(Vn.B[4*i + j], 32) × SignExtend(Vm.B[4*i + j], 32)
  endfor
  Vd.S[i] ← Vd.S[i] + sum
endfor


Summary: Dot product of unsigned integers (AArch64 NEON).

Unsigned dot product of 16 bytes viewed as 4 groups of 4 unsigned bytes, accumulating 32-bit unsigned integer results into Vd. Computes Vd[i] = Vd[i] + (Vn[4i] × Vm[4i]) + (Vn[4i+1] × Vm[4i+1]) + (Vn[4i+2] × Vm[4i+2]) + (Vn[4i+3] × Vm[4i+3]) for each 32-bit lane. Requires FEAT_DotProd. Condition flags are not affected.

for i = 0 to 3 do
  sum ← 0
  for j = 0 to 3 do
    sum ← sum + ZeroExtend(Vn.B[4*i + j], 32) × ZeroExtend(Vm.B[4*i + j], 32)
  endfor
  Vd.S[i] ← Vd.S[i] + sum
endfor


Summary: Complex addition with rotation (NEON).

Performs complex addition of two single-precision (FP32) NEON vectors with a rotation applied to the second operand before addition. The rotation angle is specified by the rot immediate (90° or 270°). Requires FEAT_FCMA. Condition flags are not affected; may raise floating-point exceptions.

if rot == 0 then
  rotated_angle ← 90°
else
  rotated_angle ← 270°
endif
for i = 0 to 3 step 2
  real_acc ← Vn.S[i]
  imag_acc ← Vn.S[i+1]
  real_op ← Vm.S[i]
  imag_op ← Vm.S[i+1]
  (rotated_real, rotated_imag) ← ComplexRotate(real_op, imag_op, rotated_angle)
  Vd.S[i] ← real_acc + rotated_real
  Vd.S[i+1] ← imag_acc + rotated_imag
endfor


Floating-Point Complex Multiply Accumulate (NEON)

Summary: Complex multiply-accumulate with rotation (NEON).

Complex fused multiply-accumulate on single-precision (FP32) vectors with rotation applied to the multiplicand. Performs Vd = Vd + (Vn × rotate(Vm, rot)) where rotation is 0°, 90°, 180°, or 270° as specified by immediate. Treats elements as complex pairs (real, imaginary). Requires FEAT_FCMA. Condition flags are not affected; floating-point exceptions per IEEE 754.

// rot encodes: 0→0°, 1→90°, 2→180°, 3→270°
for i = 0 to 1 do
  rotated ← ComplexRotate(Vm.S[2*i:2*i+1], rot)
  product ← ComplexMultiply(Vn.S[2*i:2*i+1], rotated)
  Vd.S[2*i:2*i+1] ← Vd.S[2*i:2*i+1] + product
endfor


Summary: AES single round encryption (AArch64 NEON).

AES single round encryption on 128-bit state using 128-bit round key. Applies SubBytes, ShiftRows, MixColumns, and AddRoundKey transformations. Used in AES encryption loops (not the final round). Requires Crypto extension. Condition flags are not affected.

state ← Vd.B[0:15]
key ← Vm.B[0:15]
state ← SubBytes(state)
state ← ShiftRows(state)
state ← MixColumns(state)
state ← state ⊕ key
Vd.B[0:15] ← state


Summary: AES single round decryption (AArch64 NEON).

AES single round decryption on 128-bit state using 128-bit round key. Applies InvSubBytes, InvShiftRows, InvMixColumns, and AddRoundKey transformations. Used in AES decryption loops (not the final round). Requires Crypto extension. Condition flags are not affected.

state ← Vd.B[0:15]
key ← Vm.B[0:15]
state ← InvSubBytes(state)
state ← InvShiftRows(state)
state ← InvMixColumns(state)
state ← state ⊕ key
Vd.B[0:15] ← state


Summary: SHA1 hash update (AArch64 NEON).

Sd

Destination 32-bit floating-point register

Sn

First source 32-bit floating-point register

SHA1 hash update: rotates the 32-bit scalar value left by 1 bit and writes result to destination. This is a specialized operation used in SHA1 compression to update the working state. Requires Crypto extension. Condition flags are not affected.


Summary: SHA1 hash choose (AArch64 NEON).

SHA1 choose: computes SHA1 compression function's choose operation across 128-bit state, updating the state register. Takes a 32-bit scalar index and 4 × 32-bit vector of operands, producing updated 128-bit state. Requires Crypto extension. Condition flags are not affected.

// Simplified: SHA1C updates 128-bit state Qd with function output based on Sn and Vm
for i = 0 to 3 do
  Qd.S[i] ← SHA1Choose(Qd.S[i], Sn, Vm.S[i])
endfor


Summary: SHA256 hash part 1 (AArch64 NEON).

SHA256 Hash Part 1 performs the first part of a SHA256 compression function round, operating on 128-bit SIMD registers containing four 32-bit words. The instruction takes hash state values from Qn, a round constant and message schedule word from Vm.4S, and produces updated hash state in Qd. Condition flags are unaffected. This instruction requires AArch64 execution state and the Crypto extension.

hash_state ← SHA256HashPart1(Qn, Vm.4S)
Qd ← hash_state


Summary: SHA256 hash part 2 (AArch64 NEON).

SHA256 Hash Part 2 performs the second part of a SHA256 compression function round, operating on 128-bit SIMD registers containing four 32-bit words. The instruction takes hash state values from Qn, a round constant and message schedule word from Vm.4S, and produces updated hash state in Qd. Condition flags are unaffected. This instruction requires AArch64 execution state and the Crypto extension.

hash_state ← SHA256HashPart2(Qn, Vm.4S)
Qd ← hash_state


Summary: Polynomial multiply long (NEON).

Polynomial Multiply Long performs polynomial multiplication on the 64-bit elements from Vn and Vm, producing a 128-bit result in Vd. Each 64-bit input is treated as a polynomial with binary coefficients, and the result is a 128-bit polynomial. Condition flags are unaffected. This instruction requires AArch64 execution state and the Crypto extension (AES variant).

product ← PolynomialMultiply(Vn[0], Vm[0])
Vd ← product[127:0]


Summary: Calculates (Rn * Rm) + RdLo + RdHi -> 64-bit result.

Rn

First source / base general-purpose register

Rm

Second source / offset general-purpose register

Unsigned Multiply Accumulate Accumulate Long multiplies Rn by Rm, adds both RdLo and RdHi to the product, and writes the 64-bit result back to RdLo:RdHi. All operands are treated as unsigned 32-bit values. Condition flags are not affected; RdLo and RdHi must be different registers. This instruction is available in A32/T32 and requires the DSP extension on some implementations.

temp ← (Rn * Rm) + RdLo + RdHi
RdLo ← temp[31:0]
RdHi ← temp[63:32]


Summary: Loads a word using User Mode permissions (even if Privileged).

Rt

Transfer general-purpose register (load/store)

Load Register Unprivileged loads a 32-bit word from memory using unprivileged (User mode) permissions, regardless of the current privilege level, and writes it to Rt. The address is computed from Rn plus an optionally pre-indexed or post-indexed 12-bit signed immediate offset. Condition flags are unaffected. This instruction is available in A32/T32 and is commonly used for accessing user-mode memory from privileged code.

address ← Rn + SignExtend(imm12)
Rt ← ZeroExtend([address][31:0])
if W then Rn ← address


Summary: Loads a byte using User Mode permissions.

Load Register Byte Unprivileged loads an unsigned byte from memory using unprivileged (User mode) permissions, regardless of the current privilege level, and writes it zero-extended to Rt. The address is computed from Rn plus an optionally pre-indexed or post-indexed 12-bit signed immediate offset. Condition flags are unaffected. This instruction is available in A32/T32 and is commonly used for accessing user-mode memory from privileged code.

address ← Rn + SignExtend(imm12)
Rt ← ZeroExtend([address][7:0])
if W then Rn ← address


Summary: Loads a halfword using User Mode permissions.

Load Register Halfword Unprivileged loads an unsigned halfword (16 bits) from memory using unprivileged (User mode) permissions, regardless of the current privilege level, and writes it zero-extended to Rt. The address is computed from Rn plus a 12-bit signed immediate offset (formed from two 4-bit fields). Condition flags are unaffected. This instruction is available in A32/T32 and is commonly used for accessing user-mode memory from privileged code.

offset ← (imm4_upper << 4) | imm4_lower
address ← Rn + SignExtend(offset)
Rt ← ZeroExtend([address][15:0])
if W then Rn ← address


Summary: Loads a signed byte using User Mode permissions.

Load Register Signed Byte Unprivileged loads a signed byte from memory using unprivileged (User mode) permissions, regardless of the current privilege level, and writes it sign-extended to Rt. The address is computed from Rn plus a 12-bit signed immediate offset (formed from two 4-bit fields). Condition flags are unaffected. This instruction is available in A32/T32 and is commonly used for accessing user-mode memory from privileged code.

offset ← (imm4_upper << 4) | imm4_lower
address ← Rn + SignExtend(offset)
Rt ← SignExtend([address][7:0])
if W then Rn ← address


Load Register Signed Halfword Unprivileged

Summary: Loads a signed halfword using User Mode permissions.

Loads a signed halfword from memory using User Mode access permissions, ignoring the current privilege level. The loaded value is sign-extended to the full register width. No condition flags are affected. This is an A32 instruction that provides unprivileged memory access.

address ← Rn + (if U then imm else -imm); Rt ← SignExtend(Mem[address, 2], 16);


Summary: Stores a word using User Mode permissions.

Stores a 32-bit word to memory using User Mode access permissions, regardless of current privilege level. The T suffix indicates unprivileged (User mode) access is enforced. No condition flags are affected. This is an A32 instruction.

address ← Rn + (if U then imm12 else -imm12); Mem[address, 4] ← Rt[31:0];


Summary: Stores a byte using User Mode permissions.

Stores a byte (8 bits) to memory using User Mode access permissions, ignoring the current privilege level. The T suffix indicates unprivileged (User mode) access is enforced. No condition flags are affected. This is an A32 instruction.

address ← Rn + (if U then imm12 else -imm12); Mem[address, 1] ← Rt[7:0];


Summary: Stores a halfword using User Mode permissions.

Stores a halfword (16 bits) to memory using User Mode access permissions, ignoring the current privilege level. The T suffix indicates unprivileged (User mode) access is enforced. No condition flags are affected. This is an A32 instruction.

address ← Rn + (if U then imm else -imm); Mem[address, 2] ← Rt[15:0];


Summary: Read Check Write with soft failure reporting (Translation Hardening).

Atomically reads a 128-bit translation table descriptor from memory and checks its validity with soft failure reporting (FEAT_THE). Unlike RCW, failure does not raise an exception but returns status in the registers. The instruction requires 128-bit alignment and is available only in AArch64.

address ← Xn; data ← Mem[address, 16]; ValidateAndProcess(data); Xt ← data[63:0]; Xt+1 ← data[127:64]; if validation_failed then status ← FAIL else status ← PASS;


Summary: Atomically swaps a 128-bit register pair with a checked descriptor in memory, with Acquire semantics (Translation Hardening).

Atomically reads a 128-bit translation table descriptor from memory with Acquire memory ordering semantics (FEAT_THE). The instruction performs validation checking with Acquire constraints, preventing subsequent memory operations from being reordered before the load. Available only in AArch64 with 128-bit alignment requirement.

address ← Xn; data ← Mem[address, 16]; AcquireSemantics(); ValidateAndProcess(data); Xt ← data[63:0]; Xt+1 ← data[127:64];


Read Check Write Swap Pair (Acquire-Release)

Summary: Atomically swaps a 128-bit register pair with a checked descriptor in memory, with Acquire and Release semantics (Translation Hardening).

Atomically reads a 128-bit translation table descriptor from memory with full Acquire-Release memory ordering semantics (FEAT_THE). The instruction enforces both Acquire (on the read) and Release (implicit for conditional update) constraints, providing full mutual exclusion semantics. Available only in AArch64 with 128-bit alignment requirement.

address ← Xn; data ← Mem[address, 16]; AcquireSemantics(); ValidateAndProcess(data); if validated then Mem[address, 16] ← data; ReleaseSemantics(); Xt ← data[63:0]; Xt+1 ← data[127:64];


Summary: Injects an entry into the Branch Record Buffer (Debug).

Injects an entry into the Branch Record Buffer (BRB) for debugging purposes. This is a privileged system instruction that requires EL1 or higher execution level and is only available when FEAT_BRBE is implemented. The instruction does not affect any condition flags.

if PSTATE.EL == EL0 then
  UNDEFINED
else
  case op of
    when '0' BRBIall()
    when '1' BRBInj()


Summary: Pops the value from the Guarded Control Stack into LR.

Pops a value from the Guarded Control Stack (GCS) and loads it into the Link Register (LR/X30). This privileged instruction is available when FEAT_GCS is implemented and requires EL1 or higher. The instruction does not affect the condition flags but may generate a GCS exception if the stack underflows.

if FEAT_GCS == '0' then
  UNDEFINED
else if PSTATE.EL == EL0 then
  UNDEFINED
else
  X[30] ← GCSPop()
  PC ← X[30]


Summary: First step to switch the GCS pointer.

First step of a two-instruction sequence to switch the Guarded Control Stack pointer. This privileged instruction validates and begins the GCS pointer switch operation using the value in the source register. It is available when FEAT_GCS is implemented and requires EL1 or higher. The instruction does not affect condition flags.

if FEAT_GCS == '0' then
  UNDEFINED
else if PSTATE.EL == EL0 then
  UNDEFINED
else
  GCSSwitchStack1(X[t])


Summary: Second step to switch the GCS pointer.

Second step of a two-instruction sequence to switch the Guarded Control Stack pointer, completing the switch initiated by GCSSS1. This privileged instruction commits the new GCS pointer value and is available when FEAT_GCS is implemented and requires EL1 or higher. The instruction does not affect condition flags.

if FEAT_GCS == '0' then
  UNDEFINED
else if PSTATE.EL == EL0 then
  UNDEFINED
else
  GCSSwitchStack2(X[t])


Summary: Copies data from source to destination using SVE vector length.

Copies data from a source SVE vector register to a destination SVE vector register under predicate control, operating on elements of the specified type. This SVE2 instruction processes VL/element-size elements in parallel and does not affect condition flags. The predicate register controls which elements are copied; unpredicated elements in the destination are left unchanged.

for i = 0 to VL/esize-1 do
  if Pg[i] == '1' then
    Zd[i*esize +: esize] ← Zn[i*esize +: esize]


Summary: Multi-vector unsigned dot product (SME2).

Performs multi-vector unsigned dot product between byte elements, accumulating results into 32-bit destination registers. This SME2 instruction operates on a pair of consecutive 32-bit result registers and does not affect condition flags. Each 32-bit result accumulates the dot products of four unsigned byte multiplications.

for i = 0 to VL/32-1 do
  acc ← 0
  for j = 0 to 3 do
    acc ← acc + (unsigned(Zn[i*4+j]) × unsigned(Zm[i*4+j]))
  Zd[i*64 +: 32] ← Zd[i*64 +: 32] + acc
  Zd[i*64+32 +: 32] ← Zd[i*64+32 +: 32] + acc


Summary: Multi-vector signed dot product (SME2).

Performs signed dot products on pairs of 8-bit elements from two SVE registers and accumulates results into a pair of 32-bit destination registers. This SME2 instruction operates on multi-vector register pairs and does not modify condition flags. Requires SME2 extension; AArch64 only.

for i = 0 to (128 / 32) - 1
  acc ← (Zd1[i] as i32) + (Zd2[i] as i32)
  for j = 0 to 3
    acc ← acc + (sign_extend(Zn[i*4 + j], 8) * sign_extend(Zm[i*4 + j], 8))
  Zd1[i] ← acc
  Zd2[i] ← acc >> 32


Summary: Adds BFloat16 elements.

Adds BFloat16 (16-bit) elements from two SVE registers under predicate control and stores the result in the destination register. Floating-point exceptions may be generated; condition flags are unaffected. Requires FEAT_SVE_B16B16; AArch64 only.

for i = 0 to VL/16 - 1
  if Pg[i]
    Zdn[i] ← FP_Add(Zdn[i], Zm[i], RMode_TONEAREST)
  else
    Zdn[i] ← Zdn[i]


Summary: Subtracts BFloat16 elements.

Subtracts BFloat16 (16-bit) elements of one SVE register from another under predicate control and stores the result in the destination register. Floating-point exceptions may be generated; condition flags are unaffected. Requires FEAT_SVE_B16B16; AArch64 only.

for i = 0 to VL/16 - 1
  if Pg[i]
    Zdn[i] ← FP_Sub(Zdn[i], Zm[i], RMode_TONEAREST)
  else
    Zdn[i] ← Zdn[i]


Summary: Multiplies BFloat16 elements.

Multiplies BFloat16 (16-bit) elements from two SVE registers under predicate control and stores the result in the destination register. Floating-point exceptions may be generated; condition flags are unaffected. Requires FEAT_SVE_B16B16; AArch64 only.

for i = 0 to VL/16 - 1
  if Pg[i]
    Zdn[i] ← FP_Mul(Zdn[i], Zm[i], RMode_TONEAREST)
  else
    Zdn[i] ← Zdn[i]


Summary: Calculates maximum of BFloat16 elements.

Computes the maximum of BFloat16 (16-bit) elements from two SVE registers under predicate control and stores the result in the destination register. Floating-point exceptions may be generated; condition flags are unaffected. Requires FEAT_SVE_B16B16; AArch64 only.

for i = 0 to VL/16 - 1
  if Pg[i]
    Zdn[i] ← FP_Max(Zdn[i], Zm[i])
  else
    Zdn[i] ← Zdn[i]


Summary: Calculates minimum of BFloat16 elements.

Computes the minimum of BFloat16 (16-bit) elements from two SVE registers under predicate control and stores the result in the destination register. Floating-point exceptions may be generated; condition flags are unaffected. Requires FEAT_SVE_B16B16; AArch64 only.

for i = 0 to VL/16 - 1
  if Pg[i]
    Zdn[i] ← FP_Min(Zdn[i], Zm[i])
  else
    Zdn[i] ← Zdn[i]


Summary: Adds two 64-bit values to a 64-bit result (Scalar NEON).

Adds the two 64-bit elements of a NEON vector register pairwise and stores the scalar 64-bit result in a destination register. Condition flags (N, Z, C, V) are set according to the result. AArch64 only with NEON extension.

result ← (Vn[0] as i64) + (Vn[1] as i64)
Dd ← result
N ← result[63]
Z ← (result == 0)
C ← Carry_Out(Vn[0], Vn[1])
V ← Overflow_From_Add(Vn[0], Vn[1])


Summary: Finds max float in a vector.

Floating-point maximum reduction across vector elements. Scans all floating-point elements in the source vector and writes the maximum value to the destination scalar register. FPSR is updated with cumulative exception flags from all comparisons; condition flags (N, Z, C, V) are unaffected. AArch64-only instruction requiring NEON support.

elements ← VecReduction(Vn, 'max')
Sd ← FPMaxReduction(elements)
FPSR.IOC ← FPSRAccum from comparisons


Summary: Finds min float in a vector.

Floating-point minimum reduction across vector elements. Scans all floating-point elements in the source vector and writes the minimum value to the destination scalar register. FPSR is updated with cumulative exception flags from all comparisons; condition flags (N, Z, C, V) are unaffected. AArch64-only instruction requiring NEON support.

elements ← VecReduction(Vn, 'min')
Sd ← FPMinReduction(elements)
FPSR.IOC ← FPSRAccum from comparisons


Floating-Point Round to 32-bit Integer (Exact)

Summary: Rounds to 32-bit integer, exact exception.

Rounds a 32-bit floating-point value to the nearest 32-bit integer value using the current rounding mode, signaling an inexact exception. Condition flags are unaffected. Requires FEAT_FRINTTS; AArch64 only.

result ← FP_RoundToInt(Sn, RMode_FromFPCR, exact=true)
if result != Sn
  FP_InexactException()
Sd ← result


Floating-Point Round to 32-bit Integer (Zero)

Summary: Rounds to 32-bit integer towards zero.

Rounds the source single-precision floating-point value to a 32-bit signed integer using round towards zero (truncate) rounding mode, and writes the result as a single-precision floating-point value to the destination. Does not update the NZCV condition flags. Requires FEAT_FRINTTS extension; AArch64 only.

Xn_bits ← Sn
int32_val ← RoundTowardsZero(FPUnpack(Xn_bits), 32)
Sd ← FPPack(int32_val as single-precision floating-point)


Floating-Point Round to 64-bit Integer (Exact)

Summary: Rounds to 64-bit integer, exact exception.

Rounds the source single-precision floating-point value to a 64-bit signed integer using the current rounding mode, and writes the result as a single-precision floating-point value to the destination. Signals an inexact exception if the input was not exactly representable as a 64-bit integer. Does not update the NZCV condition flags. Requires FEAT_FRINTTS extension; AArch64 only.

Xn_bits ← Sn
int64_val ← RoundUsingCurrentMode(FPUnpack(Xn_bits), 64)
if int64_val is inexact then signal_inexact_exception()
Sd ← FPPack(int64_val as single-precision floating-point)


Floating-Point Round to 64-bit Integer (Zero)

Summary: Rounds to 64-bit integer towards zero.

Rounds the source single-precision floating-point value to a 64-bit signed integer using round towards zero (truncate) rounding mode, and writes the result as a single-precision floating-point value to the destination. Does not update the NZCV condition flags. Requires FEAT_FRINTTS extension; AArch64 only.

Xn_bits ← Sn
int64_val ← RoundTowardsZero(FPUnpack(Xn_bits), 64)
Sd ← FPPack(int64_val as single-precision floating-point)


Summary: Check feature status (FEAT_CHK).

Checks the status of a system feature identified by the immediate operand and raises a CHK exception if the feature is not available or in the expected state. The specific behavior depends on the feature ID encoded in the immediate. Requires FEAT_CHK extension; AArch64 only; may only execute at EL0 and EL1 (subject to CHKFEATURE_EL0 register control).

feature_id ← imm
if not CheckFeature(feature_id) then raise_exception(CHK_EXCEPTION)


Summary: Clears the local monitor state (AArch64 variant).

Clears the local monitor state associated with the current PE, removing any exclusive accesses held by this processor. Subsequent LDEX/STEX instructions will treat the exclusive monitor as clear. Does not update condition flags. AArch64 only; optional immediate operand is typically 0xF (ignored).


Summary: Adds two single-precision floating-point registers.

Sm

Second source 32-bit floating-point register

Floating-point addition of two single-precision (32-bit) values. Adds operand Sn and operand Sm and writes the result to Sd. FPSR exception flags are updated; condition flags (N, Z, C, V) are unaffected. AArch64-only instruction; uses IEEE 754 rounding mode from FPCR.

operand1 ← Sn (32-bit float)
operand2 ← Sm (32-bit float)
result ← FPAdd(operand1, operand2)
Sd ← result
UpdateFPSR(exception_flags)


Summary: Adds two double-precision floating-point registers.

Floating-point addition of two double-precision (64-bit) values. Adds operand Dn and operand Dm and writes the result to Dd. FPSR exception flags are updated; condition flags (N, Z, C, V) are unaffected. AArch64-only instruction; uses IEEE 754 rounding mode from FPCR.

operand1 ← Dn (64-bit float)
operand2 ← Dm (64-bit float)
result ← FPAdd(operand1, operand2)
Dd ← result
UpdateFPSR(exception_flags)


Summary: Subtracts two single-precision floating-point registers.

Floating-point subtraction of two single-precision (32-bit) values. Subtracts operand Sm from operand Sn and writes the result to Sd. FPSR exception flags are updated; condition flags (N, Z, C, V) are unaffected. AArch64-only instruction; uses IEEE 754 rounding mode from FPCR.

operand1 ← Sn (32-bit float)
operand2 ← Sm (32-bit float)
result ← FPSub(operand1, operand2)
Sd ← result
UpdateFPSR(exception_flags)


Summary: Subtracts two double-precision floating-point registers.

Floating-point subtraction of two double-precision (64-bit) values. Subtracts operand Dm from operand Dn and writes the result to Dd. FPSR exception flags are updated; condition flags (N, Z, C, V) are unaffected. AArch64-only instruction; uses IEEE 754 rounding mode from FPCR.

operand1 ← Dn (64-bit float)
operand2 ← Dm (64-bit float)
result ← FPSub(operand1, operand2)
Dd ← result
UpdateFPSR(exception_flags)


Summary: Multiplies two single-precision floating-point registers.

Floating-point multiplication of two single-precision (32-bit) values. Multiplies operand Sn by operand Sm and writes the result to Sd. FPSR exception flags are updated; condition flags (N, Z, C, V) are unaffected. AArch64-only instruction; uses IEEE 754 rounding mode from FPCR.

operand1 ← Sn (32-bit float)
operand2 ← Sm (32-bit float)
result ← FPMul(operand1, operand2)
Sd ← result
UpdateFPSR(exception_flags)


Summary: Multiplies two double-precision floating-point registers.

Floating-point multiplication of two double-precision (64-bit) values. Multiplies operand Dn by operand Dm and writes the result to Dd. FPSR exception flags are updated; condition flags (N, Z, C, V) are unaffected. AArch64-only instruction; uses IEEE 754 rounding mode from FPCR.

operand1 ← Dn (64-bit float)
operand2 ← Dm (64-bit float)
result ← FPMul(operand1, operand2)
Dd ← result
UpdateFPSR(exception_flags)


Summary: Divides two single-precision floating-point registers.

Divides the single-precision floating-point value in Sn by the value in Sm and stores the result in Sd. This instruction operates on 32-bit IEEE 754 floating-point values. The NZCV flags are updated based on the result: N is set if the result is negative, Z if zero, C and V are set according to IEEE 754 semantics. This is an AArch64-only instruction requiring the Floating-Point extension.

Sd ← Sn ÷ Sm
N ← Sd[31]
Z ← (Sd == 0.0)
C ← (overflow or underflow)
V ← (invalid operation or overflow)


Summary: Divides two double-precision floating-point registers.

Divides the double-precision floating-point value in Dn by the value in Dm and stores the result in Dd. This instruction operates on 64-bit IEEE 754 floating-point values. The NZCV flags are updated based on the result: N is set if the result is negative, Z if zero, C and V are set according to IEEE 754 semantics. This is an AArch64-only instruction requiring the Floating-Point extension.

Dd ← Dn ÷ Dm
N ← Dd[63]
Z ← (Dd == 0.0)
C ← (overflow or underflow)
V ← (invalid operation or overflow)


Summary: Compares two single-precision registers and updates NZCV flags.

Compares two single-precision floating-point registers (Sn and Sm) and updates the NZCV condition flags based on the result. Handles NaN operands by setting both N and V flags; neither operand being NaN results in N, Z, C, V being set according to the comparison outcome. AArch64 only.

op1 ← FPUnpack(Sn)
op2 ← FPUnpack(Sm)
result ← FPCompare(op1, op2)
if isNaN(op1) or isNaN(op2) then
  N ← 1; Z ← 0; C ← 1; V ← 1
else if op1 == op2 then
  N ← 0; Z ← 1; C ← 1; V ← 0
else if op1 < op2 then
  N ← 1; Z ← 0; C ← 0; V ← 0
else
  N ← 0; Z ← 0; C ← 1; V ← 0


Summary: Compares two double-precision registers and updates NZCV flags.

Compares two double-precision floating-point registers (Dn and Dm) and updates the NZCV condition flags based on the result. Handles NaN operands by setting both N and V flags; neither operand being NaN results in N, Z, C, V being set according to the comparison outcome. AArch64 only.

op1 ← FPUnpack(Dn)
op2 ← FPUnpack(Dm)
result ← FPCompare(op1, op2)
if isNaN(op1) or isNaN(op2) then
  N ← 1; Z ← 0; C ← 1; V ← 1
else if op1 == op2 then
  N ← 0; Z ← 1; C ← 1; V ← 0
else if op1 < op2 then
  N ← 1; Z ← 0; C ← 0; V ← 0
else
  N ← 0; Z ← 0; C ← 1; V ← 0


Summary: Copies value between floating-point registers.

Copies a 64-bit double-precision floating-point value from Dn to Dd without any conversion or modification. The condition flags NZCV are not affected. This is an AArch64-only instruction requiring the Floating-Point extension.


Summary: Moves immediate value into floating-point register.

Moves an 8-bit encoded immediate value into a 64-bit double-precision floating-point register Dd. The immediate is expanded to a full 64-bit floating-point value according to the VFPv3 expanded-immediate encoding scheme. The condition flags NZCV are not affected. This is an AArch64-only instruction requiring the Floating-Point extension.


Signed Integer Convert to Floating-point

Summary: Converts signed integer (scalar) to floating-point.

Converts a 64-bit signed integer value from Xn to a double-precision floating-point value using the current rounding mode, and writes the result to Dd. Does not update the NZCV condition flags. AArch64 only.

int_val ← X[n]
fp_result ← ConvertSignedIntegerToFP(int_val, double-precision, current_rounding_mode)
D[d] ← FPPack(fp_result)


Floating-point Convert to Signed Integer (Round towards Zero)

Summary: Converts floating-point to signed integer.

Converts a 64-bit double-precision floating-point value in Dn to a signed 64-bit integer, rounding towards zero, and stores the result in Xd. If the result overflows the signed 64-bit range, the result is the most negative or most positive 64-bit integer depending on the input sign. The condition flags NZCV are not affected. This is an AArch64-only instruction requiring the Floating-Point extension.

Xd ← ConvertToSignedInteger(Dn, RoundTowardZero)
if (overflow) then
  Xd ← (Dn < 0) ? INT64_MIN : INT64_MAX


Summary: Reverses the byte order in a 32-bit register (Endianness swap).

Wn

First source / base 32-bit integer register

Reverses the byte order of a 32-bit value in Wn and stores the result in Wd, performing endianness conversion. The upper 32 bits of the destination register are zeroed. The condition flags NZCV are not affected. This is an AArch64-only instruction available in the Base instruction set.


Summary: Reverses the bit order in a 64-bit register.

Reverses the bit order in a 64-bit register, placing the least significant bit at the most significant position. No condition flags are affected. This is an AArch64 instruction with no privilege requirements.


Summary: Extracts the lowest 8 bits and sign-extends to 32 bits (Alias for SBFM).

Extracts the lowest 8 bits of a 32-bit register and sign-extends the result to fill all 32 bits. No condition flags are affected. This is an AArch64 alias for SBFM (Signed Bitfield Move) with bit positions 0 and 7.


Summary: Sign-extends a 32-bit register to 64 bits (Alias for SBFM).

Sign-extends a 32-bit value to fill 64 bits, replicating bit 31 into all upper bits. No condition flags are affected. This is an AArch64 alias for SBFM with bit positions 0 and 31.


Summary: Adds two 32-bit values and the Carry flag.

Adds two 32-bit values from Rn and Rm along with the Carry flag (C) and stores the result in Rd. If the S bit is set, the condition flags are updated: N and Z reflect the result, C is set on unsigned overflow, V is set on signed overflow. The shift operand is optional and applies a shift to Rm before the addition. This is an A32 instruction with conditional execution.

shifted_Rm ← ApplyShift(Rm, shift)
result ← Rn + shifted_Rm + C
Rd ← result
if S then
  N ← result[31]
  Z ← (result == 0)
  C ← CarryOut(Rn + shifted_Rm + C)
  V ← OverflowFrom(Rn + shifted_Rm + C)


Summary: Adds two 32-bit values.

Adds two 32-bit operands and stores the result in the destination register. If the S bit is set, the condition flags (N, Z, C, V) are updated based on the result; otherwise they are unaffected. This is an A32 instruction where the condition code (cond) field determines execution based on the current condition flags.

result ← Rn + (Rm << shift_amount)
Rd ← result[31:0]
if S then
  N ← result[31]
  Z ← (result == 0)
  C ← CarryOut(Rn, Rm << shift_amount)
  V ← OverflowFrom(Rn, Rm << shift_amount)


Summary: Adds an immediate value to the PC register.

Computes the PC-relative address of a label and stores it in Rd. The address is calculated by adding an 12-bit immediate (rotated by an even number of bits) to PC. The assembler resolves the label to the appropriate immediate offset. The condition flags NZCV are not affected. This is an A32 instruction with conditional execution.

offset ← RotateImmediate(imm12)
Rd ← PC + offset


Summary: Performs a bitwise AND on two 32-bit values.

Performs a bitwise AND of two 32-bit values and stores the result in Rd. If the S suffix is present, condition flags are updated: N and Z are set based on the result, C is set to the shifter carry-out, and V is unaffected. Executes in A32 (32-bit ARM) instruction set only.

result ← Rn AND (Rm shifted by shift_amount)
Rd ← result
if S == 1 then
  N ← result[31]
  Z ← (result == 0)
  C ← shifter_carry_out
else
  condition_flags unchanged


Summary: Arithmetic right shift (sign-extending).

Performs an arithmetic right shift of Rm by the number of bits specified in Rs (register shift amount), sign-extending the vacated bits from the left. If the S suffix is present, condition flags are updated: N and Z based on the result, C set to the last bit shifted out, and V is unaffected. Executes in A32 only.

shift_amount ← Rs[7:0]
if shift_amount == 0 then
  result ← Rm
  carry_out ← C
else if shift_amount < 32 then
  result ← Rm >> shift_amount (arithmetic, sign-extended)
  carry_out ← Rm[shift_amount - 1]
else
  result ← (Rm[31] repeated 32 times)
  carry_out ← Rm[31]
Rd ← result
if S == 1 then
  N ← result[31]
  Z ← (result == 0)
  C ← carry_out
else
  condition_flags unchanged


Summary: Branch relative (PC +/- 32MB).

Performs a relative branch to a label up to ±32 MB from the current instruction. The branch is taken only if the condition code (specified by <c>) is satisfied; if no condition is specified, it is always taken (AL). The PC is updated to point to the target address. Executes in A32 only.

if condition_satisfied then
  PC ← PC + (sign_extend(imm24) << 2) + 8


Summary: Clears a bitfield in a register.

Clears a contiguous bitfield in a 32-bit register, setting bits from lsb to (lsb+width-1) to zero while preserving all other bits. No condition flags are affected. This is an A32 instruction where the condition code (cond) field determines execution; width is computed as (msb-lsb+1).

width ← msb - lsb + 1
mask ← ((1 << width) - 1) << lsb
Rd ← Rd AND NOT(mask)


Summary: Copies a bitfield into a register.

Copies a contiguous bitfield from the source register into the destination register at a specified bit position, preserving all other bits. No condition flags are affected. This is an A32 instruction where the condition code (cond) field determines execution; width is computed as (msb-lsb+1).

width ← msb - lsb + 1
mask ← ((1 << width) - 1)
source_bits ← (Rn AND mask) << lsb
dest_mask ← NOT((mask << lsb))
Rd ← (Rd AND dest_mask) OR source_bits


Summary: Performs AND NOT (Rd = Rn & ~Rm).

Performs a bitwise AND with the complement (NOT) of Rm, computing Rd = Rn AND ~Rm (bit clear). If the S suffix is present, condition flags are updated: N and Z set based on the result, C set to shifter carry-out, and V is unaffected. Executes in A32 only.

result ← Rn AND NOT(Rm shifted by shift_amount)
Rd ← result
if S == 1 then
  N ← result[31]
  Z ← (result == 0)
  C ← shifter_carry_out
else
  condition_flags unchanged


Summary: Causes a software breakpoint.

Causes a software breakpoint exception (BKPT) to be raised. The immediate operand is encoded in the instruction as a 16-bit value for debugging purposes but does not affect processor state directly. This is an A32 instruction that triggers a breakpoint interrupt; execution cannot proceed past this instruction without debugger intervention.

GenerateException(Breakpoint)
PC ← (unchanged by architecture, debugger determines resumption)


Summary: Calls a subroutine, storing return address in LR (R14).

Calls a subroutine by performing a relative branch to a label and storing the return address (address of the next instruction after BL) in the link register (LR, R14). The branch offset is ±32 MB from the current instruction. Branch is conditional based on the specified condition code. Executes in A32 only.

if condition_satisfied then
  LR ← PC + 4
  PC ← PC + (sign_extend(imm24) << 2) + 8


Summary: Calls subroutine and optionally switches to Thumb state.

Branches to a subroutine whose address is in a register and stores the return address (instruction following the BLX) in the link register (LR/R14). The least significant bit of the target register determines whether execution switches to Thumb state (bit[0]=1) or remains in A32 state (bit[0]=0). This is an A32 instruction where the condition code (cond) field determines execution.

LR ← PC + 4
PC ← Rm AND NOT(0x1)
if Rm[0] == 1 then CPSR.T ← 1 else CPSR.T ← 0


Summary: Branches to address in register, optionally switching ISA.

Branch to address in register Rm, optionally switching between A32/T32 instruction sets based on bit[0] of Rm (0=A32, 1=T32). No flags are affected. Execution state restricted to A32; generates an Undefined Instruction exception if executed in T32.

if ConditionPassed() then
  new_PC ← Rm & 0xFFFFFFFE
  if (Rm & 1) == 1 then
    CPSR.T ← 1
  else
    CPSR.T ← 0
  BranchWritePC(new_PC)


Summary: Clears the local exclusive access monitor.

Clears the local exclusive access monitor, cancelling any pending exclusive memory operations (LDREX/STREX sequences). No flags are affected. Restricted to A32 instruction set; in T32 use CLREX or equivalent (T32-encoded form).

if ConditionPassed() then
  ClearExclusiveMonitor()


Summary: Counts the number of consecutive zeros from MSB.

Counts the number of consecutive zero bits from the most significant bit (MSB) of Rm and stores the count in Rd; if Rm is 0, the result is 32. Condition flags are not affected by this instruction. Executes in A32 only.

if Rm == 0 then
  Rd ← 32
else
  count ← 0
  for i from 31 down to 0
    if Rm[i] == 1 then
      break
    count ← count + 1
  Rd ← count
condition_flags unchanged


Summary: Adds two values and updates flags (discarding result). Same as ADDS with no destination.

Computes Rn + (shifted Rm) and updates the N, Z, C, V flags based on the result, but discards the calculated value. Equivalent to an ADDS instruction with no destination register. Restricted to A32 instruction set.

if ConditionPassed() then
  (result, carry, overflow) ← AddWithCarry(Rn, shifted_Rm, '0')
  N ← result[31]
  Z ← (result == 0)
  C ← carry
  V ← overflow


Summary: Subtracts two values and updates flags (discarding result).

Computes Rn - (shifted Rm) and updates the N, Z, C, V flags based on the result, but discards the calculated value. Equivalent to a SUBS instruction with no destination register. Restricted to A32 instruction set.

if ConditionPassed() then
  (result, carry, overflow) ← AddWithCarry(Rn, NOT(shifted_Rm), '1')
  N ← result[31]
  Z ← (result == 0)
  C ← carry
  V ← overflow


Summary: Ensures memory access ordering.

Data Memory Barrier: guarantees that all explicit memory operations issued before this instruction complete before any memory operations after it begin. Affects memory ordering and synchronization semantics. No flags are affected. Restricted to A32 instruction set.

if ConditionPassed() then
  DataMemoryBarrier(option)


Summary: Ensures completion of memory accesses.

Data Synchronization Barrier: ensures all explicit memory operations issued before this instruction complete before the instruction itself completes, serializing memory access. No flags are affected. Restricted to A32 instruction set.

if ConditionPassed() then
  DataSynchronizationBarrier(option)


Summary: Performs bitwise XOR.

Performs a bitwise exclusive OR (XOR) of two 32-bit values and stores the result in Rd. If the S suffix is present, condition flags are updated: N and Z set based on the result, C set to shifter carry-out, and V is unaffected. Executes in A32 only.

result ← Rn XOR (Rm shifted by shift_amount)
Rd ← result
if S == 1 then
  N ← result[31]
  Z ← (result == 0)
  C ← shifter_carry_out
else
  condition_flags unchanged


Summary: Calls the Hypervisor (EL2).

Hypervisor Call: traps to Exception Level 2 (EL2 / Hypervisor), passing a 16-bit immediate as the hypervisor call number. Requires HYP mode to be available (ARMv7 with Virtualization Extensions or later). Generates HVC exception; no flags are affected. Restricted to A32 instruction set.

if ConditionPassed() then
  if not IsFeatureImplemented(HVP) then
    raise UndefinedInstruction
  else
    CallHypervisor(imm16)


Instruction Synchronization Barrier (A32)

Summary: Flushes the pipeline.

Instruction Synchronization Barrier: flushes the instruction pipeline and refetches following instructions, ensuring all previous instructions have completed. No flags are affected. Restricted to A32 instruction set.

if ConditionPassed() then
  InstructionSynchronizationBarrier(option)


Summary: Loads multiple registers from memory (Stack pop).

cond | 100 | 0 | 0 | 0 | W | 1 | Rn | register_list

Loads multiple 32-bit registers from consecutive memory addresses starting at the address in Rn (possibly pre- or post-adjusted based on addressing mode). If W=1, Rn is updated after the load; S controls whether user-mode registers are loaded in privileged modes. Condition flags are not affected. Executes in A32 only.

address ← Rn
if P == 1 and U == 1 then
  address ← address + 4
for each register in register_list (in ascending order)
  register ← memory[address]
  address ← address + 4
if P == 1 and U == 0 then
  address ← address - 4
if W == 1 then
  Rn ← address
if S == 1 then
  CPSR ← SPSR (if loading PC in privileged mode)
condition_flags unchanged


Summary: Loads a word from memory.

Loads a 32-bit word from memory at an address computed from a base register and 12-bit immediate offset, storing the result in the destination register. The P and W bits control addressing mode (offset, pre-indexed, or post-indexed). Condition flags are not affected by this instruction. Execution is conditional based on the 4-bit condition code field; available in A32 only.

offset ← ZeroExtend(imm12);
if U == 1 then address ← Rn + offset else address ← Rn - offset;
if P == 1 then address ← address else address ← Rn;
Rt ← MemRead(address, 4);
if W == 1 then Rn ← address;


Summary: Loads a byte from memory (Zero extended).

Loads an unsigned byte (8 bits) from memory and zero-extends it to 32 bits, storing the result in the destination register. The P and W bits control addressing mode. Condition flags are not affected. Execution is conditional based on the 4-bit condition code field; available in A32 only.

offset ← ZeroExtend(imm12);
if U == 1 then address ← Rn + offset else address ← Rn - offset;
if P == 1 then address ← address else address ← Rn;
Rt ← ZeroExtend(MemRead(address, 1));
if W == 1 then Rn ← address;


Summary: Loads two consecutive words into consecutive registers.

Loads two consecutive 32-bit words from memory into two consecutive registers. The 8-bit immediate (imm4H:imm4L) is shifted left by 2 bits to form a byte offset. The P and W bits control addressing mode (offset, pre-indexed, or post-indexed). Condition flags are not affected. Execution is conditional; available in A32 only.

offset ← ZeroExtend(imm4H:imm4L) << 2;
if U == 1 then address ← Rn + offset else address ← Rn - offset;
if P == 1 then address ← address else address ← Rn;
Rt ← MemRead(address, 4);
Rt2 ← MemRead(address + 4, 4);
if W == 1 then Rn ← address + 8;


Summary: Loads a word and marks physical address as exclusive.

Loads a 32-bit word from memory and tags the physical address as exclusively held by the processor, enabling atomic compare-and-swap sequences via STREX. The address must be word-aligned. Condition flags are not affected. This instruction requires word-aligned addresses and is available in A32 only; it is essential for implementing locks and atomic operations.

address ← Rn;
if (address MOD 4) != 0 then UNPREDICTABLE;
Rt ← MemRead(address, 4);
MarkExclusive(address, ProcessorID(), 4);


Summary: Loads a halfword (Zero extended).

Loads an unsigned halfword (16 bits) from memory and zero-extends it to 32 bits, storing the result in the destination register. The 8-bit immediate (imm4H:imm4L) is shifted left by 1 bit to form a byte offset. The P and W bits control addressing mode. Condition flags are not affected. Execution is conditional; available in A32 only.

offset ← ZeroExtend(imm4H:imm4L) << 1;
if U == 1 then address ← Rn + offset else address ← Rn - offset;
if P == 1 then address ← address else address ← Rn;
Rt ← ZeroExtend(MemRead(address, 2));
if W == 1 then Rn ← address;


Summary: Loads a byte and sign-extends it.

Loads a signed byte (8 bits) from memory and sign-extends it to 32 bits, storing the result in the destination register. The 8-bit immediate (imm4H:imm4L) is shifted left by 0 bits to form the byte offset. The P and W bits control addressing mode. Condition flags are not affected. Execution is conditional; available in A32 only.

offset ← ZeroExtend(imm4H:imm4L);
if U == 1 then address ← Rn + offset else address ← Rn - offset;
if P == 1 then address ← address else address ← Rn;
Rt ← SignExtend(MemRead(address, 1));
if W == 1 then Rn ← address;


Summary: Loads a halfword and sign-extends it.

Loads a signed halfword (16 bits) from memory and sign-extends it to 32 bits, storing the result in the destination register. The 8-bit immediate (imm4H:imm4L) is shifted left by 1 bit to form a byte offset. The P and W bits control addressing mode. Condition flags are not affected. Execution is conditional; available in A32 only.

offset ← ZeroExtend(imm4H:imm4L) << 1;
if U == 1 then address ← Rn + offset else address ← Rn - offset;
if P == 1 then address ← address else address ← Rn;
Rt ← SignExtend(MemRead(address, 2));
if W == 1 then Rn ← address;


Summary: Shifts a register left.

Shifts the value in Rm left by the number of bits specified in the low 8 bits of Rs, storing the result in Rd. If S=1, the condition flags N, Z, C, and V are updated: N and Z reflect the result, C receives the last bit shifted out, and V is unaffected. Execution is conditional based on the 4-bit condition code; available in A32 only.

shift_amount ← Rs[7:0];
if shift_amount == 0 then result ← Rm else if shift_amount < 32 then (C_out, result) ← Rm << shift_amount else if shift_amount == 32 then (C_out, result) ← (Rm[31], 0) else (C_out, result) ← (0, 0);
Rd ← result;
if S == 1 then N ← result[31]; Z ← (result == 0); C ← C_out;


Summary: Shifts a register right.

Logical Shift Right shifts the value in Rm right by the number of bits specified in the lower byte of Rs, filling vacated bits with zeros. The C flag is set to the last bit shifted out, and if the S bit is set, the N and Z flags are updated based on the result. This is an A32 instruction available in all privilege levels.

shift_amount ← Rs[7:0]
if shift_amount == 0 then
  Rd ← Rm
  if S == 1 then C ← C
else if shift_amount < 32 then
  Rd ← Rm >> shift_amount
  if S == 1 then C ← Rm[shift_amount - 1]
else if shift_amount == 32 then
  Rd ← 0
  if S == 1 then C ← Rm[31]
else
  Rd ← 0
  if S == 1 then C ← 0
if S == 1 then
  N ← Rd[31]
  Z ← (Rd == 0)
  V ← V


Summary: Calculates Rd = (Rn * Rm) + Ra.

Multiply Accumulate multiplies Rn and Rm, adds the result to Ra, and stores the 32-bit result in Rd. If the S bit is set, the N and Z flags are updated based on the result; the C and V flags are unpredictable. This is an A32 instruction available in all privilege levels.

product ← Rn * Rm
Rd ← product + Ra
if S == 1 then
  N ← Rd[31]
  Z ← (Rd == 0)
  C ← unpredictable
  V ← unpredictable


Summary: Calculates Rd = Ra - (Rn * Rm).

Multiply Subtract multiplies Rn and Rm, subtracts the product from Ra, and stores the 32-bit result in Rd. The N and Z flags are updated based on the result; the C and V flags are unpredictable. This is an A32 instruction (ARMv6T2 and later) available in all privilege levels.

product ← Rn * Rm
Rd ← Ra - product
N ← Rd[31]
Z ← (Rd == 0)
C ← unpredictable
V ← unpredictable


Summary: Moves a value into a register.

Flexible second operand (register or shifted register)

Move copies the value from Operand2 (a flexible second operand: register, shifted register, or rotated immediate) into Rd. If the S bit is set, the N and Z flags are updated based on the result, and the C flag may be set depending on the operand type. This is an A32 instruction available in all privilege levels.

Rd ← Operand2
if S == 1 then
  N ← Rd[31]
  Z ← (Rd == 0)
  if Operand2_has_shift then C ← Operand2_carry_out
  V ← V


Summary: Writes a 16-bit immediate to the top half of a register.

Move Top writes a 16-bit immediate value into bits [31:16] of Rd while leaving bits [15:0] unchanged. No condition flags are affected. This is an A32 instruction (ARMv6T2 and later) available in all privilege levels.


Summary: Writes a 16-bit immediate to the bottom half, zeroing top.

Move Word writes a 16-bit immediate value into bits [15:0] of Rd and zeros bits [31:16]. No condition flags are affected. This is an A32 instruction (ARMv6T2 and later) available in all privilege levels.


Summary: Reads CPSR or SPSR.

Reads the Current Program Status Register (CPSR) or Saved Program Status Register (SPSR) into a general-purpose register. The R bit in the encoding selects between CPSR (R=0) and SPSR (R=1). No condition flags are affected by this instruction. Execution is restricted to privileged modes when reading SPSR; reading CPSR is available in all modes.

if R == 0 then
  Rd ← CPSR
else
  Rd ← SPSR


Summary: Writes to CPSR or SPSR.

Writes the contents of a general-purpose register to specified fields of the Current Program Status Register (CPSR) or Saved Program Status Register (SPSR). The R bit selects the target register; field specifiers (c, x, s, f) control which bit ranges are updated. Condition flags (N, Z, C, V) may be modified if the f field is selected. Execution in privileged modes is required.

if R == 0 then
  dest ← CPSR
else
  dest ← SPSR
if c then dest[7:0] ← Rn[7:0]
if x then dest[15:8] ← Rn[15:8]
if s then dest[23:16] ← Rn[23:16]
if f then dest[31:24] ← Rn[31:24]
if R == 0 then
  CPSR ← dest
else
  SPSR ← dest


Summary: Multiplies two 32-bit values.

Multiply computes the product of Rn and Rm and stores the low 32 bits in Rd; the high 32 bits are discarded. If the S bit is set, the N and Z flags are updated based on the result; the C and V flags are unpredictable. This is an A32 instruction available in all privilege levels.

product ← Rn * Rm
Rd ← product[31:0]
if S == 1 then
  N ← Rd[31]
  Z ← (Rd == 0)
  C ← unpredictable
  V ← unpredictable


Summary: Moves bitwise inverse of value.

Move NOT computes the bitwise inverse of Operand2 and stores the result in Rd. If the S bit is set, the N and Z flags are updated based on the result, and the C flag may be set depending on the operand type. This is an A32 instruction available in all privilege levels.

Rd ← ~Operand2
if S == 1 then
  N ← Rd[31]
  Z ← (Rd == 0)
  if Operand2_has_shift then C ← Operand2_carry_out
  V ← V


Summary: Does nothing.

Performs no operation and does not modify any registers or memory. Executes in a single cycle and is typically used for instruction alignment or padding. All condition flags (N, Z, C, V) are unaffected. This is an A32 instruction available in all ARM implementations.


Summary: Performs bitwise OR.

Performs a bitwise logical OR between Rn and Operand2, storing the result in Rd. When S=1, updates condition flags: N and Z flags set according to result, C flag set to the carry output of the shifter (or unaffected if no shift), V flag unaffected. This is an A32 data-processing instruction available in all ARM implementations.

result ← Rn | Operand2
Rd ← result
if S == 1 then
  N ← result[31]
  Z ← (result == 0)
  C ← shifter_carry_out
endif


Summary: Loads registers from stack (Alias for LDMIA SP!).

Loads multiple registers from the stack by incrementing SP after each load; equivalent to LDMIA SP!. Increments SP by 4 bytes for each register loaded. All loaded registers are updated; the program counter (PC) may be loaded if included in the register list, causing a branch. This A32 instruction is an alias and operates identically to the corresponding LDMIA instruction.

address ← SP
for each register in register_list (in ascending order)
  register ← [address]
  address ← address + 4
endfor
SP ← address


Summary: Stores registers to stack (Alias for STMDB SP!).

Stores multiple registers to the stack by decrementing SP before each store; equivalent to STMDB SP!. Decrements SP by 4 bytes for each register stored, updating SP to point to the first stored value. All listed registers are written to memory. This A32 instruction is an alias and operates identically to the corresponding STMDB instruction.

address ← SP - (4 × number_of_registers_in_list)
for each register in register_list (in ascending order)
  [address] ← register
  address ← address + 4
endfor
SP ← SP - (4 × number_of_registers_in_list)


Summary: Reverses bits in a 32-bit register.

Reverses the bit order in a 32-bit register, writing the reversed value to the destination. Bit 0 becomes bit 31, bit 1 becomes bit 30, and so on. No condition flags are affected. This instruction requires the ARMv6T2 or later extension.


Summary: Reverses bytes (Endian swap).

Reverses the byte order of a 32-bit value in Rm and stores the result in Rd, performing a little-endian to big-endian (or vice versa) conversion. No condition flags are affected. This is an A32 instruction available in ARMv6 and later; it is a register-to-register operation with no writeback or memory access.


Summary: Rotates register right.

Rotates the value in Rm right by the number of bits specified in Rs[7:0], storing the result in Rd. When S=1, updates condition flags: N and Z flags set according to result, C flag set to the last bit rotated out, V flag unaffected. This is an A32 data-processing instruction; the rotate amount is taken modulo 32.

shift_amount ← Rs[7:0] mod 32
if shift_amount == 0 then
  result ← Rm
  carry_out ← C
else
  result ← (Rm >> shift_amount) | (Rm << (32 - shift_amount))
  carry_out ← Rm[shift_amount - 1]
endif
Rd ← result
if S == 1 then
  N ← result[31]
  Z ← (result == 0)
  C ← carry_out
endif


Summary: Calculates Rd = Operand2 - Rn.

Computes the reverse subtraction Rd = Operand2 - Rn and stores the result in Rd. When S=1, updates condition flags: N and Z flags set according to result, C flag set to the borrow (NOT of the borrow-out), V flag set on signed overflow. This is an A32 data-processing instruction available in all ARM implementations.

result ← Operand2 - Rn
Rd ← result
if S == 1 then
  N ← result[31]
  Z ← (result == 0)
  C ← NOT(Borrow)
  V ← (Operand2[31] != Rn[31]) AND (Operand2[31] != result[31])
endif


Summary: Calculates Rd = Operand2 - Rn - NOT(Carry).

Computes the reverse subtraction with carry: Rd = Operand2 - Rn - NOT(C), and stores the result in Rd. When S=1, updates condition flags: N and Z flags set according to result, C flag set to the borrow (NOT of the borrow-out), V flag set on signed overflow. This is an A32 data-processing instruction useful for multi-word arithmetic.

result ← Operand2 - Rn - NOT(C)
Rd ← result
if S == 1 then
  N ← result[31]
  Z ← (result == 0)
  C ← NOT(Borrow)
  V ← (Operand2[31] != Rn[31]) AND (Operand2[31] != result[31])
endif


Summary: Calculates Rd = Rn - Operand2 - NOT(Carry).

Subtract with Carry subtracts the Operand2 and the inverted Carry flag from Rn, storing the result in Rd. When the S suffix is present, the N, Z, C, and V condition flags are updated based on the result. This instruction is available in A32 (32-bit ARM) and executes conditionally based on the condition code field.

result ← Rn - Operand2 - NOT(C);
Rd ← result;
if S then
  N ← result[31];
  Z ← (result == 0);
  C ← NOT(BorrowFrom(Rn - Operand2 - NOT(C)));
  V ← OverflowFrom(Rn - Operand2 - NOT(C));
endif;


Summary: Signed integer division.

Signed Divide performs signed integer division of Rn (dividend) by Rm (divisor), storing the quotient in Rd. Division by zero does not raise an exception; the result is architecturally unpredictable. No condition flags are modified by this instruction. SDIV is available only in A32 with the Divide extension (ARMv7-R, ARMv7-A with hardware divide).

if Rm == 0 then
  Rd ← UNPREDICTABLE;
else
  Rd ← SignedDivide(Rn, Rm);
endif;


Summary: Stores multiple registers to memory.

cond | 100 | 0 | 0 | 0 | W | 0 | Rn | register_list

Store Multiple stores the registers specified in the register list to consecutive memory addresses starting from the address in Rn. The addressing mode (IA, DB, DA, ED) is encoded in the P and U bits; when W=1, Rn is updated to point past the last stored word. No condition flags are modified. This instruction is available in A32 and includes optional privilege level adjustments when storing the program counter.

address ← Rn;
if P then address ← address + 4 * NumberOfRegisters(); endif;
for i = 0 to 15 do
  if register_list[i] == 1 then
    if U then
      Memory[address] ← Ri;
      address ← address + 4;
    else
      address ← address - 4;
      Memory[address] ← Ri;
    endif;
  endif;
endfor;
if W then Rn ← address; endif;


Summary: Stores a word to memory.

Store Register stores a 32-bit word from Rt to memory at the address computed from Rn and the offset. The offset is an unsigned 12-bit immediate; when U=0 the offset is subtracted. If P=1 (pre-indexed) and W=1 (write-back), Rn is updated; if P=0 (post-indexed), Rn is always updated. No condition flags are modified. Available in A32.

offset ← if U then imm12 else -imm12 endif;
if P then
  address ← Rn + offset;
else
  address ← Rn;
endif;
Memory[address] ← Rt;
if P == 0 or W then
  Rn ← Rn + offset;
endif;


Summary: Subtracts two values.

Subtract subtracts Operand2 from Rn and stores the result in Rd. When the S suffix is present, the N, Z, C, and V condition flags are updated based on the result. This instruction is available in A32 and executes conditionally based on the condition code field.

result ← Rn - Operand2;
Rd ← result;
if S then
  N ← result[31];
  Z ← (result == 0);
  C ← NOT(BorrowFrom(Rn - Operand2));
  V ← OverflowFrom(Rn - Operand2);
endif;


Summary: System call (formerly SWI).

Generates a supervisor call exception, transferring control to the exception handler in supervisor mode. The 24-bit immediate is passed to the exception handler as optional information but does not affect the processor state directly. The instruction saves the return address in LR and updates the PC to the vector address. Condition flags are not modified by the exception itself.

saved_lr ← PC + 4
PC ← SupervisorCallVector
LR_svc ← saved_lr
CPSR.M ← 0b10011  // Supervisor mode


Summary: Atomic swap word (Legacy).

Second transfer register (load/store pair)

Atomically loads a word from memory at [Rn], writes Rt2 to that address, and stores the loaded value in Rt. This is a legacy ARMv5 and earlier instruction; ARMv6 and later code should use LDREX/STREX or LDAEX/STLEX for synchronization. No condition flags are affected. Memory ordering is not guaranteed; for ordered access use SWP with appropriate memory barriers.


Summary: Bitwise Exclusive OR and update flags (discard result).

Performs a bitwise exclusive OR of Rn and Operand2, updates the condition flags based on the result, and discards the result. The N flag is set if bit 31 of the result is 1; Z is set if the result is 0; C is affected by the shifter (if applicable); V is unchanged. This instruction is useful for testing equality of two values.

result ← Rn XOR Operand2
N ← result[31]
Z ← (result == 0)
C ← shifter_carry_out
V ← V  // Unchanged


Summary: Bitwise AND and update flags (discard result).

Performs a bitwise AND of Rn and Operand2, updates the condition flags based on the result, and discards the result. The N flag is set if bit 31 of the result is 1; Z is set if the result is 0; C is affected by the shifter (if applicable); V is unchanged. This instruction is useful for testing which bits are set in a register.

result ← Rn AND Operand2
N ← result[31]
Z ← (result == 0)
C ← shifter_carry_out
V ← V  // Unchanged


Summary: Unsigned integer division.

Unsigned Divide performs unsigned integer division of Rn (dividend) by Rm (divisor), storing the quotient in Rd. Division by zero does not raise an exception; the result is architecturally unpredictable. No condition flags are modified. UDIV is available only in A32 with the Divide extension (ARMv7-R, ARMv7-A with hardware divide).

if Rm == 0 then
  Rd ← UNPREDICTABLE;
else
  Rd ← UnsignedDivide(Rn, Rm);
endif;


Summary: Unsigned (Rn * Rm) + 64-bit Accumulator.

Unsigned multiply of Rn and Rm, then add the 64-bit result to the 64-bit accumulator formed by RdHi:RdLo, storing the result back in RdHi:RdLo. If the S bit is set, the N and Z flags are updated based on the result; C and V are unaffected. This is an A32 instruction and does not execute in AArch64 or T32 states.

accumulator ← (RdHi << 32) | RdLo
product ← (Rn × Rm)
result ← accumulator + product
RdHi ← result[63:32]
RdLo ← result[31:0]
if S == 1 then
  N ← result[63]
  Z ← (result == 0)
endif


Summary: Unsigned (Rn * Rm) -> 64-bit Result.

Unsigned Multiply Long computes the unsigned product Rn × Rm as a 64-bit result, storing the low 32 bits in RdLo and the high 32 bits in RdHi. When the S suffix is present, the N and Z flags are updated based on the result; C and V are unaffected. This instruction is available in A32 and executes conditionally.

result ← Rn[31:0] × Rm[31:0];  // unsigned 64-bit product
RdLo ← result[31:0];
RdHi ← result[63:32];
if S then
  N ← RdHi[31];
  Z ← (result == 0);
endif;


Summary: Shifts elements right and adds to the destination accumulator.

Shifts each element in the source register right by the immediate shift amount and accumulates (adds) the shifted result into the corresponding element of the destination register. The shift amount is treated as unsigned. No condition flags are modified. This is a NEON instruction available in both A32 and T32 instruction sets.

for i = 0 to elements_in_Qd - 1
  shift_amount ← imm6
  shifted ← Qm[i] >> shift_amount
  Qd[i] ← Qd[i] + shifted
endfor


Vector Rounding Shift Right and Accumulate

Summary: Shifts right with rounding and adds to accumulator.

Shifts each element in the source register right by the immediate shift amount with rounding (adding 1 to bit position before the round point), then accumulates the rounded result into the destination register. The shift amount is unsigned. No condition flags are modified. This is a NEON instruction available in both A32 and T32 instruction sets.

for i = 0 to elements_in_Qd - 1
  shift_amount ← imm6
  if shift_amount > 0 then
    rounded ← (Qm[i] + (1 << (shift_amount - 1))) >> shift_amount
  else
    rounded ← Qm[i]
  endif
  Qd[i] ← Qd[i] + rounded
endfor


Summary: Shifts bits left and inserts into destination (merging).

Shifts each element in the source register left by the immediate shift amount and inserts the shifted bits into the low bits of the destination element, leaving the high bits of the destination unchanged (merging operation). The shift amount is unsigned. No condition flags are modified. This is a NEON instruction available in both A32 and T32 instruction sets.

for i = 0 to elements_in_Qd - 1
  shift_amount ← imm6
  shifted ← Qm[i] << shift_amount
  mask ← (1 << shift_amount) - 1
  Qd[i] ← (Qd[i] & ~mask) | (shifted & mask)
endfor


Summary: Shifts bits right and inserts into destination.

Shifts each element in the source register right by the immediate shift amount and inserts the shifted bits into the high bits of the destination element, leaving the low bits of the destination unchanged (merging operation). The shift amount is unsigned. No condition flags are modified. This is a NEON instruction available in both A32 and T32 instruction sets.

for i = 0 to elements_in_Qd - 1
  shift_amount ← imm6
  shifted ← Qm[i] >> shift_amount
  mask ← ((1 << (element_size - shift_amount)) - 1) << shift_amount
  Qd[i] ← (Qd[i] & ~mask) | (shifted & mask)
endfor


Summary: Shifts left with rounding based on a register value.

Shifts each element in Qm left or right by the amount specified in the corresponding element of Qn with rounding applied when shifting right. Positive shift amounts shift left; negative amounts shift right with rounding. Results are stored in Qd. No condition flags are modified. This is a NEON instruction available in both A32 and T32 instruction sets.

for i = 0 to elements_in_Qd - 1
  shift_amount ← signed(Qn[i])
  if shift_amount >= 0 then
    Qd[i] ← Qm[i] << shift_amount
  else
    if shift_amount <= -element_size then
      Qd[i] ← 0
    else
      rounded ← Qm[i] + (1 << (-shift_amount - 1))
      Qd[i] ← rounded >> (-shift_amount)
    endif
  endif
endfor


Summary: Shifts right with rounding based on immediate.

Shifts each element in the source register right by the immediate shift amount with rounding (the bit at the shift position and all bits to the right are rounded according to ARM rounding rules). Results are stored in the destination register. No condition flags are modified. This is a NEON instruction available in both A32 and T32 instruction sets.

for i = 0 to elements_in_Qd - 1
  shift_amount ← imm6
  if shift_amount >= element_size then
    Qd[i] ← 0
  else
    rounding_bit ← (Qm[i] >> (shift_amount - 1)) & 1
    Qd[i] ← (Qm[i] >> shift_amount) + rounding_bit
  endif
endfor


Summary: Shifts right, rounds, and narrows (2N -> N bits).

Shifts each element of the 128-bit source register right by the immediate shift amount with rounding, then narrows the result from 2N bits to N bits (halving the element width), and stores into the 64-bit destination register. The high half of the shift result is kept. No condition flags are modified. This is a NEON instruction available in both A32 and T32 instruction sets.

for i = 0 to elements_in_Dd - 1
  shift_amount ← imm6
  if shift_amount > 2 × element_size then
    Dd[i] ← 0
  else
    value ← Qm[i]
    rounding_correction ← (1 << (shift_amount - 1))
    rounded ← (value + rounding_correction) >> shift_amount
    Dd[i] ← saturate(rounded, element_size / 2)
  endif
endfor


Summary: Shifts left with saturation based on register.

Vector Saturating Shift Left (Register) shifts each element in Qm left by the amount specified by the corresponding element in Qn, saturating the result to the range of the operand data type. The shift amount is interpreted as a signed value; negative amounts perform a right shift. All condition flags (N, Z, C, V) remain unaffected. This is an A32/T32 NEON instruction that operates on 128-bit quad registers.

for i = 0 to elements-1 do
  shift_amount ← SignExtend(Qn[i])
  if shift_amount >= 0 then
    result ← SatQ(Qm[i] << shift_amount, esize)
  else
    result ← SatQ(Qm[i] >> (-shift_amount), esize)
  Qd[i] ← result


Summary: Shifts left with saturation based on immediate.

Vector Saturating Shift Left (Immediate) shifts each element in Qm left by an immediate value, saturating the result to the range of the operand data type. The immediate is a signed value encoded in imm6; positive values shift left, negative values (when sign-extended) would shift right. All condition flags (N, Z, C, V) remain unaffected. This is an A32/T32 NEON instruction.

shift_amount ← SignExtend(imm6, 6)
for i = 0 to elements-1 do
  result ← SatQ(Qm[i] << shift_amount, esize)
  Qd[i] ← result


Summary: Shifts right with saturation (Unsigned).

Vector Saturating Shift Right (Unsigned) shifts each unsigned element in Qm right by an immediate value, saturating underflow to zero. The immediate specifies the right shift count. All condition flags (N, Z, C, V) remain unaffected. This is an A32/T32 NEON instruction for unsigned data types.

shift_amount ← imm6
for i = 0 to elements-1 do
  if shift_amount > 0 then
    result ← SatQ(Qm[i] >> shift_amount, 0, max_unsigned_value)
  else
    result ← Qm[i]
  Qd[i] ← result


Summary: Shifts right, saturates, and narrows.

Vector Saturating Shift Right Narrow shifts each element in Qm right by an immediate value, saturates to the range of the narrower result type, then packs the narrowed results into the destination Dd. This operation reduces element size by half and narrows the register from 128-bit to 64-bit. All condition flags (N, Z, C, V) remain unaffected. This is an A32/T32 NEON instruction.

shift_amount ← imm6
for i = 0 to narrow_elements-1 do
  wide_value ← Qm[i]
  shifted ← wide_value >> shift_amount
  result ← SatQ(shifted, narrow_esize)
  Dd[i] ← result


Summary: Shifts signed elements left, saturating to unsigned result.

Vector Saturating Shift Left Unsigned shifts each signed element in Qm left by an immediate value and saturates the result to an unsigned range. Elements that overflow are clamped to the maximum unsigned value of the result type. All condition flags (N, Z, C, V) remain unaffected. This is an A32/T32 NEON instruction.

shift_amount ← imm6
for i = 0 to elements-1 do
  result ← SatQ(Qm[i] << shift_amount, 0, max_unsigned_value)
  Qd[i] ← result


Summary: Shifts left with saturation and rounding.

Vector Saturating Rounding Shift Left shifts each element in Qm left by the amount specified in the corresponding element of Qn, with saturation and rounding applied. When the shift amount is negative, a right shift with rounding is performed. All condition flags (N, Z, C, V) remain unaffected. This is an A32/T32 NEON instruction.

for i = 0 to elements-1 do
  shift_amount ← SignExtend(Qn[i])
  if shift_amount >= 0 then
    result ← SatQ(Qm[i] << shift_amount, esize)
  else
    rounding_bit ← Qm[i][(-shift_amount-1)]
    shifted ← Qm[i] >> (-shift_amount)
    result ← SatQ(shifted + rounding_bit, esize)
  Qd[i] ← result


Summary: Shifts right, saturates, rounds, and narrows.

Vector Saturating Rounding Shift Right Narrow shifts each element in Qm right by an immediate value with rounding, saturates to the narrower result type, and packs the narrowed results into Dd. Rounding is applied before truncation and narrowing. This reduces element size by half and narrows the register from 128-bit to 64-bit. All condition flags (N, Z, C, V) remain unaffected. This is an A32/T32 NEON instruction.

shift_amount ← imm6
for i = 0 to narrow_elements-1 do
  wide_value ← Qm[i]
  rounding_bit ← wide_value[shift_amount-1]
  shifted ← wide_value >> shift_amount
  rounded ← shifted + rounding_bit
  result ← SatQ(rounded, narrow_esize)
  Dd[i] ← result


Summary: Compares absolute values (|Vn| >= |Vm|).

Vector Absolute Compare Greater or Equal compares the absolute values of corresponding floating-point elements in Qn and Qm, setting each element in Qd to all 1s (true) if |Qn[i]| >= |Qm[i]|, or all 0s (false) otherwise. The comparison is per-element on 32-bit floating-point values. All condition flags (N, Z, C, V) remain unaffected. This is an A32/T32 NEON floating-point instruction.

for i = 0 to elements-1 do
  if FPAbs(Qn[i]) >= FPAbs(Qm[i]) then
    Qd[i] ← 0xFFFFFFFF
  else
    Qd[i] ← 0x00000000


Summary: Compares absolute values (|Vn| > |Vm|).

Performs a vector absolute comparison of floating-point elements, setting each element of the destination to all 1s if |Vn| > |Vm|, otherwise 0s. This is a NEON floating-point comparison that operates on F32 elements in 128-bit registers. No condition flags are modified; the result is a per-element mask stored in the destination register.

for i = 0 to 3
  if abs(Qn[i]) > abs(Qm[i]) then
    Qd[i] ← 0xFFFFFFFF
  else
    Qd[i] ← 0x00000000


Vector Absolute Difference and Accumulate Long

Summary: Computes absolute difference of narrow elements and adds to wide acc.

Computes the absolute difference of narrow elements from two double-width registers and accumulates (adds) the widened result to a quad-width accumulator register. The operand size is determined by the data type specifier (sz field controls .I8, .I16, or .I32 variants). No condition flags are affected; saturation may occur and set the QC flag if enabled.

for i = 0 to (64 / esize - 1)
  diff ← abs(Dn[i] - Dm[i])
  Qd[i] ← Qd[i] + diff_widened


Summary: Computes absolute difference of narrow elements to wide result.

Computes the absolute difference of narrow elements from two double-width registers and widens the result to quad-width. The operand size is determined by the data type specifier (sz field controls .I8, .I16, or .I32 variants). No condition flags are affected; the result is written to the destination without saturation.

for i = 0 to (64 / esize - 1)
  diff ← abs(Dn[i] - Dm[i])
  Qd[i] ← diff_widened


Summary: Adds wide elements, rounds, and returns high narrow half.

Adds corresponding wide elements from two quad-width registers, applies rounding (round to nearest, ties to even), and returns the high half of each widened result as narrow elements in a double-width destination. The operand size is determined by the data type specifier (sz field controls .I16, .I32, or .I64 variants). No condition flags are affected.

for i = 0 to (128 / (esize * 2) - 1)
  sum ← Qn[i] + Qm[i]
  rounded ← sum + (1 << (esize - 1))
  Dd[i] ← (rounded >> esize)[esize - 1:0]


Summary: Subtracts wide elements and returns high narrow half.

Subtracts wide elements of the second quad-width register from the first, and returns the high half of the result as narrow elements in a double-width destination. The operand size is determined by the data type specifier (sz field controls .I16, .I32, or .I64 variants). No condition flags are affected; no rounding is applied.

for i = 0 to (128 / (esize * 2) - 1)
  diff ← Qn[i] - Qm[i]
  Dd[i] ← (diff >> esize)[esize - 1:0]


Summary: Subtracts wide elements, rounds, and returns high narrow half.

Subtracts wide elements of the second quad-width register from the first, applies rounding (round to nearest), and returns the high half of the result as narrow elements in a double-width destination. The operand size is determined by the data type specifier (sz field controls .I16, .I32, or .I64 variants). No condition flags are affected.

for i = 0 to (128 / (esize * 2) - 1)
  diff ← Qn[i] - Qm[i]
  rounded ← diff + (1 << (esize - 1))
  Dd[i] ← (rounded >> esize)[esize - 1:0]


Vector Saturating Doubling Multiply Accumulate Long

Summary: Multiplies, doubles, saturates, and adds to accumulator (High precision DSP).

Performs a saturating doubling multiply of corresponding narrow elements, then accumulates (adds) the doubled products to a quad-width destination register. The multiplication is doubled with saturation; the operand size is determined by the data type specifier (sz field controls .S16 or .S32 variants). The QC (saturation) flag may be set if overflow occurs during doubling or accumulation.

for i = 0 to (64 / esize - 1)
  product ← Dn[i] * Dm[i]
  doubled ← SatMul(product, 2)  ; saturating double
  Qd[i] ← SatAdd(Qd[i], doubled)


Vector Saturating Doubling Multiply Subtract Long

Summary: Multiplies, doubles, saturates, and subtracts from accumulator.

Performs a saturating doubling multiply of corresponding narrow elements, then subtracts the doubled products from a quad-width destination register. The multiplication is doubled with saturation; the operand size is determined by the data type specifier (sz field controls .S16 or .S32 variants). The QC (saturation) flag may be set if overflow occurs during doubling or subtraction.

for i = 0 to (64 / esize - 1)
  product ← Dn[i] * Dm[i]
  doubled ← SatMul(product, 2)  ; saturating double
  Qd[i] ← SatSub(Qd[i], doubled)


Vector Saturating Doubling Multiply High

Summary: Multiplies, doubles, saturates, and keeps high half.

Performs signed fixed-point saturating doubling multiply on NEON vector elements, returning the high half of the doubled result. Each element in Qn is multiplied by the corresponding element in Qm, the result is doubled, saturated to the data type range, and the high half is written to Qd. The NEON condition flags are not affected; saturation is indicated via the FPSCR QC bit if the result overflows.

for i = 0 to elements_in_128bit(dt) - 1 do
  product ← (Qn[i] * Qm[i]) * 2
  Qd[i] ← SignedSaturate(product, dt)
FPSCR.QC ← FPSCR.QC OR (product overflowed)


Vector Saturating Rounding Doubling Multiply High

Summary: Fixed-point multiply with rounding and saturation.

Performs signed fixed-point saturating rounding doubling multiply on NEON vector elements, returning the high half with rounding. Each element in Qn is multiplied by the corresponding element in Qm, the result is doubled with rounding applied (via addition of 0x80000000 for 32-bit or 0x8000 for 16-bit before right-shift), saturated to the data type range, and the high half is written to Qd. The NEON condition flags are not affected; saturation is indicated via the FPSCR QC bit.

for i = 0 to elements_in_128bit(dt) - 1 do
  product ← (Qn[i] * Qm[i]) * 2
  if dt == S32 then
    product ← (product + 0x80000000) >> 32
  else
    product ← (product + 0x8000) >> 16
  Qd[i] ← SignedSaturate(product, dt)
FPSCR.QC ← FPSCR.QC OR (saturation occurred)


Vector Saturating Doubling Multiply Long

Summary: Multiplies narrow elements, doubles, and saturates into wide elements.

Performs signed fixed-point saturating doubling multiply long on NEON vectors, widening narrow elements to double-width results. Each element in Dn is multiplied by the corresponding element in Dm, the result is doubled, saturated to the wider data type range, and written to the corresponding location in Qd. The NEON condition flags are not affected; saturation is indicated via the FPSCR QC bit.

for i = 0 to elements_in_64bit(dt) - 1 do
  product ← (Dn[i] * Dm[i]) * 2
  Qd[i] ← SignedSaturate(product, widen(dt))
FPSCR.QC ← FPSCR.QC OR (saturation occurred)


Summary: Sign-extends a byte from Rm and adds to Rn.

SXTAB<c> <Rd>, <Rn>, <Rm> {, <rotation>}

Sign-extends the least significant byte of Rm (optionally rotated), adds it to Rn, and writes the result to Rd. This is an A32 instruction that operates on general-purpose registers and does not affect the condition flags. The rotation parameter is optional (ROR by 0, 8, 16, or 24 bits before sign-extension).

rotated ← ROR(Rm, rotation)
byte_value ← rotated[7:0]
sign_extended ← SignExtend(byte_value, 32)
Rd ← Rn + sign_extended


Summary: Sign-extends two bytes and adds to two halfwords.

SXTAB16<c> <Rd>, <Rn>, <Rm> {, <rotation>}

Sign-extends the least significant byte and the most significant byte of the low halfword from Rm (optionally rotated), adds them separately to the two halfwords of Rn, and writes the results to Rd. This is an A32 instruction that operates on general-purpose registers and does not affect the condition flags. Useful for parallel byte-to-halfword sign-extension and accumulation.

rotated ← ROR(Rm, rotation)
byte0 ← rotated[7:0]
byte1 ← rotated[15:8]
sign_ext0 ← SignExtend(byte0, 16)
sign_ext1 ← SignExtend(byte1, 16)
Rd[15:0] ← Rn[15:0] + sign_ext0
Rd[31:16] ← Rn[31:16] + sign_ext1


Summary: Sign-extends a halfword and adds to Rn.

SXTAH<c> <Rd>, <Rn>, <Rm> {, <rotation>}

Sign-extends the least significant halfword of Rm (optionally rotated), adds it to Rn, and writes the result to Rd. This is an A32 instruction that operates on general-purpose registers and does not affect the condition flags. The rotation parameter is optional (ROR by 0, 8, 16, or 24 bits before sign-extension).

rotated ← ROR(Rm, rotation)
halfword_value ← rotated[15:0]
sign_extended ← SignExtend(halfword_value, 32)
Rd ← Rn + sign_extended


Summary: Zero-extends a byte and adds to Rn.

UXTAB<c> <Rd>, <Rn>, <Rm> {, <rotation>}

Zero-extends the least significant byte of Rm (optionally rotated), adds it to Rn, and writes the result to Rd. This is an A32 instruction that operates on general-purpose registers and does not affect the condition flags. The rotation parameter is optional (ROR by 0, 8, 16, or 24 bits before zero-extension).

rotated ← ROR(Rm, rotation)
byte_value ← rotated[7:0]
zero_extended ← ZeroExtend(byte_value, 32)
Rd ← Rn + zero_extended


Summary: Zero-extends two bytes and adds to two halfwords.

UXTAB16<c> <Rd>, <Rn>, <Rm> {, <rotation>}

Zero-extends the least significant byte and the most significant byte of the low halfword from Rm (optionally rotated), adds them separately to the two halfwords of Rn, and writes the results to Rd. This is an A32 instruction that operates on general-purpose registers and does not affect the condition flags. Useful for parallel byte-to-halfword zero-extension and accumulation.

rotated ← ROR(Rm, rotation)
byte0 ← rotated[7:0]
byte1 ← rotated[15:8]
zero_ext0 ← ZeroExtend(byte0, 16)
zero_ext1 ← ZeroExtend(byte1, 16)
Rd[15:0] ← Rn[15:0] + zero_ext0
Rd[31:16] ← Rn[31:16] + zero_ext1


Summary: Zero-extends a halfword and adds to Rn.

UXTAH<c> <Rd>, <Rn>, <Rm> {, <rotation>}

Zero-extends a halfword (16-bit) from Rm, optionally rotates it by 0, 8, 16, or 24 bits, and adds the result to Rn, storing the sum in Rd. The instruction executes conditionally based on the condition code and does not update the condition flags. This is an A32 DSP extension instruction.

rotated ← ROR(Rm, rotation)
extended ← ZeroExtend(rotated[15:0], 32)
Rd ← Rn + extended


Summary: Performs two 16x16 multiplies and adds results (Top*Top + Bot*Bot).

Multiplies two pairs of signed 16-bit values: (Rn[31:16] × Rm[31:16]) + (Rn[15:0] × Rm[15:0]), storing the 32-bit signed result in Rd. The {X} variant swaps the operands of one multiply. The instruction does not update condition flags. A32 DSP extension only.

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


Summary: Performs two 16x16 multiplies and subtracts results.

Multiplies two pairs of signed 16-bit values and subtracts: (Rn[31:16] × Rm[31:16]) - (Rn[15:0] × Rm[15:0]), storing the 32-bit signed result in Rd. The {X} variant swaps the operands of one multiply. The instruction does not update condition flags. A32 DSP extension only.

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


Summary: Dual multiply add + accumulate.

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.

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