diff options
Diffstat (limited to 'llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp')
-rw-r--r-- | llvm/lib/Target/Sparc/AsmParser/SparcAsmParser.cpp | 55 |
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) { |