summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/ARM/ARMBaseInstrInfo.h22
-rw-r--r--llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp4
-rw-r--r--llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp9
3 files changed, 25 insertions, 10 deletions
diff --git a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h
index 465d13803fd..c28983fcc15 100644
--- a/llvm/lib/Target/ARM/ARMBaseInstrInfo.h
+++ b/llvm/lib/Target/ARM/ARMBaseInstrInfo.h
@@ -524,6 +524,28 @@ static inline bool isPushOpcode(int Opc) {
Opc == ARM::STMDB_UPD || Opc == ARM::VSTMDDB_UPD;
}
+/// isValidCoprocessorNumber - decide whether an explicit coprocessor
+/// number is legal in generic instructions like CDP. The answer can
+/// vary with the subtarget.
+static inline bool isValidCoprocessorNumber(unsigned Num,
+ const FeatureBitset& featureBits) {
+ // 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)
+ // which clash with MVE.
+ if (featureBits[ARM::HasV8_1MMainlineOps] &&
+ ((Num & 0xE) == 0x8 || (Num & 0xE) == 0xE))
+ return false;
+
+ return true;
+}
+
/// getInstrPredicate - If instruction is predicated, returns its predicate
/// condition, otherwise returns AL. It also returns the condition code
/// register by reference.
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
index 76734a6b13e..3ff3af9dd58 100644
--- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//
#include "ARMFeatures.h"
+#include "ARMBaseInstrInfo.h"
#include "Utils/ARMBaseInfo.h"
#include "MCTargetDesc/ARMAddressingModes.h"
#include "MCTargetDesc/ARMBaseInfo.h"
@@ -4167,8 +4168,7 @@ ARMAsmParser::parseCoprocNumOperand(OperandVector &Operands) {
int Num = MatchCoprocessorOperandName(Tok.getString().lower(), 'p');
if (Num == -1)
return MatchOperand_NoMatch;
- // ARMv7 and v8 don't allow cp10/cp11 due to VFP/NEON specific instructions
- if ((hasV7Ops() || hasV8Ops()) && (Num == 10 || Num == 11))
+ if (!isValidCoprocessorNumber(Num, getSTI().getFeatureBits()))
return MatchOperand_NoMatch;
Parser.Lex(); // Eat identifier token.
diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index c6ae7d26bf9..548fb10fb3f 100644
--- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
@@ -4486,14 +4486,7 @@ static DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Val,
const FeatureBitset &featureBits =
((const MCDisassembler*)Decoder)->getSubtargetInfo().getFeatureBits();
- if (featureBits[ARM::HasV8Ops] && !(Val == 14 || Val == 15))
- return MCDisassembler::Fail;
-
- // For Armv8.1-M Mainline coprocessors matching 100x,101x or 111x should
- // decode as VFP/MVE instructions.
- if (featureBits[ARM::HasV8_1MMainlineOps] &&
- ((Val & 0xE) == 0x8 || (Val & 0xE) == 0xA ||
- (Val & 0xE) == 0xE))
+ if (!isValidCoprocessorNumber(Val, featureBits))
return MCDisassembler::Fail;
Inst.addOperand(MCOperand::createImm(Val));
OpenPOWER on IntegriCloud