Index: llvm/lib/Target/ARM/ARMBaseInstrInfo.h =================================================================== --- llvm/lib/Target/ARM/ARMBaseInstrInfo.h +++ llvm/lib/Target/ARM/ARMBaseInstrInfo.h @@ -685,15 +685,16 @@ /// vary with the subtarget. static inline bool isValidCoprocessorNumber(unsigned Num, const FeatureBitset& featureBits) { + // In Armv7 and Armv8-M CP10 and CP11 clash with VFP/NEON, however, the + // coprocessor is still valid for CDP/MCR/MRC and friends. Allowing it is + // useful for code which is shared with older architectures which do not know + // the new VFP/NEON mnemonics. + // Armv8-A disallows everything *other* than 111x (CP14 and CP15). if (featureBits[ARM::HasV8Ops] && (Num & 0xE) != 0xE) return false; - // Armv7 disallows 101x (CP10 and CP11), which clash with VFP/NEON. - if (featureBits[ARM::HasV7Ops] && (Num & 0xE) == 0xA) - return false; - - // Armv8.1-M also disallows 100x (CP8,CP9) and 111x (CP14,CP15) + // Armv8.1-M disallows 100x (CP8,CP9) and 111x (CP14,CP15) // which clash with MVE. if (featureBits[ARM::HasV8_1MMainlineOps] && ((Num & 0xE) == 0x8 || (Num & 0xE) == 0xE)) Index: llvm/lib/Target/ARM/ARMInstrInfo.td =================================================================== --- llvm/lib/Target/ARM/ARMInstrInfo.td +++ llvm/lib/Target/ARM/ARMInstrInfo.td @@ -5479,7 +5479,8 @@ def MRC : MovRCopro<"mrc", 1 /* from coprocessor to ARM core register */, (outs GPRwithAPSR:$Rt), (ins p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm, - imm0_7:$opc2), []>; + imm0_7:$opc2), []>, + ComplexDeprecationPredicate<"MRC">; def : ARMInstAlias<"mrc${p} $cop, $opc1, $Rt, $CRn, $CRm", (MRC GPRwithAPSR:$Rt, p_imm:$cop, imm0_7:$opc1, c_imm:$CRn, c_imm:$CRm, 0, pred:$p)>; Index: llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp =================================================================== --- llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -63,6 +63,25 @@ return true; } } + if (STI.getFeatureBits()[llvm::ARM::HasV7Ops] && + ((MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 10) || + (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 11))) { + Info = "since v7, cp10 and cp11 are reserved for advanced SIMD or floating " + "point instructions"; + return true; + } + return false; +} + +static bool getMRCDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI, + std::string &Info) { + if (STI.getFeatureBits()[llvm::ARM::HasV7Ops] && + ((MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 10) || + (MI.getOperand(0).isImm() && MI.getOperand(0).getImm() == 11))) { + Info = "since v7, cp10 and cp11 are reserved for advanced SIMD or floating " + "point instructions"; + return true; + } return false; } Index: llvm/test/MC/ARM/coprocessors.s =================================================================== --- llvm/test/MC/ARM/coprocessors.s +++ llvm/test/MC/ARM/coprocessors.s @@ -1,13 +1,11 @@ -@ RUN: not llvm-mc -triple=armv7 < %s 2> %t | FileCheck --check-prefix=ACCEPT-01234567CD --check-prefix=ACCEPT-89 --check-prefix=ACCEPT-EF %s -@ RUN: FileCheck --check-prefix=REJECT-AB < %t %s -@ RUN: not llvm-mc -triple=thumbv7 < %s 2> %t | FileCheck --check-prefix=ACCEPT-01234567CD --check-prefix=ACCEPT-89 --check-prefix=ACCEPT-EF %s -@ RUN: FileCheck --check-prefix=REJECT-AB < %t %s +@ RUN: llvm-mc -triple=armv7 < %s 2> %t | FileCheck --check-prefix=ACCEPT-01234567CD --check-prefix=ACCEPT-89 --check-prefix=ACCEPT-AB --check-prefix=ACCEPT-EF %s +@ RUN: llvm-mc -triple=thumbv7 < %s 2> %t | FileCheck --check-prefix=ACCEPT-01234567CD --check-prefix=ACCEPT-89 --check-prefix=ACCEPT-AB --check-prefix=ACCEPT-EF %s @ RUN: not llvm-mc -triple=armv8 < %s 2> %t | FileCheck --check-prefix=ACCEPT-EF %s @ RUN: FileCheck --check-prefix=REJECT-01234567CD --check-prefix=REJECT-89 --check-prefix=REJECT-AB < %t %s @ RUN: not llvm-mc -triple=thumbv8 < %s 2> %t | FileCheck --check-prefix=ACCEPT-EF %s @ RUN: FileCheck --check-prefix=REJECT-01234567CD --check-prefix=REJECT-89 --check-prefix=REJECT-AB < %t %s -@ RUN: not llvm-mc -triple=thumbv8.1m.main < %s 2> %t | FileCheck --check-prefix=ACCEPT-01234567CD %s -@ RUN: FileCheck --check-prefix=REJECT-89 --check-prefix=REJECT-AB --check-prefix=REJECT-EF < %t %s +@ RUN: not llvm-mc -triple=thumbv8.1m.main < %s 2> %t | FileCheck --check-prefix=ACCEPT-01234567CD --check-prefix=ACCEPT-AB %s +@ RUN: FileCheck --check-prefix=REJECT-89 --check-prefix=REJECT-EF < %t %s mrc p0, #1, r2, c3, c4, #5 @ ACCEPT-01234567CD: mrc p0, #1, r2, c3, c4, #5 Index: llvm/test/MC/ARM/diagnostics.s =================================================================== --- llvm/test/MC/ARM/diagnostics.s +++ llvm/test/MC/ARM/diagnostics.s @@ -173,8 +173,8 @@ @ p10 and p11 are reserved for NEON mcr p10, #2, r5, c1, c1, #4 mcrr p11, #8, r5, r4, c1 -@ CHECK-ERRORS: error: invalid operand for instruction -@ CHECK-ERRORS: error: invalid operand for instruction +@ CHECK-WARN: warning: since v7, cp10 and cp11 are reserved for advanced SIMD or floating point instructions +@ CHECK-WARN: warning: since v7, cp10 and cp11 are reserved for advanced SIMD or floating point instructions @ Out of range immediate for MOV movw r9, 0x10000