From 5f693d0b9020185954999034fa9583af4c7852ea Mon Sep 17 00:00:00 2001 From: Sander de Smalen Date: Mon, 14 May 2018 11:54:41 +0000 Subject: [PATCH] [AArch64][SVE] Extend parsing of Prefetch operation for SVE. Reviewers: rengolin, fhahn, samparker, SjoerdMeijer, javed.absar Reviewed By: fhahn Differential Revision: https://reviews.llvm.org/D46681 llvm-svn: 332234 --- lib/Target/AArch64/AArch64SystemOperands.td | 29 +++++++++++++++ .../AArch64/AsmParser/AArch64AsmParser.cpp | 35 +++++++++++++++---- .../InstPrinter/AArch64InstPrinter.cpp | 15 +++++--- .../AArch64/InstPrinter/AArch64InstPrinter.h | 1 + lib/Target/AArch64/SVEInstrFormats.td | 14 ++++++++ lib/Target/AArch64/Utils/AArch64BaseInfo.cpp | 7 ++++ lib/Target/AArch64/Utils/AArch64BaseInfo.h | 8 +++++ 7 files changed, 99 insertions(+), 10 deletions(-) diff --git a/lib/Target/AArch64/AArch64SystemOperands.td b/lib/Target/AArch64/AArch64SystemOperands.td index 2630d697bee..cc1fb58e28a 100644 --- a/lib/Target/AArch64/AArch64SystemOperands.td +++ b/lib/Target/AArch64/AArch64SystemOperands.td @@ -174,6 +174,35 @@ def : PRFM<"pstl2strm", 0x13>; def : PRFM<"pstl3keep", 0x14>; 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 //===----------------------------------------------------------------------===// diff --git a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 705d492e0a9..2a87c886ff5 100644 --- a/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -128,6 +128,7 @@ private: 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 @@ AArch64AsmParser::tryParseSysCROperand(OperandVector &Operands) { } /// 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 @@ AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) { 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 @@ AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) { 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 @@ AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) { Parser.Lex(); // Eat identifier token. Operands.push_back(AArch64Operand::CreatePrefetch( - PRFM->Encoding, Tok.getString(), S, getContext())); + *PRFM, Tok.getString(), S, getContext())); return MatchOperand_Success; } diff --git a/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp b/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp index e743e5f42ea..03f1653ffd4 100644 --- a/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp +++ b/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp @@ -1061,15 +1061,22 @@ void AArch64InstPrinter::printAMIndexedWB(const MCInst *MI, unsigned OpNum, 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, diff --git a/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h b/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h index 63a9ef82c6a..bd970378b0c 100644 --- a/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h +++ b/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h @@ -123,6 +123,7 @@ protected: 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); diff --git a/lib/Target/AArch64/SVEInstrFormats.td b/lib/Target/AArch64/SVEInstrFormats.td index 9fb294d42da..61175e3a48d 100644 --- a/lib/Target/AArch64/SVEInstrFormats.td +++ b/lib/Target/AArch64/SVEInstrFormats.td @@ -27,6 +27,20 @@ def sve_pred_enum : Operand, ImmLeaf, ImmLeaf { + let PrintMethod = "printPrefetchOp"; + let ParserMatchClass = SVEPrefetchOperand; +} + class SVELogicalImmOperand : AsmOperandClass { let Name = "SVELogicalImm" # Width; let DiagnosticType = "LogicalSecondSource"; diff --git a/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp b/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp index a9c4f3854de..3fa383bada1 100644 --- a/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp +++ b/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp @@ -60,6 +60,13 @@ namespace llvm { } } +namespace llvm { + namespace AArch64SVEPRFM { +#define GET_SVEPRFM_IMPL +#include "AArch64GenSystemOperands.inc" + } +} + namespace llvm { namespace AArch64SVEPredPattern { #define GET_SVEPREDPAT_IMPL diff --git a/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/lib/Target/AArch64/Utils/AArch64BaseInfo.h index 59390e16d8c..26f2a86272b 100644 --- a/lib/Target/AArch64/Utils/AArch64BaseInfo.h +++ b/lib/Target/AArch64/Utils/AArch64BaseInfo.h @@ -335,6 +335,14 @@ namespace AArch64PRFM { #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;