diff options
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/ARM/ARMBaseInstrInfo.h | 22 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 9 |
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)); |