From b7d41a11cd31388e8b542b2d881f5c9d7130b95e Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Wed, 24 Jun 2020 21:50:17 +0200 Subject: [PATCH] [ARM] Make cp10 and cp11 usage a warning The ARM ARM considers p10/p11 valid arguments for MCR/MRC instructions. MRC instructions with p10 arguments are also used in kernel code which is shared for different architectures. Turn usage of p10/p11 to warnings for ARMv7/ARMv8-M. Reviewers: rengolin, olista01, t.p.northover, efriedma, psmith, simon_tatham Reviewed By: simon_tatham Subscribers: hiraditya, danielkiss, jcai19, tpimh, nickdesaulniers, peter.smith, javed.absar, kristof.beyls, jdoerfert, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D59733 --- llvm/lib/Target/ARM/ARMBaseInstrInfo.h | 11 ++++++----- llvm/lib/Target/ARM/ARMInstrInfo.td | 3 ++- llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp | 19 +++++++++++++++++++ llvm/test/MC/ARM/coprocessors.s | 10 ++++------ llvm/test/MC/ARM/diagnostics.s | 4 ++-- 5 files changed, 33 insertions(+), 14 deletions(-) diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h index 615d72d..5e3525e 100644 --- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h +++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h @@ -685,15 +685,16 @@ static inline bool isMovRegOpcode(int Opc) { /// 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)) diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index 6b990a5..3fed1cd 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -5479,7 +5479,8 @@ def : ARMInstAlias<"mcr${p} $cop, $opc1, $Rt, $CRn, $CRm", 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)>; diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp index 6ce5a19..05d73cc 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp @@ -63,6 +63,25 @@ static bool getMCRDeprecationInfo(MCInst &MI, const MCSubtargetInfo &STI, 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; } diff --git a/llvm/test/MC/ARM/coprocessors.s b/llvm/test/MC/ARM/coprocessors.s index d2ef5815..5ab29cc 100644 --- a/llvm/test/MC/ARM/coprocessors.s +++ b/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 diff --git a/llvm/test/MC/ARM/diagnostics.s b/llvm/test/MC/ARM/diagnostics.s index 1e84a80..e6d80ea 100644 --- a/llvm/test/MC/ARM/diagnostics.s +++ b/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 -- 2.7.4