The A64 Instruction set
One of the most significant changes introduced in the ARMv8-A architecture was the addition of an instruction set for AArch64, called A64. This instruction set contains features similar to the existing AArch32 (ARMv7-A) 32-bit instruction set.
The addition of A64 provides access to 64-bit wide integer registers and data operations, and the ability to use 64-bit sized pointers to memory. The A64 instructions execute in the AArch64 Execution state. ARMv8-A also includes the original ARM® instruction set, now called A32, and the Thumb® (T32) instruction set.
Programmers writing at the application level might never need to write code in assembly language. However, assembly code can be useful in cases when highly optimized code is required. This is the case when writing compilers, or where using low level features not directly available in C is required, for example:
- Portions of boot code.
- Device drivers.
- Operating system development.
Reading assembly code can be helpful for debugging C, particularly to understand the mapping between assembly instructions and C statements.
The A64 instruction set overloads instruction mnemonics. That is, it distinguishes between the different forms of an instruction, based on the operand register names that are used. For example, the following ADD instructions all have different forms, but you only have to remember one instruction and the assembler automatically chooses the correct encoding, based on the operands used.
ADD W0, W1, W2
add 32-bit registers
ADD X0, X1, X2
add 64-bit registers
ADD X0, X1, W2, SXTW // add sign extended 32-bit
register to 64-bit extended register
ADD X0, X1,
add immediate to 64-bit register
ADD V0.8H, V1.8H, V2.8H // NEON 16-bit add, in each of 8
Distinguishing between 32-bit and 64-bit A64 instructions
Most integer instructions in the A64 instruction set have two forms, which operate on either 32-bit or 64-bit values within the 64-bit general-purpose register file.
When looking at the register name that the instruction uses:
- If the register name starts with X, it is a 64-bit register.
- If the register name starts with W, it is a 32-bit register.
When a 32-bit register form is selected:
- Right shifts and rotates inject at bit 31, instead of bit 63.
- The condition flags, where set by the instruction, are computed from the lower 32 bits.
- Writes to the W register set bits [63:32] of the X register to zero.
This distinction applies even when the results of a 32-bit register form would be
indistinguishable from the lower 32 bits computed by the equivalent 64-bit register
form. For example, A64 includes separate 32-bit and 64-bit register forms of the ORR
instructions. A 32-bit bitwise
ORR could just as easily be performed using
ORR and ignoring the top 32 bits of the result.