Introduction
A64 is a load-store architecture: arithmetic works on registers, and only these
instructions move data between registers and memory. A base register holds the address.
It is a general-purpose register or sp. None of these instructions changes
the flags, so the Flags column has a dash throughout.
The addressing forms are:
- Offset:
[Xn, #imm]. The address is the base plus an immediate, and the base is unchanged. The ordinary forms use an unsigned immediate scaled by the access size. The unscaled forms take a signed 9-bit byte offset. - Pre-index:
[Xn, #imm]!. The base is updated first, and the new value is the address. - Post-index:
[Xn], #imm. The base is the address, and the base is updated afterwards. - Register offset:
[Xn, Xm],[Xn, Xm, lsl #s], or with a W register and an extension,[Xn, Wm, uxtw #s]or[Xn, Wm, sxtw #s], or[Xn, Xm, sxtx #s]. The shift is 0 or the base-2 logarithm of the access size, so thatXmcounts elements. - Literal:
ldr Xt, label. The address is an offset from the instruction, within ±1 MiB.
The disassembler shows an offset of zero as [x0]. The floating-point and
SIMD forms of these instructions take b, h, s,
d or q registers.
Loads that sign-extend (ldrsb, ldrsh, ldrsw)
and their relatives can write a W or an X register, and the width of the result is
chosen by the register name.
Some instructions order memory accesses or access memory as if at EL0. The
instructions that use a lower privilege are named with a t. At EL1, or at
EL2 with HCR_EL2.{E2H, TGE} both set, they behave as if run at EL0 unless the
PSTATE.UAO bit is set. In other cases they use the current privilege.
The instructions
Single registers
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
ldr | ldr Rt, [Xn, #imm]; pre-index, post-index, register offset; ldr Rt, label | Loads a word or doubleword. With a floating-point register, loads that size. | – |
str | str Rt, [Xn, #imm]; pre-index, post-index, register offset | Stores a word or doubleword, or a floating-point register. | – |
ldrb | ldrb Wt, [Xn, #imm] | Loads a byte and zero-extends it. | – |
ldrh | ldrh Wt, [Xn, #imm] | Loads a halfword and zero-extends it. | – |
strb | strb Wt, [Xn, #imm] | Stores the low byte of a register. | – |
strh | strh Wt, [Xn, #imm] | Stores the low halfword. | – |
ldrsb | ldrsb Rt, [Xn, #imm] | Loads a byte and sign-extends it to the width of the register. | – |
ldrsh | ldrsh Rt, [Xn, #imm] | Loads a halfword and sign-extends it. | – |
ldrsw | ldrsw Xt, [Xn, #imm]; ldrsw Xt, label | Loads a word and sign-extends it to 64 bits. | – |
Unscaled offset
These take a signed 9-bit byte offset, −256 to 255, not scaled by the access size.
They are used for offsets that the scaled ldr form cannot hold.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
ldur, stur | ldur Rt, [Xn, #imm] | Loads or stores a word or doubleword, or a floating-point register. | – |
ldurb, sturb | ldurb Wt, [Xn, #imm] | Loads a byte, zero-extended, or stores the low byte. | – |
ldurh, sturh | ldurh Wt, [Xn, #imm] | Loads a halfword, zero-extended, or stores the low halfword. | – |
ldursb, ldursh, ldursw | ldursb Rt, [Xn, #imm]; ldursw Xt, [Xn, #imm] | Loads a byte, halfword or word and sign-extends it. | – |
Unprivileged
These act like the unscaled forms. They use the lower privilege described in the Introduction.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
ldtr, sttr | ldtr Rt, [Xn, #imm] | Unprivileged load or store of a word or doubleword. | – |
ldtrb, sttrb | ldtrb Wt, [Xn, #imm] | Unprivileged load, zero-extended, or store of a byte. | – |
ldtrh, sttrh | ldtrh Wt, [Xn, #imm] | Unprivileged load, zero-extended, or store of a halfword. | – |
ldtrsb, ldtrsh, ldtrsw | ldtrsb Rt, [Xn, #imm]; ldtrsw Xt, [Xn, #imm] | Unprivileged load of a byte, halfword or word, sign-extended. | – |
ldtp, sttp | ldtp Xt1, Xt2, [Xn, #imm]; pre-index and post-index forms | Unprivileged load or store of two doublewords or two q registers (FEAT_LSUI). | – |
ldtnp, sttnp | ldtnp Xt1, Xt2, [Xn, #imm] | The same with a non-temporal hint. | – |
Pairs
A pair offset is a 7-bit signed immediate scaled by the size of one register. These
are the usual way to save and restore registers on the stack, for example
stp x29, x30, [sp, #-16]!.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
ldp | ldp Rt1, Rt2, [Xn, #imm]; pre-index and post-index forms | Loads two registers from consecutive locations. | – |
stp | stp Rt1, Rt2, [Xn, #imm]; pre-index and post-index forms | Stores two registers to consecutive locations. | – |
ldpsw | ldpsw Xt1, Xt2, [Xn, #imm]; pre-index and post-index forms | Loads two words and sign-extends each to 64 bits. | – |
ldnp | ldnp Rt1, Rt2, [Xn, #imm] | Loads a pair with a non-temporal hint: the data is unlikely to be used again soon. | – |
stnp | stnp Rt1, Rt2, [Xn, #imm] | Stores a pair with a non-temporal hint. | – |
Acquire and release
A load-acquire is ordered before all later memory accesses by that processor, and a store-release is ordered after all earlier ones. Other load-acquire and store-release instructions are also ordered with each other. These take a plain base register with no offset, except for the unscaled and writeback forms.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
ldar, ldarb, ldarh | ldar Rt, [Xn]; ldarb Wt, [Xn] | Load-acquire of a word or doubleword, a byte or a halfword. | – |
stlr, stlrb, stlrh | stlr Rt, [Xn]; stlr Rt, [Xn, #-size]! | Store-release. A word or doubleword stlr also has a pre-index form (FEAT_LRCPC3). | – |
ldlar, ldlarb, ldlarh | ldlar Rt, [Xn] | Load-acquire within a limited ordering region (FEAT_LOR). | – |
stllr, stllrb, stllrh | stllr Rt, [Xn] | Store-release within a limited ordering region (FEAT_LOR). | – |
ldapr | ldapr Rt, [Xn], #size | Load-acquire RCpc, with a post-index by the access size (FEAT_LRCPC3). The plain form is on the Atomic and exclusive access page. | – |
Exclusives
A load-exclusive marks an address as held. A store-exclusive writes only if the mark
is still there, and writes a status to Ws: 0 means the store happened and
1 means it did not. The pair is used in a retry loop. clrex on the
System instructions page clears the
mark. The Large System Extensions have direct atomics on the
Atomic and exclusive access page.
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
ldxr, ldxrb, ldxrh | ldxr Rt, [Xn] | Load-exclusive of a word or doubleword, a byte or a halfword. | – |
stxr, stxrb, stxrh | stxr Ws, Rt, [Xn] | Store-exclusive. | – |
ldaxr, ldaxrb, ldaxrh | ldaxr Rt, [Xn] | Load-exclusive with acquire ordering. | – |
stlxr, stlxrb, stlxrh | stlxr Ws, Rt, [Xn] | Store-exclusive with release ordering. | – |
ldxp, stxp | ldxp Rt1, Rt2, [Xn]; stxp Ws, Rt1, Rt2, [Xn] | Exclusive load or store of a pair. | – |
ldaxp, stlxp | ldaxp Rt1, Rt2, [Xn]; stlxp Ws, Rt1, Rt2, [Xn] | Exclusive pair with acquire or release ordering. | – |
Prefetch
A prefetch is a hint and does not change architectural state. A prefetch operation
reads as a type (pld for loads, pli for instructions,
pst for stores), a target cache (l1, l2,
l3 or slc, the system level cache) and a policy
(keep or strm, streaming). Example:
prfm pldl1keep, [x0].
| Mnemonic | Syntax | What it does | Flags |
|---|---|---|---|
prfm | prfm op, [Xn, #imm]; register offset; prfm op, label | Signals that an address will probably be used soon. | – |
prfum | prfum op, [Xn, #imm] | The same with a signed, unscaled offset. | – |
rprfm | rprfm op, Xm, [Xn] | Range prefetch (FEAT_RPRFM). Xm describes blocks of memory near the base address: their length, stride, count and reuse distance. The options are pldkeep, pstkeep, pldstrm and pststrm. | – |
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