Introduction
Advanced SIMD, usually called NEON, works on vectors held in the 32 registers V0 to V31.
A vector is 64 or 128 bits wide and is divided into equal elements. The suffix on a
register gives the shape: .8b and .16b for bytes,
.4h and .8h for 16-bit halfwords, .2s and
.4s for 32-bit words, .1d and .2d for 64-bit
doublewords.
Unless a row says otherwise, an instruction applies its operation to each element separately, and the rows below do not repeat this. The Syntax column shows one arrangement; the row names the element sizes that exist, as B, H, S and D. A write to a 64-bit vector clears the top half of the V register.
- The 2 suffix. Widening and narrowing instructions come in pairs.
The plain form uses the lower half of its narrow operand. The form ending in
2uses the upper half. A narrowing2form writes to the upper half of the destination and keeps the lower half. - Scalar forms. “Scalar: D” at the end of a row means the instruction
also exists on a single value in that register size, for example
add d0, d1, d2. A row with no such note has no scalar form. - Saturation. A saturating instruction clamps to the limit of the result type, and sets the sticky FPSR.QC bit if it did.
- Half precision. Floating-point arithmetic on H elements needs the FP16 extension.
No instruction on this page changes NZCV, so the Flags column is a dash throughout. Floating-point instructions record exceptions in FPSR, as the Floating point page describes.
The instructions
Integer arithmetic
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
add, sub | add Vd.8b, Vn.8b, Vm.8b | Add; subtract. B, H, S, D. Scalar: D. | – |
addp | addp Vd.8b, Vn.8b, Vm.8b; addp Dd, Vn.2d | Adds adjacent pairs: Vn’s pairs give the lower half of the result, Vm’s the upper. B, H, S, D. Scalar: D, adding the two elements of Vn. | – |
addv | addv Bd, Vn.8b | Adds all the elements of Vn into one scalar. B, H, S (not .2s). | – |
saddlv, uaddlv | saddlv Hd, Vn.8b | Adds all the elements, signed or unsigned, into one scalar of twice the size. B, H, S (not .2s). | – |
saddlp, uaddlp | saddlp Vd.4h, Vn.8b | Adds adjacent pairs into elements of twice the size. B, H, S. | – |
sadalp, uadalp | sadalp Vd.4h, Vn.8b | Adds adjacent pairs and accumulates into Vd. B, H, S. | – |
mul, mla, mls | mla Vd.8b, Vn.8b, Vm.8b | Multiply; multiply and add to Vd; multiply and subtract from Vd. The low half of each product is kept. B, H, S. | – |
pmul | pmul Vd.8b, Vn.8b, Vm.8b | Carry-less (polynomial) multiply, keeping the low half. B only. | – |
shadd, uhadd | shadd Vd.8b, Vn.8b, Vm.8b | Halving add, signed or unsigned, rounding down. B, H, S. | – |
srhadd, urhadd | srhadd Vd.8b, Vn.8b, Vm.8b | Halving add, rounding up. B, H, S. | – |
shsub, uhsub | shsub Vd.8b, Vn.8b, Vm.8b | Halving subtract, rounding down. B, H, S. | – |
sqadd, uqadd, sqsub, uqsub | sqadd Vd.8b, Vn.8b, Vm.8b | Saturating add or subtract, signed or unsigned. B, H, S, D. Scalar: B, H, S, D. | – |
suqadd, usqadd | suqadd Vd.8b, Vn.8b | Saturating accumulate into Vd: suqadd adds an unsigned Vn to a signed Vd, usqadd a signed Vn to an unsigned Vd. B, H, S, D. Scalar: B, H, S, D. | – |
sabd, uabd | sabd Vd.8b, Vn.8b, Vm.8b | Absolute difference, signed or unsigned. B, H, S. | – |
saba, uaba | saba Vd.8b, Vn.8b, Vm.8b | Absolute difference, accumulated into Vd. B, H, S. | – |
smax, smin, umax, umin | smax Vd.8b, Vn.8b, Vm.8b | The larger or smaller element, signed or unsigned. B, H, S. | – |
smaxp, sminp, umaxp, uminp | smaxp Vd.8b, Vn.8b, Vm.8b | Maximum or minimum of adjacent pairs. B, H, S. | – |
smaxv, sminv, umaxv, uminv | smaxv Bd, Vn.8b | Maximum or minimum of all the elements, as one scalar. B, H, S (not .2s). | – |
abs, neg | abs Vd.8b, Vn.8b | Absolute value; negate. B, H, S, D. Scalar: D. | – |
sqabs, sqneg | sqabs Vd.8b, Vn.8b | Saturating absolute value; saturating negate. B, H, S, D. Scalar: B, H, S, D. | – |
sqdmulh, sqrdmulh | sqdmulh Vd.4h, Vn.4h, Vm.4h | Multiplies, doubles and keeps the high half, saturating; sqrdmulh rounds as well. H, S. Scalar: H, S. | – |
sqrdmlah, sqrdmlsh | sqrdmlah Vd.4h, Vn.4h, Vm.4h | Like sqrdmulh, but adds the result to Vd or subtracts it from Vd. H, S. Scalar: H, S. | – |
Logic and bit operations
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
and, eor, orn | and Vd.8b, Vn.8b, Vm.8b | Bitwise AND; XOR; OR with the complement of Vm. .8b and .16b. | – |
orr, bic | orr Vd.8b, Vn.8b, Vm.8b; orr Vd.4h, #imm, lsl #8 | Bitwise OR; AND with the complement of Vm. Each also has an immediate form, applied to H or S elements. When both sources of orr are the same register, it is printed as mov. | – |
mvn | mvn Vd.8b, Vn.8b | Bitwise NOT. | – |
bsl | bsl Vd.8b, Vn.8b, Vm.8b | Bitwise select. Vd is the mask: each 1 takes the bit from Vn, each 0 from Vm. | – |
bit, bif | bit Vd.8b, Vn.8b, Vm.8b | Vm is the mask. bit copies bits of Vn into Vd where the mask is 1; bif where it is 0. | – |
cls, clz | clz Vd.8b, Vn.8b | Counts leading sign bits; counts leading zeros. B, H, S. | – |
cnt | cnt Vd.8b, Vn.8b | Counts the set bits in each byte. | – |
rbit | rbit Vd.8b, Vn.8b | Reverses the bits in each byte. | – |
Comparisons
Each result element is all ones if the comparison holds and all zeros if not.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
cmeq | cmeq Vd.8b, Vn.8b, Vm.8b; cmeq Vd.8b, Vn.8b, #0 | Equal. B, H, S, D. Scalar: D. | – |
cmge, cmgt | cmge Vd.8b, Vn.8b, Vm.8b; cmge Vd.8b, Vn.8b, #0 | Signed greater than or equal; greater than. B, H, S, D. Scalar: D. | – |
cmhs, cmhi | cmhs Vd.8b, Vn.8b, Vm.8b | Unsigned higher or same; higher. B, H, S, D. Scalar: D. | – |
cmle, cmlt | cmle Vd.8b, Vn.8b, #0 | Signed less than or equal to zero; less than zero. Compare with zero only. B, H, S, D. Scalar: D. | – |
cmtst | cmtst Vd.8b, Vn.8b, Vm.8b | True where Vn AND Vm is non-zero. B, H, S, D. Scalar: D. | – |
fcmeq, fcmge, fcmgt | fcmeq Vd.2s, Vn.2s, Vm.2s; fcmeq Vd.2s, Vn.2s, #0.0 | Floating-point equal; greater than or equal; greater than. H, S, D. Scalar: H, S, D. | – |
fcmle, fcmlt | fcmle Vd.2s, Vn.2s, #0.0 | Less than or equal to zero; less than zero. Compare with zero only. H, S, D. Scalar: H, S, D. | – |
facge, facgt | facge Vd.2s, Vn.2s, Vm.2s | Compares absolute values: greater than or equal; greater than. H, S, D. Scalar: H, S, D. | – |
Widening and narrowing
Widening results have elements twice the size of the source; narrowing results have elements half the size. Widening and narrowing shifts are in the next table.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
saddl, saddl2, uaddl, uaddl2 | saddl Vd.8h, Vn.8b, Vm.8b | Widens both sources, signed or unsigned, and adds. Sources B, H, S. | – |
ssubl, ssubl2, usubl, usubl2 | ssubl Vd.8h, Vn.8b, Vm.8b | Widens both sources and subtracts. Sources B, H, S. | – |
saddw, saddw2, uaddw, uaddw2 | saddw Vd.8h, Vn.8h, Vm.8b | Widens Vm and adds it to the wide Vn. Sources B, H, S. | – |
ssubw, ssubw2, usubw, usubw2 | ssubw Vd.8h, Vn.8h, Vm.8b | Widens Vm and subtracts it from the wide Vn. Sources B, H, S. | – |
sabdl, sabdl2, uabdl, uabdl2 | sabdl Vd.8h, Vn.8b, Vm.8b | Absolute difference, widened. Sources B, H, S. | – |
sabal, sabal2, uabal, uabal2 | sabal Vd.8h, Vn.8b, Vm.8b | Absolute difference, widened and accumulated into Vd. Sources B, H, S. | – |
smull, smull2, umull, umull2 | smull Vd.8h, Vn.8b, Vm.8b | Multiplies, keeping the full-width product. Sources B, H, S. | – |
smlal, smlal2, umlal, umlal2 | smlal Vd.8h, Vn.8b, Vm.8b | Widening multiply, added to Vd. Sources B, H, S. | – |
smlsl, smlsl2, umlsl, umlsl2 | smlsl Vd.8h, Vn.8b, Vm.8b | Widening multiply, subtracted from Vd. Sources B, H, S. | – |
pmull, pmull2 | pmull Vd.8h, Vn.8b, Vm.8b | Carry-less (polynomial) widening multiply of bytes. The 64-bit forms are on the Cryptography page. | – |
sqdmull, sqdmull2 | sqdmull Vd.4s, Vn.4h, Vm.4h | Signed multiply, doubled and saturated, at full width. Sources H, S. Scalar: H and S sources (sqdmull only). | – |
sqdmlal, sqdmlal2, sqdmlsl, sqdmlsl2 | sqdmlal Vd.4s, Vn.4h, Vm.4h | The same product added to Vd or subtracted from Vd, saturating. Sources H, S. Scalar: H and S sources (no 2 forms). | – |
xtn, xtn2 | xtn Vd.8b, Vn.8h | Narrows, keeping the low half of each element. Sources H, S, D. | – |
sqxtn, sqxtn2, uqxtn, uqxtn2 | sqxtn Vd.8b, Vn.8h | Saturating narrow, signed or unsigned. Sources H, S, D. Scalar: H, S and D sources (no 2 forms). | – |
sqxtun, sqxtun2 | sqxtun Vd.8b, Vn.8h | Saturating narrow from signed to unsigned. Sources H, S, D. Scalar: H, S and D sources (sqxtun only). | – |
addhn, addhn2, subhn, subhn2 | addhn Vd.8b, Vn.8h, Vm.8h | Adds or subtracts and keeps the high half of each result. Sources H, S, D. | – |
raddhn, raddhn2, rsubhn, rsubhn2 | raddhn Vd.8b, Vn.8h, Vm.8h | The same, rounding before the high half is taken. Sources H, S, D. | – |
Shifts
The register forms shift by the signed value in the bottom byte of each element of Vm: positive to the left, negative to the right.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
sshl, ushl | sshl Vd.8b, Vn.8b, Vm.8b | Shift by register, signed or unsigned. B, H, S, D. Scalar: D. | – |
srshl, urshl | srshl Vd.8b, Vn.8b, Vm.8b | The same, rounding right shifts. B, H, S, D. Scalar: D. | – |
sqshl, uqshl | sqshl Vd.8b, Vn.8b, Vm.8b; sqshl Vd.8b, Vn.8b, #imm | Saturating shift left, by register or immediate. B, H, S, D. Scalar: B, H, S, D. | – |
sqrshl, uqrshl | sqrshl Vd.8b, Vn.8b, Vm.8b | Saturating rounding shift by register. B, H, S, D. Scalar: B, H, S, D. | – |
sqshlu | sqshlu Vd.8b, Vn.8b, #imm | Saturating shift left of a signed value to an unsigned result. B, H, S, D. Scalar: B, H, S, D. | – |
shl | shl Vd.8b, Vn.8b, #imm | Shift left by immediate. B, H, S, D. Scalar: D. | – |
sshr, ushr | sshr Vd.8b, Vn.8b, #imm | Shift right by immediate, arithmetic or logical. B, H, S, D. Scalar: D. | – |
srshr, urshr | srshr Vd.8b, Vn.8b, #imm | Rounding shift right. B, H, S, D. Scalar: D. | – |
ssra, usra | ssra Vd.8b, Vn.8b, #imm | Shift right and add to Vd. B, H, S, D. Scalar: D. | – |
srsra, ursra | srsra Vd.8b, Vn.8b, #imm | Rounding shift right and add to Vd. B, H, S, D. Scalar: D. | – |
sli, sri | sli Vd.8b, Vn.8b, #imm | Shift left or right and insert: the shifted bits of Vn replace those bits of Vd, and the other bits of Vd stay. B, H, S, D. Scalar: D. | – |
sshll, sshll2, ushll, ushll2 | sshll Vd.8h, Vn.8b, #imm | Widens, signed or unsigned, then shifts left. The immediate can be 0. Sources B, H, S. | – |
shll, shll2 | shll Vd.8h, Vn.8b, #8 | Widens and shifts left by exactly the source element size. Sources B, H, S. | – |
shrn, shrn2 | shrn Vd.8b, Vn.8h, #imm | Shifts right and narrows, keeping the low half. Sources H, S, D. | – |
rshrn, rshrn2 | rshrn Vd.8b, Vn.8h, #imm | The same, rounding. Sources H, S, D. | – |
sqshrn, sqshrn2, uqshrn, uqshrn2 | sqshrn Vd.8b, Vn.8h, #imm | Saturating shift right and narrow, signed or unsigned. Sources H, S, D. Scalar: H, S and D sources (no 2 forms). | – |
sqrshrn, sqrshrn2, uqrshrn, uqrshrn2 | sqrshrn Vd.8b, Vn.8h, #imm | The same, rounding. Sources H, S, D. Scalar: H, S and D sources (no 2 forms). | – |
sqshrun, sqshrun2 | sqshrun Vd.8b, Vn.8h, #imm | Saturating shift right and narrow, signed to unsigned. Sources H, S, D. Scalar: H, S and D sources (sqshrun only). | – |
sqrshrun, sqrshrun2 | sqrshrun Vd.8b, Vn.8h, #imm | The same, rounding. Sources H, S, D. Scalar: H, S and D sources (sqrshrun only). | – |
Moves and permutes
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
mov | mov Vd.16b, Vn.16b; mov Vd.b[i], Wn; mov Vd.b[i], Vn.b[j]; mov Bd, Vn.b[i]; mov Wd, Vn.s[i]; mov Xd, Vn.d[i] | Copies a whole register; or sets one element from a general-purpose register or another element, leaving the rest; or copies an element to a scalar register; or moves a word or doubleword element to W or X. These are aliases: the architecture’s names are ORR, INS, DUP (scalar) and UMOV. | – |
movi | movi Vd.2s, #imm; movi Vd.2d, #imm; movi Dd, #imm | Fills each element with an immediate. B, H, S elements take an 8-bit value, with a shift for H and S. The D forms take a 64-bit value whose bytes are each 0x00 or 0xFF. Scalar: D. | – |
mvni | mvni Vd.2s, #imm | Fills each element with the complement of a shifted 8-bit immediate. H, S. | – |
dup | dup Vd.8b, Vn.b[i]; dup Vd.8b, Wn | Copies one element, or a general-purpose register, to every element. X sources are for .2d. B, H, S, D. The scalar form exists and is printed as mov. | – |
smov | smov Wd, Vn.b[i]; smov Xd, Vn.s[i] | Copies an element to a general-purpose register, sign-extended. B and H to W or X; S to X. | – |
umov | umov Wd, Vn.b[i] | Copies an element to W, zero-extended. B, H. S and D elements are printed as mov. | – |
ext | ext Vd.8b, Vn.8b, Vm.8b, #imm | Joins Vn and Vm as one vector, with Vn lowest, and takes a run of bytes starting at byte #imm. | – |
trn1, trn2 | trn1 Vd.8b, Vn.8b, Vm.8b | Interleaves the even-numbered (trn1) or odd-numbered (trn2) elements of Vn and Vm. B, H, S, D. | – |
uzp1, uzp2 | uzp1 Vd.8b, Vn.8b, Vm.8b | Takes the even-numbered or odd-numbered elements of Vn, then the same of Vm. B, H, S, D. | – |
zip1, zip2 | zip1 Vd.8b, Vn.8b, Vm.8b | Interleaves the lower halves (zip1) or upper halves (zip2) of Vn and Vm. B, H, S, D. | – |
rev16 | rev16 Vd.8b, Vn.8b | Reverses the bytes in each 16-bit unit. B. | – |
rev32 | rev32 Vd.8b, Vn.8b | Reverses the elements in each 32-bit unit. B, H. | – |
rev64 | rev64 Vd.8b, Vn.8b | Reverses the elements in each 64-bit unit. B, H, S. | – |
tbl, tbx | tbl Vd.8b, { Vn.16b }, Vm.8b | Byte table look-up. The table is one to four consecutive 128-bit registers, and each byte of Vm is an index into it. An index out of range gives 0 with tbl, and leaves the byte of Vd unchanged with tbx. | – |
luti2, luti4 | luti2 Vd.16b, { Vn.16b }, Vm[i]; luti4 Vd.8h, { Vn.8h, Vn2.8h }, Vm[i] | Table look-up with packed 2-bit or 4-bit indices, taken from the segment of Vm picked by i. B or H elements. luti4 with H elements uses two table registers; the other forms use one. | – |
Floating-point arithmetic
The scalar forms of fadd, fsub, fmul,
fdiv, fabs, fneg, fsqrt,
fmax, fmin, fmaxnm, fminnm and the
frint family are the ordinary instructions on the
Floating point page, so the rows
here have no Scalar note for them.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
fadd, fsub | fadd Vd.2s, Vn.2s, Vm.2s | Add; subtract. H, S, D. | – |
fmul, fdiv | fmul Vd.2s, Vn.2s, Vm.2s | Multiply; divide. H, S, D. | – |
fabs, fneg | fabs Vd.2s, Vn.2s | Absolute value; negate. H, S, D. | – |
fsqrt | fsqrt Vd.2s, Vn.2s | Square root. H, S, D. | – |
fabd | fabd Vd.2s, Vn.2s, Vm.2s | Absolute difference. H, S, D. Scalar: H, S, D. | – |
fmax, fmin, fmaxnm, fminnm | fmax Vd.2s, Vn.2s, Vm.2s | Maximum and minimum, with the NaN rules described on the Floating point page. H, S, D. | – |
famax, famin | famax Vd.2s, Vn.2s, Vm.2s | The larger or smaller absolute value. H, S, D. Needs the FAMINMAX extension. | – |
faddp | faddp Vd.2s, Vn.2s, Vm.2s; faddp Sd, Vn.2s | Adds adjacent pairs. H, S, D. Scalar: H, S, D, adding the two elements of Vn. | – |
fmaxp, fminp, fmaxnmp, fminnmp | fmaxp Vd.2s, Vn.2s, Vm.2s; fmaxp Sd, Vn.2s | Maximum or minimum of adjacent pairs. H, S, D. Scalar: H, S, D, using the two elements of Vn. | – |
fmaxv, fminv, fmaxnmv, fminnmv | fmaxv Sd, Vn.4s | Maximum or minimum of all the elements, as one scalar. .4h, .8h and .4s only. | – |
fmla, fmls | fmla Vd.2s, Vn.2s, Vm.2s | Fused multiply-add to Vd, or multiply-subtract from Vd. H, S, D. Scalar: only by element, see By-element forms. | – |
fmulx | fmulx Vd.2s, Vn.2s, Vm.2s | Multiplies; infinity × 0 gives ±2.0 instead of a NaN. H, S, D. Scalar: H, S, D. | – |
fscale | fscale Vd.2s, Vn.2s, Vm.2s | Multiplies each element of Vn by 2 to the power of the signed integer in Vm. H, S, D. Needs FEAT_FP8. | – |
fcadd | fcadd Vd.4h, Vn.4h, Vm.4h, #90 | Complex add, with Vm rotated by 90 or 270 degrees. Elements are pairs (real, imaginary). H, S, D. Needs the FCMA extension. | – |
fcmla | fcmla Vd.4h, Vn.4h, Vm.4h, #0 | Complex multiply-accumulate, with a rotation of 0, 90, 180 or 270 degrees. Two instructions with suitable rotations give one full complex product. H, S, D. Needs the FCMA extension. | – |
fmov | fmov Vd.2s, #imm | Fills each element with a floating-point immediate, of the form described on the Floating point page. H, S, D. | – |
frecpe, frsqrte | frecpe Vd.2s, Vn.2s | Reciprocal estimate; reciprocal square root estimate. H, S, D. Scalar: H, S, D. | – |
frecps | frecps Vd.2s, Vn.2s, Vm.2s | Newton–Raphson step for the reciprocal: 2.0 − Vn × Vm. H, S, D. Scalar: H, S, D. | – |
frsqrts | frsqrts Vd.2s, Vn.2s, Vm.2s | Newton–Raphson step for the reciprocal square root: (3.0 − Vn × Vm) ÷ 2.0. H, S, D. Scalar: H, S, D. | – |
frecpx | frecpx Sd, Sn | Reciprocal exponent, a coarse scale factor built from the sign and exponent of the input. Scalar only: H, S, D. | – |
urecpe, ursqrte | urecpe Vd.2s, Vn.2s | Unsigned reciprocal estimate; unsigned reciprocal square root estimate. S elements only. | – |
Floating-point conversion and rounding
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
fcvtas, fcvtau | fcvtas Vd.2s, Vn.2s | To signed or unsigned integer of the same size, rounding to nearest with ties away from zero. H, S, D. Scalar: H, S, D (fcvtas Sd, Sn). | – |
fcvtms, fcvtmu | fcvtms Vd.2s, Vn.2s | To integer, rounding towards minus infinity. H, S, D. Scalar: H, S, D. | – |
fcvtns, fcvtnu | fcvtns Vd.2s, Vn.2s | To integer, rounding to nearest with ties to even. H, S, D. Scalar: H, S, D. | – |
fcvtps, fcvtpu | fcvtps Vd.2s, Vn.2s | To integer, rounding towards plus infinity. H, S, D. Scalar: H, S, D. | – |
fcvtzs, fcvtzu | fcvtzs Vd.2s, Vn.2s; fcvtzs Vd.2s, Vn.2s, #fbits | To integer or fixed point, rounding towards zero. H, S, D. Scalar: H, S, D. | – |
scvtf, ucvtf | scvtf Vd.2s, Vn.2s; scvtf Vd.2s, Vn.2s, #fbits | From signed or unsigned integer or fixed point of the same size. H, S, D. Scalar: H, S, D. | – |
fcvtl, fcvtl2 | fcvtl Vd.4s, Vn.4h | Widens the precision: H to S, or S to D. | – |
fcvtn, fcvtn2 | fcvtn Vd.4h, Vn.4s | Narrows the precision: S to H, or D to S. | – |
fcvtxn, fcvtxn2 | fcvtxn Vd.2s, Vn.2d | Narrows D to S, rounding to odd. Scalar: fcvtxn Sd, Dn (fcvtxn only). | – |
frinta, frintm, frintn, frintp, frintz | frinta Vd.2s, Vn.2s | Rounds to an integral value, using the rounding in each mnemonic: a nearest with ties away, m towards minus infinity, n nearest with ties to even, p towards plus infinity, z towards zero. H, S, D. | – |
frinti, frintx | frinti Vd.2s, Vn.2s | Rounds using the FPCR mode. frintx raises Inexact when the value changes; frinti does not. H, S, D. | – |
frint32x, frint32z, frint64x, frint64z | frint32x Vd.2s, Vn.2s | Rounds to an integral value that fits 32 or 64 bits, with the FPCR mode (x) or towards zero (z). S, D. Needs the FRINTTS extension. | – |
By-element forms
Many multiplying instructions can take their second operand from one element of Vm, used for every element of the result. Each is described at the row linked below. For the integer multiplies with H elements, Vm must be V0 to V15.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
mul, mla, mls | mul Vd.4h, Vn.4h, Vm.h[i] | H, S. | – |
fmla, fmls, fmul, fmulx | fmla Vd.2s, Vn.2s, Vm.s[i]; fmla Sd, Sn, Vm.s[i] | H, S, D. Scalar: H, S, D. | – |
fcmla | fcmla Vd.4h, Vn.4h, Vm.h[i], #0 | H, S. | – |
smull, umull, smlal, umlal, smlsl, umlsl | smull Vd.4s, Vn.4h, Vm.h[i] | Sources H, S. Each has a 2 form too. | – |
sqdmull, sqdmlal, sqdmlsl | sqdmull Vd.4s, Vn.4h, Vm.h[i]; sqdmull Sd, Hn, Vm.h[i] | Sources H, S. Each has a 2 form too. Scalar: H and S sources (no 2 forms). | – |
sqdmulh, sqrdmulh, sqrdmlah, sqrdmlsh | sqdmulh Vd.4h, Vn.4h, Vm.h[i]; sqdmulh Hd, Hn, Vm.h[i] | H, S. Scalar: H, S. | – |
sdot, udot, usdot, sudot | sdot Vd.2s, Vn.8b, Vm.4b[i] | The index picks one group of four bytes. sudot exists only in this form. | – |
fmlal, fmlal2, fmlsl, fmlsl2 | fmlal Vd.2s, Vn.2h, Vm.h[i] | H sources. | – |
bfdot | bfdot Vd.2s, Vn.4h, Vm.2h[i] | The index picks one pair of halfwords. | – |
bfmlalb, bfmlalt | bfmlalb Vd.4s, Vn.8h, Vm.h[i] | BFloat16 H sources. | – |
fdot | fdot Vd.2s, Vn.8b, Vm.4b[i]; fdot Vd.4h, Vn.8b, Vm.2b[i] | 8-bit floating-point sources. | – |
fmlalb, fmlalt, fmlallbb, fmlallbt, fmlalltb, fmlalltt | fmlalb Vd.8h, Vn.16b, Vm.b[i]; fmlallbb Vd.4s, Vn.16b, Vm.b[i] | 8-bit floating-point sources. Vm must be V0 to V7. | – |
Dot products and matrix multiply
A dot product multiplies groups of small elements and sums each group into one wider element. The matrix instructions divide each 128-bit register into matrices. The floating-point dot and matrix instructions are in the next table.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
sdot, udot | sdot Vd.2s, Vn.8b, Vm.8b | For each 32-bit element, multiplies four signed or unsigned bytes of Vn by the same four of Vm, and adds the four products to Vd. Needs the DotProd extension. | – |
usdot | usdot Vd.2s, Vn.8b, Vm.8b | The same with unsigned bytes in Vn and signed bytes in Vm. Needs the I8MM extension. | – |
sudot | sudot Vd.2s, Vn.8b, Vm.4b[i] | The same with signed bytes in Vn and unsigned bytes taken from one group of Vm. By element only. Needs the I8MM extension. | – |
smmla, ummla, usmmla | smmla Vd.4s, Vn.16b, Vm.16b | Multiplies a 2×8 byte matrix in Vn by an 8×2 byte matrix in Vm, and adds the 2×2 result to the 32-bit elements of Vd. smmla is signed, ummla unsigned, and usmmla has unsigned Vn and signed Vm. Needs the I8MM extension. | – |
FP8 and FP16 forms
These instructions handle small floating-point formats.
- Half precision to single (FEAT_FHM): the fused widening multiplies
fmlalandfmlsl. - BFloat16 (FEAT_BF16): a 16-bit format with the same 8-bit exponent as single precision, and so with more range and less precision than half precision.
- FP8: 8-bit floating-point values. The FPMR register sets the format of each source (F8S1, F8S2) and a downscale (LSCALE), so the same mnemonics handle different 8-bit formats.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
fmlal, fmlal2 | fmlal Vd.2s, Vn.2h, Vm.2h | Widens H sources to S, multiplies and adds to Vd, fused. fmlal takes the lower half of each source, fmlal2 the upper. | – |
fmlsl, fmlsl2 | fmlsl Vd.2s, Vn.2h, Vm.2h | The same, subtracting from Vd. | – |
bfcvt | bfcvt Hd, Sn | Converts single precision to BFloat16. Scalar only. | – |
bfcvtn, bfcvtn2 | bfcvtn Vd.4h, Vn.4s | The vector forms: single precision to BFloat16, narrowing. | – |
bfdot | bfdot Vd.2s, Vn.4h, Vm.4h | For each 32-bit element, multiplies two BFloat16 pairs and adds both products to Vd. | – |
bfmlalb, bfmlalt | bfmlalb Vd.4s, Vn.8h, Vm.8h | Multiplies the even-numbered (bfmlalb) or odd-numbered (bfmlalt) BFloat16 elements and adds to the S elements of Vd. | – |
bfmmla | bfmmla Vd.4s, Vn.8h, Vm.8h | Multiplies a 2×4 BFloat16 matrix in Vn by a 4×2 matrix in Vm, and adds the 2×2 result to the S elements of Vd. | – |
f1cvtl, f1cvtl2, f2cvtl, f2cvtl2 | f1cvtl Vd.8h, Vn.8b | Converts 8-bit floating point to half precision and downscales. f1cvtl uses FPMR.F8S1 and LSCALE; f2cvtl uses F8S2 and LSCALE2. A trailing 2 reads the upper half of the source. | – |
bf1cvtl, bf1cvtl2, bf2cvtl, bf2cvtl2 | bf1cvtl Vd.8h, Vn.8b | The same, converting to BFloat16. | – |
fdot | fdot Vd.2s, Vn.8b, Vm.8b; fdot Vd.4h, Vn.8b, Vm.8b | Fused sum of products of four 8-bit values into each S element, or of two into each H element, then scaled by 2−LSCALE and added to Vd. | – |
fmlalb, fmlalt | fmlalb Vd.8h, Vn.16b, Vm.16b | Widens the even-numbered (fmlalb) or odd-numbered (fmlalt) 8-bit elements to half precision, multiplies them, scales, and adds to Vd. | – |
fmlallbb, fmlallbt, fmlalltb, fmlalltt | fmlallbb Vd.4s, Vn.16b, Vm.16b | Widens byte 0, 1, 2 or 3 of each 32-bit unit to single precision, multiplies, scales and adds to Vd. | – |
fmmla | fmmla Vd.8h, Vn.16b, Vm.16b; fmmla Vd.4s, Vn.16b, Vm.16b | Matrix multiply of 8-bit floating-point values, giving H or S results that are scaled and added to Vd. The H form multiplies a 2×4 matrix in each 64-bit segment of Vn by a 4×2 matrix in Vm. Needs FEAT_F8F16MM or FEAT_F8F32MM. | – |
Links
Reference
- Arm A64 Instruction Set Architecture – Arm’s description of each A64 instruction
- Arm Architecture Reference Manual for A-profile – the full architecture specification