summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp')
-rw-r--r--llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp55
1 files changed, 55 insertions, 0 deletions
diff --git a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
index 35f52f7d279..691421e533e 100644
--- a/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
+++ b/llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp
@@ -78,6 +78,8 @@ class SparcAsmParser : public MCTargetAsmParser {
// Custom parse functions for Sparc specific operands.
OperandMatchResultTy parseMEMOperand(OperandVector &Operands);
+ OperandMatchResultTy parseMembarTag(OperandVector &Operands);
+
OperandMatchResultTy parseOperand(OperandVector &Operands, StringRef Name);
OperandMatchResultTy
@@ -256,6 +258,7 @@ public:
bool isMem() const override { return isMEMrr() || isMEMri(); }
bool isMEMrr() const { return Kind == k_MemoryReg; }
bool isMEMri() const { return Kind == k_MemoryImm; }
+ bool isMembarTag() const { return Kind == k_Immediate; }
bool isIntReg() const {
return (Kind == k_Register && Reg.Kind == rk_IntReg);
@@ -366,6 +369,12 @@ public:
addExpr(Inst, Expr);
}
+ void addMembarTagOperands(MCInst &Inst, unsigned N) const {
+ assert(N == 1 && "Invalid number of operands!");
+ const MCExpr *Expr = getImm();
+ addExpr(Inst, Expr);
+ }
+
static std::unique_ptr<SparcOperand> CreateToken(StringRef Str, SMLoc S) {
auto Op = make_unique<SparcOperand>(k_Token);
Op->Tok.Data = Str.data();
@@ -742,6 +751,52 @@ SparcAsmParser::parseMEMOperand(OperandVector &Operands) {
return MatchOperand_Success;
}
+OperandMatchResultTy SparcAsmParser::parseMembarTag(OperandVector &Operands) {
+ SMLoc S = Parser.getTok().getLoc();
+ const MCExpr *EVal;
+ int64_t ImmVal = 0;
+
+ std::unique_ptr<SparcOperand> Mask;
+ if (parseSparcAsmOperand(Mask) == MatchOperand_Success) {
+ if (!Mask->isImm() || !Mask->getImm()->evaluateAsAbsolute(ImmVal) ||
+ ImmVal < 0 || ImmVal > 127) {
+ Error(S, "invalid membar mask number");
+ return MatchOperand_ParseFail;
+ }
+ }
+
+ while (getLexer().getKind() == AsmToken::Hash) {
+ SMLoc TagStart = getLexer().getLoc();
+ Parser.Lex(); // Eat the '#'.
+ unsigned MaskVal = StringSwitch<unsigned>(Parser.getTok().getString())
+ .Case("LoadLoad", 0x1)
+ .Case("StoreLoad", 0x2)
+ .Case("LoadStore", 0x4)
+ .Case("StoreStore", 0x8)
+ .Case("Lookaside", 0x10)
+ .Case("MemIssue", 0x20)
+ .Case("Sync", 0x40)
+ .Default(0);
+
+ Parser.Lex(); // Eat the identifier token.
+
+ if (!MaskVal) {
+ Error(TagStart, "unknown membar tag");
+ return MatchOperand_ParseFail;
+ }
+
+ ImmVal |= MaskVal;
+
+ if (getLexer().getKind() == AsmToken::Pipe)
+ Parser.Lex(); // Eat the '|'.
+ }
+
+ EVal = MCConstantExpr::create(ImmVal, getContext());
+ SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
+ Operands.push_back(SparcOperand::CreateImm(EVal, S, E));
+ return MatchOperand_Success;
+}
+
OperandMatchResultTy
SparcAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
OpenPOWER on IntegriCloud