Index: llvm/trunk/lib/Target/AArch64/AArch64SystemOperands.td =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64SystemOperands.td +++ llvm/trunk/lib/Target/AArch64/AArch64SystemOperands.td @@ -175,6 +175,35 @@ def : PRFM<"pstl3strm", 0x15>; //===----------------------------------------------------------------------===// +// SVE Prefetch instruction options. +//===----------------------------------------------------------------------===// + +class SVEPRFM encoding> : SearchableTable { + let SearchableFields = ["Name", "Encoding"]; + let EnumValueField = "Encoding"; + + string Name = name; + bits<4> Encoding; + let Encoding = encoding; + code Requires = [{ {} }]; +} + +let Requires = [{ {AArch64::FeatureSVE} }] in { +def : SVEPRFM<"pldl1keep", 0x00>; +def : SVEPRFM<"pldl1strm", 0x01>; +def : SVEPRFM<"pldl2keep", 0x02>; +def : SVEPRFM<"pldl2strm", 0x03>; +def : SVEPRFM<"pldl3keep", 0x04>; +def : SVEPRFM<"pldl3strm", 0x05>; +def : SVEPRFM<"pstl1keep", 0x08>; +def : SVEPRFM<"pstl1strm", 0x09>; +def : SVEPRFM<"pstl2keep", 0x0a>; +def : SVEPRFM<"pstl2strm", 0x0b>; +def : SVEPRFM<"pstl3keep", 0x0c>; +def : SVEPRFM<"pstl3strm", 0x0d>; +} + +//===----------------------------------------------------------------------===// // SVE Predicate patterns //===----------------------------------------------------------------------===// Index: llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -128,6 +128,7 @@ OperandMatchResultTy tryParseMRSSystemRegister(OperandVector &Operands); OperandMatchResultTy tryParseSysReg(OperandVector &Operands); OperandMatchResultTy tryParseSysCROperand(OperandVector &Operands); + template OperandMatchResultTy tryParsePrefetch(OperandVector &Operands); OperandMatchResultTy tryParsePSBHint(OperandVector &Operands); OperandMatchResultTy tryParseAdrpLabel(OperandVector &Operands); @@ -2033,11 +2034,32 @@ } /// tryParsePrefetch - Try to parse a prefetch operand. +template OperandMatchResultTy AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) { MCAsmParser &Parser = getParser(); SMLoc S = getLoc(); const AsmToken &Tok = Parser.getTok(); + + auto LookupByName = [](StringRef N) { + if (IsSVEPrefetch) { + if (auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(N)) + return Optional(Res->Encoding); + } else if (auto Res = AArch64PRFM::lookupPRFMByName(N)) + return Optional(Res->Encoding); + return Optional(); + }; + + auto LookupByEncoding = [](unsigned E) { + if (IsSVEPrefetch) { + if (auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(E)) + return Optional(Res->Name); + } else if (auto Res = AArch64PRFM::lookupPRFMByEncoding(E)) + return Optional(Res->Name); + return Optional(); + }; + unsigned MaxVal = IsSVEPrefetch ? 15 : 31; + // Either an identifier for named values or a 5-bit immediate. // Eat optional hash. if (parseOptionalToken(AsmToken::Hash) || @@ -2052,14 +2074,15 @@ return MatchOperand_ParseFail; } unsigned prfop = MCE->getValue(); - if (prfop > 31) { - TokError("prefetch operand out of range, [0,31] expected"); + if (prfop > MaxVal) { + TokError("prefetch operand out of range, [0," + utostr(MaxVal) + + "] expected"); return MatchOperand_ParseFail; } - auto PRFM = AArch64PRFM::lookupPRFMByEncoding(MCE->getValue()); + auto PRFM = LookupByEncoding(MCE->getValue()); Operands.push_back(AArch64Operand::CreatePrefetch( - prfop, PRFM ? PRFM->Name : "", S, getContext())); + prfop, PRFM.getValueOr(""), S, getContext())); return MatchOperand_Success; } @@ -2068,7 +2091,7 @@ return MatchOperand_ParseFail; } - auto PRFM = AArch64PRFM::lookupPRFMByName(Tok.getString()); + auto PRFM = LookupByName(Tok.getString()); if (!PRFM) { TokError("pre-fetch hint expected"); return MatchOperand_ParseFail; @@ -2076,7 +2099,7 @@ Parser.Lex(); // Eat identifier token. Operands.push_back(AArch64Operand::CreatePrefetch( - PRFM->Encoding, Tok.getString(), S, getContext())); + *PRFM, Tok.getString(), S, getContext())); return MatchOperand_Success; } Index: llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h =================================================================== --- llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h +++ llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h @@ -123,6 +123,7 @@ void printImmScale(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); + template void printPrefetchOp(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); Index: llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp +++ llvm/trunk/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp @@ -1061,15 +1061,22 @@ O << ']'; } +template void AArch64InstPrinter::printPrefetchOp(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O) { unsigned prfop = MI->getOperand(OpNum).getImm(); - auto PRFM = AArch64PRFM::lookupPRFMByEncoding(prfop); - if (PRFM) + if (IsSVEPrefetch) { + if (auto PRFM = AArch64SVEPRFM::lookupSVEPRFMByEncoding(prfop)) { + O << PRFM->Name; + return; + } + } else if (auto PRFM = AArch64PRFM::lookupPRFMByEncoding(prfop)) { O << PRFM->Name; - else - O << '#' << formatImm(prfop); + return; + } + + O << '#' << formatImm(prfop); } void AArch64InstPrinter::printPSBHintOp(const MCInst *MI, unsigned OpNum, Index: llvm/trunk/lib/Target/AArch64/SVEInstrFormats.td =================================================================== --- llvm/trunk/lib/Target/AArch64/SVEInstrFormats.td +++ llvm/trunk/lib/Target/AArch64/SVEInstrFormats.td @@ -27,6 +27,20 @@ let ParserMatchClass = SVEPatternOperand; } +def SVEPrefetchOperand : AsmOperandClass { + let Name = "SVEPrefetch"; + let ParserMethod = "tryParsePrefetch"; + let PredicateMethod = "isPrefetch"; + let RenderMethod = "addPrefetchOperands"; +} + +def sve_prfop : Operand, ImmLeaf { + let PrintMethod = "printPrefetchOp"; + let ParserMatchClass = SVEPrefetchOperand; +} + class SVELogicalImmOperand : AsmOperandClass { let Name = "SVELogicalImm" # Width; let DiagnosticType = "LogicalSecondSource"; Index: llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.h =================================================================== --- llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.h +++ llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.h @@ -335,6 +335,14 @@ #include "AArch64GenSystemOperands.inc" } +namespace AArch64SVEPRFM { + struct SVEPRFM : SysAlias { + using SysAlias::SysAlias; + }; +#define GET_SVEPRFM_DECL +#include "AArch64GenSystemOperands.inc" +} + namespace AArch64SVEPredPattern { struct SVEPREDPAT { const char *Name; Index: llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp =================================================================== --- llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp +++ llvm/trunk/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp @@ -61,6 +61,13 @@ } namespace llvm { + namespace AArch64SVEPRFM { +#define GET_SVEPRFM_IMPL +#include "AArch64GenSystemOperands.inc" + } +} + +namespace llvm { namespace AArch64SVEPredPattern { #define GET_SVEPREDPAT_IMPL #include "AArch64GenSystemOperands.inc"