Index: lib/Target/AArch64/AArch64SystemOperands.td =================================================================== --- lib/Target/AArch64/AArch64SystemOperands.td +++ lib/Target/AArch64/AArch64SystemOperands.td @@ -175,6 +175,37 @@ def : PRFM<"pstl3strm", 0x15>; //===----------------------------------------------------------------------===// +// SVE Predicate patterns +//===----------------------------------------------------------------------===// + +class SVEPREDPAT encoding> : SearchableTable { + let SearchableFields = ["Name", "Encoding"]; + let EnumValueField = "Encoding"; + + string Name = name; + bits<5> Encoding; + let Encoding = encoding; +} + +def : SVEPREDPAT<"pow2", 0x00>; +def : SVEPREDPAT<"vl1", 0x01>; +def : SVEPREDPAT<"vl2", 0x02>; +def : SVEPREDPAT<"vl3", 0x03>; +def : SVEPREDPAT<"vl4", 0x04>; +def : SVEPREDPAT<"vl5", 0x05>; +def : SVEPREDPAT<"vl6", 0x06>; +def : SVEPREDPAT<"vl7", 0x07>; +def : SVEPREDPAT<"vl8", 0x08>; +def : SVEPREDPAT<"vl16", 0x09>; +def : SVEPREDPAT<"vl32", 0x0a>; +def : SVEPREDPAT<"vl64", 0x0b>; +def : SVEPREDPAT<"vl128", 0x0c>; +def : SVEPREDPAT<"vl256", 0x0d>; +def : SVEPREDPAT<"mul4", 0x1d>; +def : SVEPREDPAT<"mul3", 0x1e>; +def : SVEPREDPAT<"all", 0x1f>; + +//===----------------------------------------------------------------------===// // PState instruction options. //===----------------------------------------------------------------------===// Index: lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -140,6 +140,8 @@ template OperandMatchResultTy tryParseSVEDataVector(OperandVector &Operands); OperandMatchResultTy tryParseSVEPredicateVector(OperandVector &Operands); + LLVM_ATTRIBUTE_UNUSED OperandMatchResultTy + tryParseSVEPattern(OperandVector &Operands); public: enum AArch64MatchResultTy { @@ -516,6 +518,16 @@ return (Val >= -1024 && Val <= 1008 && (Val & 15) == 0); } + bool isSVEPattern() const { + if (!isImm()) + return false; + auto *MCE = dyn_cast(getImm()); + if (!MCE) + return false; + int64_t Val = MCE->getValue(); + return (Val >= 0 && Val < 32); + } + bool isSymbolicUImm12Offset(const MCExpr *Expr, unsigned Scale) const { AArch64MCExpr::VariantKind ELFRefKind; MCSymbolRefExpr::VariantKind DarwinRefKind; @@ -4717,3 +4729,47 @@ return MatchOperand_Success; } + +OperandMatchResultTy +AArch64AsmParser::tryParseSVEPattern(OperandVector &Operands) { + MCAsmParser &Parser = getParser(); + + SMLoc SS = getLoc(); + const AsmToken &TokE = Parser.getTok(); + bool IsHash = TokE.is(AsmToken::Hash); + + if (!IsHash && TokE.isNot(AsmToken::Identifier)) + return MatchOperand_NoMatch; + + int64_t Pattern; + if (IsHash) { + Parser.Lex(); // Eat hash + + // Parse the immediate operand. + const MCExpr *ImmVal; + SS = getLoc(); + if (Parser.parseExpression(ImmVal)) + return MatchOperand_ParseFail; + + auto *MCE = dyn_cast(ImmVal); + if (!MCE) + return MatchOperand_ParseFail; + + Pattern = MCE->getValue(); + } else { + // Parse the pattern + auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.getString()); + if (!Pat) + return MatchOperand_NoMatch; + + Parser.Lex(); + Pattern = Pat->Encoding; + assert(Pattern >= 0 && Pattern < 32); + } + + Operands.push_back( + AArch64Operand::CreateImm(MCConstantExpr::create(Pattern, getContext()), + SS, getLoc(), getContext())); + + return MatchOperand_Success; +} Index: lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h =================================================================== --- lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h +++ lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h @@ -17,6 +17,7 @@ #include "MCTargetDesc/AArch64MCTargetDesc.h" #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCInstPrinter.h" +#include "../Utils/AArch64BaseInfo.h" namespace llvm { @@ -165,6 +166,8 @@ void printGPRSeqPairsClassOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); + void printSVEPattern(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); template void printSVERegOp(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); Index: lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp =================================================================== --- lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp +++ lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp @@ -1340,6 +1340,16 @@ O << "#" << (Val * Angle) + Remainder; } +void AArch64InstPrinter::printSVEPattern(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, + raw_ostream &O) { + unsigned Val = MI->getOperand(OpNum).getImm(); + if (auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByEncoding(Val)) + O << Pat->Name; + else + O << '#' << formatImm(Val); +} + template void AArch64InstPrinter::printSVERegOp(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, Index: lib/Target/AArch64/Utils/AArch64BaseInfo.h =================================================================== --- lib/Target/AArch64/Utils/AArch64BaseInfo.h +++ lib/Target/AArch64/Utils/AArch64BaseInfo.h @@ -335,6 +335,15 @@ #include "AArch64GenSystemOperands.inc" } +namespace AArch64SVEPredPattern { + struct SVEPREDPAT { + const char *Name; + uint16_t Encoding; + }; +#define GET_SVEPREDPAT_DECL +#include "AArch64GenSystemOperands.inc" +} + namespace AArch64PState { struct PState : SysAlias{ using SysAlias::SysAlias; Index: lib/Target/AArch64/Utils/AArch64BaseInfo.cpp =================================================================== --- lib/Target/AArch64/Utils/AArch64BaseInfo.cpp +++ lib/Target/AArch64/Utils/AArch64BaseInfo.cpp @@ -61,6 +61,13 @@ } namespace llvm { + namespace AArch64SVEPredPattern { +#define GET_SVEPREDPAT_IMPL +#include "AArch64GenSystemOperands.inc" + } +} + +namespace llvm { namespace AArch64PState { #define GET_PSTATE_IMPL #include "AArch64GenSystemOperands.inc"