[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
This commit is contained in:
Sander de Smalen 2018-05-14 11:54:41 +00:00
parent a6556e26ff
commit 93380371bb
7 changed files with 99 additions and 10 deletions

View File

@ -174,6 +174,35 @@ def : PRFM<"pstl2strm", 0x13>;
def : PRFM<"pstl3keep", 0x14>; def : PRFM<"pstl3keep", 0x14>;
def : PRFM<"pstl3strm", 0x15>; 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 // SVE Predicate patterns
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -128,6 +128,7 @@ private:
OperandMatchResultTy tryParseMRSSystemRegister(OperandVector &Operands); OperandMatchResultTy tryParseMRSSystemRegister(OperandVector &Operands);
OperandMatchResultTy tryParseSysReg(OperandVector &Operands); OperandMatchResultTy tryParseSysReg(OperandVector &Operands);
OperandMatchResultTy tryParseSysCROperand(OperandVector &Operands); OperandMatchResultTy tryParseSysCROperand(OperandVector &Operands);
template <bool IsSVEPrefetch = false>
OperandMatchResultTy tryParsePrefetch(OperandVector &Operands); OperandMatchResultTy tryParsePrefetch(OperandVector &Operands);
OperandMatchResultTy tryParsePSBHint(OperandVector &Operands); OperandMatchResultTy tryParsePSBHint(OperandVector &Operands);
OperandMatchResultTy tryParseAdrpLabel(OperandVector &Operands); OperandMatchResultTy tryParseAdrpLabel(OperandVector &Operands);
@ -2033,11 +2034,32 @@ AArch64AsmParser::tryParseSysCROperand(OperandVector &Operands) {
} }
/// tryParsePrefetch - Try to parse a prefetch operand. /// tryParsePrefetch - Try to parse a prefetch operand.
template <bool IsSVEPrefetch>
OperandMatchResultTy OperandMatchResultTy
AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) { AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) {
MCAsmParser &Parser = getParser(); MCAsmParser &Parser = getParser();
SMLoc S = getLoc(); SMLoc S = getLoc();
const AsmToken &Tok = Parser.getTok(); 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. // Either an identifier for named values or a 5-bit immediate.
// Eat optional hash. // Eat optional hash.
if (parseOptionalToken(AsmToken::Hash) || if (parseOptionalToken(AsmToken::Hash) ||
@ -2052,14 +2074,15 @@ AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) {
return MatchOperand_ParseFail; return MatchOperand_ParseFail;
} }
unsigned prfop = MCE->getValue(); unsigned prfop = MCE->getValue();
if (prfop > 31) { if (prfop > MaxVal) {
TokError("prefetch operand out of range, [0,31] expected"); TokError("prefetch operand out of range, [0," + utostr(MaxVal) +
"] expected");
return MatchOperand_ParseFail; return MatchOperand_ParseFail;
} }
auto PRFM = AArch64PRFM::lookupPRFMByEncoding(MCE->getValue()); auto PRFM = LookupByEncoding(MCE->getValue());
Operands.push_back(AArch64Operand::CreatePrefetch( Operands.push_back(AArch64Operand::CreatePrefetch(
prfop, PRFM ? PRFM->Name : "", S, getContext())); prfop, PRFM.getValueOr(""), S, getContext()));
return MatchOperand_Success; return MatchOperand_Success;
} }
@ -2068,7 +2091,7 @@ AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) {
return MatchOperand_ParseFail; return MatchOperand_ParseFail;
} }
auto PRFM = AArch64PRFM::lookupPRFMByName(Tok.getString()); auto PRFM = LookupByName(Tok.getString());
if (!PRFM) { if (!PRFM) {
TokError("pre-fetch hint expected"); TokError("pre-fetch hint expected");
return MatchOperand_ParseFail; return MatchOperand_ParseFail;
@ -2076,7 +2099,7 @@ AArch64AsmParser::tryParsePrefetch(OperandVector &Operands) {
Parser.Lex(); // Eat identifier token. Parser.Lex(); // Eat identifier token.
Operands.push_back(AArch64Operand::CreatePrefetch( Operands.push_back(AArch64Operand::CreatePrefetch(
PRFM->Encoding, Tok.getString(), S, getContext())); *PRFM, Tok.getString(), S, getContext()));
return MatchOperand_Success; return MatchOperand_Success;
} }

View File

@ -1061,15 +1061,22 @@ void AArch64InstPrinter::printAMIndexedWB(const MCInst *MI, unsigned OpNum,
O << ']'; O << ']';
} }
template <bool IsSVEPrefetch>
void AArch64InstPrinter::printPrefetchOp(const MCInst *MI, unsigned OpNum, void AArch64InstPrinter::printPrefetchOp(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI, const MCSubtargetInfo &STI,
raw_ostream &O) { raw_ostream &O) {
unsigned prfop = MI->getOperand(OpNum).getImm(); unsigned prfop = MI->getOperand(OpNum).getImm();
auto PRFM = AArch64PRFM::lookupPRFMByEncoding(prfop); if (IsSVEPrefetch) {
if (PRFM) if (auto PRFM = AArch64SVEPRFM::lookupSVEPRFMByEncoding(prfop)) {
O << PRFM->Name;
return;
}
} else if (auto PRFM = AArch64PRFM::lookupPRFMByEncoding(prfop)) {
O << PRFM->Name; O << PRFM->Name;
else return;
O << '#' << formatImm(prfop); }
O << '#' << formatImm(prfop);
} }
void AArch64InstPrinter::printPSBHintOp(const MCInst *MI, unsigned OpNum, void AArch64InstPrinter::printPSBHintOp(const MCInst *MI, unsigned OpNum,

View File

@ -123,6 +123,7 @@ protected:
void printImmScale(const MCInst *MI, unsigned OpNum, void printImmScale(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O); const MCSubtargetInfo &STI, raw_ostream &O);
template <bool IsSVEPrefetch = false>
void printPrefetchOp(const MCInst *MI, unsigned OpNum, void printPrefetchOp(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O); const MCSubtargetInfo &STI, raw_ostream &O);

View File

@ -27,6 +27,20 @@ def sve_pred_enum : Operand<i32>, ImmLeaf<i32, [{
let ParserMatchClass = SVEPatternOperand; 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 { class SVELogicalImmOperand<int Width> : AsmOperandClass {
let Name = "SVELogicalImm" # Width; let Name = "SVELogicalImm" # Width;
let DiagnosticType = "LogicalSecondSource"; let DiagnosticType = "LogicalSecondSource";

View File

@ -60,6 +60,13 @@ namespace llvm {
} }
} }
namespace llvm {
namespace AArch64SVEPRFM {
#define GET_SVEPRFM_IMPL
#include "AArch64GenSystemOperands.inc"
}
}
namespace llvm { namespace llvm {
namespace AArch64SVEPredPattern { namespace AArch64SVEPredPattern {
#define GET_SVEPREDPAT_IMPL #define GET_SVEPREDPAT_IMPL

View File

@ -335,6 +335,14 @@ namespace AArch64PRFM {
#include "AArch64GenSystemOperands.inc" #include "AArch64GenSystemOperands.inc"
} }
namespace AArch64SVEPRFM {
struct SVEPRFM : SysAlias {
using SysAlias::SysAlias;
};
#define GET_SVEPRFM_DECL
#include "AArch64GenSystemOperands.inc"
}
namespace AArch64SVEPredPattern { namespace AArch64SVEPredPattern {
struct SVEPREDPAT { struct SVEPREDPAT {
const char *Name; const char *Name;