aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSander de Smalen <sander.desmalen@arm.com>2018-05-14 11:54:41 +0000
committerSander de Smalen <sander.desmalen@arm.com>2018-05-14 11:54:41 +0000
commite2c1bdb4dd5f2bf5f1e122962dcfb4c3730b97a6 (patch)
tree11101dbf1e2a5de879e5d422f17fe57998553e35
parent4f14c9bd165dddc6c064c71f658dd86e214a6ef8 (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.td29
-rw-r--r--lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp35
-rw-r--r--lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp15
-rw-r--r--lib/Target/AArch64/InstPrinter/AArch64InstPrinter.h1
-rw-r--r--lib/Target/AArch64/SVEInstrFormats.td14
-rw-r--r--lib/Target/AArch64/Utils/AArch64BaseInfo.cpp7
-rw-r--r--lib/Target/AArch64/Utils/AArch64BaseInfo.h8
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;