Overview
The A64 instruction set is the instruction set used in the AArch64 execution mode of the Armv8-A architecture. It is distinct from the instruction sets used in the AArch32 execution mode, which comprises A32 (32-bit ARM), T32 (mixed 16-/32-bit Thumb-2), and T16 (16-bit Thumb-1). A64 instruction encodings are defined in the Arm Architecture Reference Manual (ARM ARM) — specifically the DDI0487E Armv8-A Architecture Reference Manual — and are specified using the ASL specification language, which served as the source for the Examiner test case generator.
Role in the Examiner Framework
Examiner is a differential testing tool that automatically locates inconsistent instructions between real ARM devices and CPU emulators. It uses A64 as one of the four instruction sets it targets (alongside A32, T32, and T16). A64 streams are generated by Examiner's test case generator according to the constraints defined in the Armv8-A manual, and these streams are executed both on real devices (spanning ARMv5, ARMv6, ARMv7, and ARMv8) and on emulators (QEMU, Unicorn, and Angr). The execution results are then compared to detect inconsistencies.
Evaluation Statistics for A64
According to Table 2 of the Examiner paper, A64 testing consumed 70.51 seconds of execution time and produced the following results comparing Examiner-generated streams to randomly generated streams:
| Metric | Examiner | Random | Ratio |
|---|---|---|---|
| Instruction Streams | 1,094,700 | 421,645 | 38.5% |
| Instruction Encodings | 839 | 265 | 31.6% |
| Instructions | 581 | 178 | 30.6% |
| Covered Constraints | 3,436 | 934 | 27.2% |
The statistics show that, for A64, randomly generated test cases cover only a fraction of the instruction encodings, instructions, and constraints reachable by the constraint-aware Examiner generator. The total of 489 instructions reported for A32, T32, and T16 in Table 2 does not include A64, indicating that A64 contributes a separate set of instructions to the overall ARM coverage.
Differential Testing with A64
Examiner's differential testing engine treats a generated instruction stream as inconsistent if, after ensuring equivalent initial CPU states (PC, registers, memory, and status) between the emulator and the real device, the final CPU states — including any signals or exceptions raised during execution — differ between the two platforms. Prologue instructions are used to zero general-purpose registers (except PC) and register signal handlers, while epilogue instructions dump the resulting CPU state for comparison. The same methodology is applied uniformly to A64 streams as to streams from the other three instruction sets.
Role in armshaker
armshaker is a processor fuzzer targeting the Armv8-A ISA that finds hidden instructions in hardware processors and in other implementations of the ISA such as emulators. It works by executing instructions in the search range and checking whether execution generates an undefined-instruction exception (a SIGILL signal); instructions that fail to raise SIGILL are logged as hidden. The "limited size" of the Armv8-A instruction sets — A64, A32, and T32 — makes exhaustive search of the whole instruction space feasible.
A64 fuzzing is supported when armshaker is compiled with a 64-bit (AArch64) toolchain. A defined A64 instruction can be executed and its effects inspected; for example, the A64 instruction mov x0, #0x1337 assembles to the 32-bit encoding 0xd28266e0, which when executed via the fuzzer produces the expected register state change x0: 0x0000000000000000 → 0x0000000000001337. An apparent large number of "hidden" A32 instructions can arise on processors that execute undefined instructions with an unmatched condition code as NOPs (an implementation-defined behavior documented in section G1.16.1 of the DDI0487E Armv8 Architecture Reference Manual); the -c option, which forces the condition code to match, can be used to bypass this behavior.
The main findings of the work that produced armshaker were published at the HASP 2020 workshop as Uncovering Hidden Instructions in Armv8-A Implementations (Strupe & Kumar, 2021, DOI 10.1145/3458903.3458906). The fuzzing reported there did not find hardware-attributable hidden instructions but did reveal bugs in the QEMU emulator and the Linux kernel.