The Linux kernel uses quite some mcr/mrc instructions throughout the ARM port. Probably most of them could be converted to the appropriate vmsr/vmrs instructions along with appropriate FPU definition, e.g.:
arch/arm/vfp/vfpmodule.c:345:2: error: invalid operand for instruction fmxr(FPEXC, fpexc & ~(FPEXC_EX|FPEXC_DEX|FPEXC_FP2V|FPEXC_VV|FPEXC_TRAP_MASK)); ^ arch/arm/vfp/vfpinstr.h:82:6: note: expanded from macro 'fmxr' asm("mcr p10, 7, %0, " vfpreg(_vfp_) ", cr0, 0 @ fmxr " #_vfp_ ", %0" \ ^ <inline asm>:1:6: note: instantiated into assembly here mcr p10, 7, r0, cr8, cr0, 0 @ fmxr FPEXC, r0 ^
However, there is at least one case where an unofficial/(SoC specific?) control register is accessed:
static u32 venum_read_pmresr(void) { u32 val; asm volatile("mrc p10, 7, %0, c11, c0, 0" : "=r" (val)); return val; }
There is no register definition for control register 11 in lib/Target/ARM/ARMRegisterInfo.td.
This patch converts the restriction of mcr/mrc cp10/cp11 instructions to warnings. The warnings can be suppressed using -no-deprecated-warn which is probably what the Linux kernel will use for the time being.
See also the discussion on the kernel side, tracked in this issue: https://github.com/ClangBuiltLinux/linux/issues/306.
I think it's worth leaving a comment here to explain why we're not disallowing CP10 and CP11. The point of this function is to centralize all the coprocessor validity tests in one place, so I can easily imagine someone else coming along later and adding the "missing" one if there isn't something here telling them that it's omitted on purpose.