Introduction
These instructions work on the 31 general-purpose registers. Each register has a 64-bit
name, x0 to x30, and a 32-bit name, w0 to
w30, for its low half. Writing a W register clears the top 32 bits of the X
register. Register number 31 is either the zero register (xzr,
wzr), which reads as 0 and ignores writes, or the stack pointer
(sp, wsp). Which of the two it is depends on the instruction
and the operand.
In the tables, Rd, Rn and Rm mean an X or a W
register, all the same width unless the row says otherwise. Xd and
Wd mean only that width.
There are four condition flags in PSTATE:
- N is set when the result is negative, that is, when its top bit is 1;
- Z is set when the result is zero;
- C is the carry out of an addition. For a subtraction it is set when no borrow happened, so it means “not borrow”;
- V is set when a signed result overflowed.
Ordinary instructions leave the flags alone. Only the forms with an s on
the end (adds, subs, ands and others), the
compares and the few flag instructions set them. The condition codes that read them are
listed on the Branches and exceptions page.
An ands or bics takes N and Z from the result and clears C
and V.
The operand of an add, subtract or logical instruction has several forms:
- an immediate. Add and subtract take 12 bits, which can be shifted left by 12. Logical instructions take a bitmask: a run of ones, rotated, repeated in elements of 2, 4, 8, 16, 32 or 64 bits;
- a shifted register,
Rm, lsl #n, withlsl,lsrorasr, and alsororfor logical instructions; - an extended register for add and subtract:
Rm, uxtb #nand so on, where the extension isuxtb,uxth,uxtw,uxtx,sxtb,sxth,sxtworsxtxand the left shift is 0 to 4. The immediate and extended register forms can usesp.
The instructions
Many of these names are aliases of a more general encoding. The disassembler prints
the alias, as LLVM does. For example cmp is subs with the zero
register as its destination, and lsl with an immediate is a bitfield
move.
PC-relative addresses
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
adr | adr Xd, label | Writes the address of a label within ±1 MiB of this instruction. | – |
adrp | adrp Xd, label | Writes the address of the 4 KiB page holding a label, within ±4 GiB. The low 12 bits are 0. A following add or load supplies them. | – |
Add and subtract
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
add | add Rd, Rn, #imm; add Rd, Rn, Rm, lsl #n; add Rd, Rn, Wm, sxtw #n | Adds. The immediate and extended forms can use sp. | – |
adds | adds Rd, Rn, #imm; shifted and extended register forms | Adds and sets the flags. | NZCV |
sub | sub Rd, Rn, #imm; shifted and extended register forms | Subtracts the second operand from Rn. | – |
subs | subs Rd, Rn, #imm; shifted and extended register forms | Subtracts and sets the flags. | NZCV |
cmp | cmp Rn, #imm; cmp Rn, Rm | Compares by subtracting. The result is discarded. Alias of subs with the zero register as destination. | NZCV |
cmn | cmn Rn, #imm; cmn Rn, Rm | Compares by adding, so it tests against the negated operand. Alias of adds with the zero register as destination. | NZCV |
neg | neg Rd, Rm; neg Rd, Rm, lsl #n | Writes 0 minus the operand. Alias of sub. | – |
negs | negs Rd, Rm | Negates and sets the flags. Alias of subs. | NZCV |
adc | adc Rd, Rn, Rm | Adds the two registers and the carry flag. | – |
adcs | adcs Rd, Rn, Rm | Adds with carry and sets the flags. | NZCV |
sbc | sbc Rd, Rn, Rm | Subtracts Rm and the inverse of the carry flag from Rn. | – |
sbcs | sbcs Rd, Rn, Rm | Subtracts with carry and sets the flags. | NZCV |
ngc | ngc Rd, Rm | Negates with carry: 0 minus Rm minus the inverse of carry. Alias of sbc. | – |
ngcs | ngcs Rd, Rm | Negates with carry and sets the flags. Alias of sbcs. | NZCV |
Logic
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
and | and Rd, Rn, #bitmask; and Rd, Rn, Rm, lsl #n | Bitwise AND. | – |
ands | ands Rd, Rn, #bitmask; ands Rd, Rn, Rm | Bitwise AND, setting N and Z from the result and clearing C and V. | NZCV |
tst | tst Rn, #bitmask; tst Rn, Rm | Tests bits: an ands whose result is discarded. | NZCV |
orr | orr Rd, Rn, #bitmask; orr Rd, Rn, Rm, lsl #n | Bitwise OR. | – |
eor | eor Rd, Rn, #bitmask; eor Rd, Rn, Rm, lsl #n | Bitwise exclusive OR. | – |
bic | bic Rd, Rn, Rm, lsl #n | Clears bits: Rn AND NOT Rm. | – |
bics | bics Rd, Rn, Rm, lsl #n | As bic, setting N and Z from the result and clearing C and V. | NZCV |
orn | orn Rd, Rn, Rm, lsl #n | Rn OR NOT Rm. | – |
eon | eon Rd, Rn, Rm, lsl #n | Rn exclusive OR NOT Rm. | – |
mvn | mvn Rd, Rm, lsl #n | Writes the bitwise inverse. Alias of orn with the zero register. | – |
Moves
A move-wide instruction holds 16 bits and a shift of 0, 16, 32 or 48 (0 or 16 for W
registers). A 64-bit constant is usually built with one movz or
movn and up to three movk.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
mov | mov Rd, Rm; mov Rd, #imm; mov sp, Xn | Copies a register or loads a constant. It is an alias of orr with the zero register, of movz, of movn, or of add with #0 when sp is involved. | – |
movz | movz Rd, #imm, lsl #n | Writes the 16-bit value at the shift and clears all other bits. | – |
movn | movn Rd, #imm, lsl #n | Writes the bitwise inverse of the shifted 16-bit value. | – |
movk | movk Rd, #imm, lsl #n | Writes 16 bits at the shift and keeps the other bits. | – |
Shifts and rotates
A shift by a register uses the amount modulo the register width. The immediate forms
are aliases of the bitfield moves, and ror with an immediate is an alias
of extr.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
lsl | lsl Rd, Rn, #n; lsl Rd, Rn, Rm | Logical shift left, filling with zeros. | – |
lsr | lsr Rd, Rn, #n; lsr Rd, Rn, Rm | Logical shift right, filling with zeros. | – |
asr | asr Rd, Rn, #n; asr Rd, Rn, Rm | Arithmetic shift right, filling with copies of the sign bit. | – |
ror | ror Rd, Rn, #n; ror Rd, Rn, Rm | Rotates right. Bits leaving the bottom enter at the top. | – |
extr | extr Rd, Rn, Rm, #lsb | Joins Rn above Rm and takes one register’s width of bits starting at bit lsb of Rm. | – |
Extend and bitfield
A bitfield is given as its lowest bit, lsb, and its
width. All these names are aliases of three encodings: SBFM, UBFM and
BFM.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
sxtb | sxtb Rd, Wn | Sign-extends the low byte of Wn. | – |
sxth | sxth Rd, Wn | Sign-extends the low halfword. | – |
sxtw | sxtw Xd, Wn | Sign-extends a word to 64 bits. | – |
uxtb | uxtb Wd, Wn | Zero-extends the low byte. Writing the W register also clears the top half of the X register. | – |
uxth | uxth Wd, Wn | Zero-extends the low halfword. | – |
sbfx | sbfx Rd, Rn, #lsb, #width | Extracts a field from Rn to the bottom of Rd and sign-extends it. | – |
ubfx | ubfx Rd, Rn, #lsb, #width | Extracts a field to the bottom of Rd and zero-extends it. | – |
sbfiz | sbfiz Rd, Rn, #lsb, #width | Takes the low width bits of Rn, places them at lsb, sign-extends above and clears below. | – |
ubfiz | ubfiz Rd, Rn, #lsb, #width | Takes the low width bits of Rn, places them at lsb and clears all other bits. | – |
bfi | bfi Rd, Rn, #lsb, #width | Inserts the low width bits of Rn at lsb of Rd. Other bits of Rd stay. | – |
bfxil | bfxil Rd, Rn, #lsb, #width | Copies a field of Rn to the bottom of Rd. Other bits of Rd stay. | – |
Conditional select and compare
These read a condition code. In
the aliases cset, csetm, cinc,
cinv and cneg, the condition may not be al or
nv, and it is written as the true case: the encoding holds its
inverse.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
csel | csel Rd, Rn, Rm, cond | Writes Rn if the condition holds, otherwise Rm. | – |
csinc | csinc Rd, Rn, Rm, cond | Writes Rn if the condition holds, otherwise Rm plus 1. | – |
csinv | csinv Rd, Rn, Rm, cond | Writes Rn if the condition holds, otherwise the bitwise inverse of Rm. | – |
csneg | csneg Rd, Rn, Rm, cond | Writes Rn if the condition holds, otherwise the negative of Rm. | – |
cset | cset Rd, cond | Writes 1 if the condition holds, otherwise 0. | – |
csetm | csetm Rd, cond | Writes all ones if the condition holds, otherwise 0. | – |
cinc | cinc Rd, Rn, cond | Writes Rn plus 1 if the condition holds, otherwise Rn. | – |
cinv | cinv Rd, Rn, cond | Writes the bitwise inverse of Rn if the condition holds, otherwise Rn. | – |
cneg | cneg Rd, Rn, cond | Writes the negative of Rn if the condition holds, otherwise Rn. | – |
ccmp | ccmp Rn, Rm, #nzcv, cond; ccmp Rn, #imm, #nzcv, cond | If the condition holds, sets the flags as cmp does. Otherwise sets them to the 4-bit #nzcv value. The immediate is 0 to 31. | NZCV |
ccmn | ccmn Rn, Rm, #nzcv, cond; ccmn Rn, #imm, #nzcv, cond | If the condition holds, sets the flags as cmn does. Otherwise sets them to #nzcv. | NZCV |
Multiply and divide
Dividing by zero writes 0 and does not trap. Division rounds towards zero. The most negative value divided by −1 gives the most negative value.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
mul | mul Rd, Rn, Rm | Multiplies and keeps the low half. Alias of madd with the zero register. | – |
madd | madd Rd, Rn, Rm, Ra | Ra + Rn × Rm. | – |
msub | msub Rd, Rn, Rm, Ra | Ra − Rn × Rm. | – |
mneg | mneg Rd, Rn, Rm | The negative of Rn × Rm. Alias of msub. | – |
smull | smull Xd, Wn, Wm | Signed 32 × 32 multiply to a 64-bit result. | – |
umull | umull Xd, Wn, Wm | Unsigned 32 × 32 multiply to a 64-bit result. | – |
smaddl | smaddl Xd, Wn, Wm, Xa | Xa + signed Wn × Wm. | – |
umaddl | umaddl Xd, Wn, Wm, Xa | Xa + unsigned Wn × Wm. | – |
smsubl | smsubl Xd, Wn, Wm, Xa | Xa − signed Wn × Wm. | – |
umsubl | umsubl Xd, Wn, Wm, Xa | Xa − unsigned Wn × Wm. | – |
smnegl | smnegl Xd, Wn, Wm | The negative of signed Wn × Wm. | – |
umnegl | umnegl Xd, Wn, Wm | The negative of unsigned Wn × Wm. | – |
smulh | smulh Xd, Xn, Xm | Top 64 bits of a signed 64 × 64 multiply. | – |
umulh | umulh Xd, Xn, Xm | Top 64 bits of an unsigned 64 × 64 multiply. | – |
sdiv | sdiv Rd, Rn, Rm | Signed division. | – |
udiv | udiv Rd, Rn, Rm | Unsigned division. | – |
Counting and reversing
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
clz | clz Rd, Rn | Counts leading zero bits. | – |
cls | cls Rd, Rn | Counts the bits below the top bit that match it. | – |
rbit | rbit Rd, Rn | Reverses the order of the bits. | – |
rev | rev Rd, Rn | Reverses the order of the bytes in the register. | – |
rev16 | rev16 Rd, Rn | Reverses the bytes within each 16-bit halfword. | – |
rev32 | rev32 Xd, Xn | Reverses the bytes within each 32-bit word. | – |
Common short sequences (CSSC)
These come with FEAT_CSSC. Each replaces a short sequence of older instructions.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
abs | abs Rd, Rn | Writes the absolute value. The most negative value stays as it is. | – |
cnt | cnt Rd, Rn | Counts the bits that are set. | – |
ctz | ctz Rd, Rn | Counts trailing zero bits. | – |
smax | smax Rd, Rn, Rm; smax Rd, Rn, #imm | Writes the signed larger of the two. The immediate is 8 bits, signed. | – |
smin | smin Rd, Rn, Rm; smin Rd, Rn, #imm | Writes the signed smaller of the two. | – |
umax | umax Rd, Rn, Rm; umax Rd, Rn, #imm | Writes the unsigned larger of the two. The immediate is 8 bits, unsigned. | – |
umin | umin Rd, Rn, Rm; umin Rd, Rn, #imm | Writes the unsigned smaller of the two. | – |
CRC32
Wn holds the CRC so far, and the result is the new CRC. The second
operand is the data: its low 8, 16 or 32 bits, or all of Xm. The
crc32 forms use the polynomial 0x04C11DB7, and the
crc32c forms use the Castagnoli polynomial 0x1EDC6F41.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
crc32b | crc32b Wd, Wn, Wm | Adds one byte to a CRC-32. | – |
crc32h | crc32h Wd, Wn, Wm | Adds one halfword. | – |
crc32w | crc32w Wd, Wn, Wm | Adds one word. | – |
crc32x | crc32x Wd, Wn, Xm | Adds one doubleword. | – |
crc32cb | crc32cb Wd, Wn, Wm | Adds one byte to a CRC-32C. | – |
crc32ch | crc32ch Wd, Wn, Wm | Adds one halfword. | – |
crc32cw | crc32cw Wd, Wn, Wm | Adds one word. | – |
crc32cx | crc32cx Wd, Wn, Xm | Adds one doubleword. | – |
Checked pointer arithmetic
These come with FEAT_CPA. They calculate an address as ordinary arithmetic does. If the result’s top 8 bits differ from those of the base pointer, the result is changed so that it is likely to be non-canonical when used as an address.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
addpt | addpt Xd, Xn, Xm, lsl #n | Adds an offset, shifted left by 0 to 7, to a base pointer. | – |
subpt | subpt Xd, Xn, Xm, lsl #n | Subtracts a shifted offset from a base pointer. | – |
maddpt | maddpt Xd, Xn, Xm, Xa | Multiplies Xn by Xm to give an offset and adds it to the pointer in Xa. The result is also made likely to be non-canonical if the product does not fit in 64 signed bits. | – |
msubpt | msubpt Xd, Xn, Xm, Xa | As maddpt, but subtracts the product from the pointer in Xa. | – |
Flag manipulation
Other flag instructions, cfinv, axflag and
xaflag, are on the
System instructions page.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
rmif | rmif Xn, #shift, #mask | Rotates Xn right by shift. The bottom four bits of the result then go into N, Z, C and V. Only the flags chosen by the 4-bit mask change. | NZCV, as chosen by the mask |
setf8 | setf8 Wn | Treats the low 8 bits as a value. N is bit 7, Z is set if the low 8 bits are 0, and V is bit 8 exclusive-ORed with bit 7. | NZV |
setf16 | setf16 Wn | The same for the low 16 bits, using bits 15 and 16. | NZV |
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