A32 instruction set
Overview
A32, also referred to as ARM32, is a 32-bit fixed-length instruction set used in the AArch32 execution state of the ARM architecture. It is one of the three instruction sets defined for AArch32 mode, alongside T32 (Thumb-2, mixed 16/32-bit) and T16 (Thumb-1, 16-bit).
Architectural support
A32 is supported across multiple generations of the ARM architecture, including:
- ARMv5
- ARMv6
- ARMv7
- ARMv8
The AArch32 mode and its A32 instruction set are described in the ARMv8-A manual using the ASL specification language. A32 is part of the broader Armv8-A ISA.
Instruction count
The combined instruction set of A32, T32, and T16 contains 489 instructions (where a single instruction may have multiple encodings across instruction sets). A32 specifically accounted for 550 instruction encodings in the Examiner test-case-generation evaluation.
Use by Examiner
The Examiner differential testing system (presented at ASPLOS '22) targets the A32 instruction set as one of four instruction sets under test, comparing CPU emulator behavior (QEMU, Unicorn, Angr) against real ARM hardware to locate inconsistent instructions.
Examiner evaluation statistics (A32)
From the Examiner paper's Table 2 (A32 row):
| Metric | Examiner | Random | Ratio |
|---|---|---|---|
| Instruction streams generated | 870,221 | 578,845 | 66.5% |
| Instruction encodings covered | 550 | 415 | 75.5% |
| Instructions covered | 481 | 361 | 75.1% |
| Covered constraints | 4,718 | 3,725 | 79% |
The Examiner-generated test cases therefore covered roughly 75–79% as many encodings/instructions/constraints as the combined random and targeted generation, indicating that systematic test-case generation scales to A32 in a way that random testing alone does not.
Use by armshaker
The armshaker fuzzer targets A32 as part of its coverage of Armv8-A instruction sets. armshaker works by executing undefined instruction encodings and checking whether the execution produces a SIGILL (undefined-instruction exception); encodings that do not raise SIGILL are logged as "hidden" instructions. Because the A32 space is limited in size, armshaker can perform an exhaustive search over it on Armv8-A-based hardware and on emulators such as QEMU.
On AArch32 builds of armshaker, A32 is the default instruction set under test; the T32 (Thumb) instruction set can be selected with the -t option. On AArch64 builds, the fuzzer targets A64 by default, with cross-compilation to a 32-bit toolchain available to fuzz A32/T32 from AArch64.
Example A32/T32 armshaker invocations
- Check whether a QEMU release contains hidden VMUL instructions (in A32/T32):
$ ./fuzzer -s f3200d10 -m 004ff0ef -pVzg -f2 - Check whether a QEMU release contains hidden VQDMULL instructions (in A32/T32):
$ ./fuzzer -s f3900d00 -m 007ff0af -pVzg -f2
The README notes that armshaker's exhaustive fuzzing of A32 frequently reports millions of "hidden" instructions on some processors. This is typically an artifact of the processor treating undefined instructions with an unmatched condition code as NOPs (an implementation-defined behavior documented in section G1.16.1 of the Armv8 Architecture Reference Manual DDI0487E), and can be reduced by using the -c option to force the condition code to match.
The armshaker project reported that fuzzing of A32/T32 on Armv8-A systems found no hidden instructions attributable to hardware, but did reveal bugs in the QEMU emulator and the Linux kernel.
See also
- Armv8-A ISA — the architecture family that includes A32.
- Examiner — research tool that consumes A32 as one of its test-target instruction sets.
- armshaker — fuzzer that exhaustively searches A32 (and A64, T32) for hidden instructions.
- T32 instruction set
- T16 instruction set
- A64 instruction set