[AArch64][SVE] Asm: Predicate patterns

Summary:
This patch adds support for parsing/printing of named or unnamed
patterns that are used in SVE's PTRUE instruction, amongst others.

The pattern can be specified as a named pattern to initialize the predicate
vector or it can be specified as an immediate in the range 0-31.

Reviewers: fhahn, rengolin, evandro, mcrosier, t.p.northover

Reviewed By: fhahn

Subscribers: aemerson, javed.absar, tschuett, kristof.beyls, llvm-commits

Differential Revision: https://reviews.llvm.org/D41818

llvm-svn: 323098
This commit is contained in:
Sander de Smalen 2018-01-22 10:46:00 +00:00
parent 0bbe66e7ac
commit 245e0e67f3
6 changed files with 116 additions and 0 deletions

View File

@ -174,6 +174,37 @@ def : PRFM<"pstl2strm", 0x13>;
def : PRFM<"pstl3keep", 0x14>;
def : PRFM<"pstl3strm", 0x15>;
//===----------------------------------------------------------------------===//
// SVE Predicate patterns
//===----------------------------------------------------------------------===//
class SVEPREDPAT<string name, bits<5> encoding> : SearchableTable {
let SearchableFields = ["Name", "Encoding"];
let EnumValueField = "Encoding";
string Name = name;
bits<5> Encoding;
let Encoding = encoding;
}
def : SVEPREDPAT<"pow2", 0x00>;
def : SVEPREDPAT<"vl1", 0x01>;
def : SVEPREDPAT<"vl2", 0x02>;
def : SVEPREDPAT<"vl3", 0x03>;
def : SVEPREDPAT<"vl4", 0x04>;
def : SVEPREDPAT<"vl5", 0x05>;
def : SVEPREDPAT<"vl6", 0x06>;
def : SVEPREDPAT<"vl7", 0x07>;
def : SVEPREDPAT<"vl8", 0x08>;
def : SVEPREDPAT<"vl16", 0x09>;
def : SVEPREDPAT<"vl32", 0x0a>;
def : SVEPREDPAT<"vl64", 0x0b>;
def : SVEPREDPAT<"vl128", 0x0c>;
def : SVEPREDPAT<"vl256", 0x0d>;
def : SVEPREDPAT<"mul4", 0x1d>;
def : SVEPREDPAT<"mul3", 0x1e>;
def : SVEPREDPAT<"all", 0x1f>;
//===----------------------------------------------------------------------===//
// PState instruction options.
//===----------------------------------------------------------------------===//

View File

@ -140,6 +140,8 @@ private:
template <bool ParseSuffix>
OperandMatchResultTy tryParseSVEDataVector(OperandVector &Operands);
OperandMatchResultTy tryParseSVEPredicateVector(OperandVector &Operands);
LLVM_ATTRIBUTE_UNUSED OperandMatchResultTy
tryParseSVEPattern(OperandVector &Operands);
public:
enum AArch64MatchResultTy {
@ -488,6 +490,16 @@ public:
return Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0;
}
bool isSVEPattern() const {
if (!isImm())
return false;
auto *MCE = dyn_cast<MCConstantExpr>(getImm());
if (!MCE)
return false;
int64_t Val = MCE->getValue();
return Val >= 0 && Val < 32;
}
bool isSymbolicUImm12Offset(const MCExpr *Expr, unsigned Scale) const {
AArch64MCExpr::VariantKind ELFRefKind;
MCSymbolRefExpr::VariantKind DarwinRefKind;
@ -4725,3 +4737,47 @@ AArch64AsmParser::tryParseSVEDataVector(OperandVector &Operands) {
return MatchOperand_Success;
}
OperandMatchResultTy
AArch64AsmParser::tryParseSVEPattern(OperandVector &Operands) {
MCAsmParser &Parser = getParser();
SMLoc SS = getLoc();
const AsmToken &TokE = Parser.getTok();
bool IsHash = TokE.is(AsmToken::Hash);
if (!IsHash && TokE.isNot(AsmToken::Identifier))
return MatchOperand_NoMatch;
int64_t Pattern;
if (IsHash) {
Parser.Lex(); // Eat hash
// Parse the immediate operand.
const MCExpr *ImmVal;
SS = getLoc();
if (Parser.parseExpression(ImmVal))
return MatchOperand_ParseFail;
auto *MCE = dyn_cast<MCConstantExpr>(ImmVal);
if (!MCE)
return MatchOperand_ParseFail;
Pattern = MCE->getValue();
} else {
// Parse the pattern
auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.getString());
if (!Pat)
return MatchOperand_NoMatch;
Parser.Lex();
Pattern = Pat->Encoding;
assert(Pattern >= 0 && Pattern < 32);
}
Operands.push_back(
AArch64Operand::CreateImm(MCConstantExpr::create(Pattern, getContext()),
SS, getLoc(), getContext()));
return MatchOperand_Success;
}

View File

@ -1340,6 +1340,16 @@ void AArch64InstPrinter::printComplexRotationOp(const MCInst *MI, unsigned OpNo,
O << "#" << (Val * Angle) + Remainder;
}
void AArch64InstPrinter::printSVEPattern(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI,
raw_ostream &O) {
unsigned Val = MI->getOperand(OpNum).getImm();
if (auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByEncoding(Val))
O << Pat->Name;
else
O << '#' << formatImm(Val);
}
template <char suffix>
void AArch64InstPrinter::printSVERegOp(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI,

View File

@ -17,6 +17,7 @@
#include "MCTargetDesc/AArch64MCTargetDesc.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCInstPrinter.h"
#include "../Utils/AArch64BaseInfo.h"
namespace llvm {
@ -165,6 +166,8 @@ protected:
void printGPRSeqPairsClassOperand(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI,
raw_ostream &O);
void printSVEPattern(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O);
template <char = 0>
void printSVERegOp(const MCInst *MI, unsigned OpNum,
const MCSubtargetInfo &STI, raw_ostream &O);

View File

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

View File

@ -335,6 +335,15 @@ namespace AArch64PRFM {
#include "AArch64GenSystemOperands.inc"
}
namespace AArch64SVEPredPattern {
struct SVEPREDPAT {
const char *Name;
uint16_t Encoding;
};
#define GET_SVEPREDPAT_DECL
#include "AArch64GenSystemOperands.inc"
}
namespace AArch64PState {
struct PState : SysAlias{
using SysAlias::SysAlias;