30.5.3. ARM system register instructions

Examples of using them can be found at: dump_regs

aarch64 only uses exactly 2 instructions:

  • MRS: reads a system register to a regular register

  • MSR: writes to the system register

aarch32 is a bit more messy due to older setups, we have both:

  • MRS and MSR which are much like in aarch64

  • coprocessor accesses:

    • MRC: reads a system register, C means coprocessor, which is how system registers were previously known as

    • MCR: write to the system register

    • MRRC: like MRC, but used for the system registers that are marked as 64-bit, and reads to two general purpose register

    • MCRR: write version of MCRR

TODO why both? For example, as mentioned at https://stackoverflow.com/questions/62920281/cross-compilng-c-program-for-armv8-a-in-linux-x86-64-system/62922677#62922677 a register that was accessed with MRC in armv7 can move to MRS in aarch64, as is the case for:

mrs r0, ctr     /* aarch32 */
mrc x0, ctr_el0 /* aarch64 */

Other functionality has moved away from coprocessors into actual instructions, e.g. cache invalidation:

/* aarch32: DCISW, Data Cache line Invalidate by Set/Way. */
mcr     p15, 0, r5, c7, c6, 2

/* aarch64: moved to one of the DC instruction variants. */
dc isw

ARMv8 architecture reference manual db G1.19.4 "Background to the System register interface" says that only CP14 and CP15 are specified by the ISA:

The interface to the System registers was originally defined as part of a generic coprocessor interface, that gave access to 15 coprocessors, CP0 - CP15. Of these, CP8 - CP15 were reserved for use by Arm, while CP0 - CP7 were available for IMPLEMENTATION DEFINED coprocessors.

and the actual coprocessor registers are specified in Chapter G7 "AArch32 System Register Encoding" at:

  • CP14: Table G7-1 "Mapping of (coproc ==0b1110) MCR, MRC, and MRRC instruction arguments to System registers"

  • CP15: Table G7-3 "VMSAv8-32 (coproc==0b1111) register summary, in MCR/MRC parameter order."

The actual MRC assembly does not exactly match the order of that table, this is how you can decode it, sample MCR:

mcr     p15, 0, r5, c7, c6, 2

what each part means:

mcr     p<coproc>, <opc1>, <src-dest-reg>, <CRn>, <CRm>, <opc2>