diff options
author | Sander de Smalen <sander.desmalen@arm.com> | 2018-05-14 11:54:41 +0000 |
---|---|---|
committer | Sander de Smalen <sander.desmalen@arm.com> | 2018-05-14 11:54:41 +0000 |
commit | e2c1bdb4dd5f2bf5f1e122962dcfb4c3730b97a6 (patch) | |
tree | 11101dbf1e2a5de879e5d422f17fe57998553e35 | |
parent | 4f14c9bd165dddc6c064c71f658dd86e214a6ef8 (diff) |
[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
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@332234 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/AArch64/AArch64SystemOperands.td | 29 | ||||
-rw-r--r-- | lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp | 35 | ||||
-rw-r--r-- | lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp | 15 | ||||
-rw-r--r-- | lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h | 1 | ||||
-rw-r--r-- | lib/Target/AArch64/SVEInstrFormats.td | 14 | ||||
-rw-r--r-- | lib/Target/AArch64/Utils/AArch64BaseInfo.cpp | 7 | ||||
-rw-r--r-- | 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 @@ -175,6 +175,35 @@ def : PRFM<"pstl3keep", 0x14>; def : PRFM<"pstl3strm", 0x15>; //===----------------------------------------------------------------------===// +// SVE Prefetch instruction options. +//===----------------------------------------------------------------------===// + +class SVEPRFM<string name, bits<4> 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 <bool IsSVEPrefetch = false> 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 <bool IsSVEPrefetch> 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<unsigned>(Res->Encoding); + } else if (auto Res = AArch64PRFM::lookupPRFMByName(N)) + return Optional<unsigned>(Res->Encoding); + return Optional<unsigned>(); + }; + + auto LookupByEncoding = [](unsigned E) { + if (IsSVEPrefetch) { + if (auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(E)) + return Optional<StringRef>(Res->Name); + } else if (auto Res = AArch64PRFM::lookupPRFMByEncoding(E)) + return Optional<StringRef>(Res->Name); + return Optional<StringRef>(); + }; + 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 <bool IsSVEPrefetch> 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 <bool IsSVEPrefetch = false> 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<i32>, ImmLeaf<i32, [{ let ParserMatchClass = SVEPatternOperand; } +def SVEPrefetchOperand : AsmOperandClass { + let Name = "SVEPrefetch"; + let ParserMethod = "tryParsePrefetch<true>"; + let PredicateMethod = "isPrefetch"; + let RenderMethod = "addPrefetchOperands"; +} + +def sve_prfop : Operand<i32>, ImmLeaf<i32, [{ + return (((uint32_t)Imm) <= 15); + }]> { + let PrintMethod = "printPrefetchOp<true>"; + let ParserMatchClass = SVEPrefetchOperand; +} + class SVELogicalImmOperand<int Width> : 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 @@ -61,6 +61,13 @@ namespace llvm { } namespace llvm { + namespace AArch64SVEPRFM { +#define GET_SVEPRFM_IMPL +#include "AArch64GenSystemOperands.inc" + } +} + +namespace llvm { namespace AArch64SVEPredPattern { #define GET_SVEPREDPAT_IMPL #include "AArch64GenSystemOperands.inc" 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; |