35#define DEBUG_TYPE "avr-asm-parser"
44 const std::string GENERATE_STUBS =
"gs";
46 enum AVRMatchResultTy {
47 Match_InvalidRegisterOnTiny = FIRST_TARGET_MATCH_RESULT_TY + 1,
50#define GET_ASSEMBLER_HEADER
51#include "AVRGenAsmMatcher.inc"
53 bool matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
56 bool MatchingInlineAsm)
override;
60 SMLoc &EndLoc)
override;
72 MCRegister parseRegister(
bool RestoreOnFailure =
false);
79 unsigned Kind)
override;
82 MCRegisterClass const *Class = &getAVRMCRegisterClass(AVR::DREGSRegClassID);
86 bool emit(MCInst &Instruction, SMLoc
const &Loc, MCStreamer &Out)
const;
88 uint64_t
const &ErrorInfo);
89 bool missingFeature(SMLoc
const &Loc, uint64_t
const &ErrorInfo);
91 ParseStatus parseLiteralValues(
unsigned SizeInBytes, SMLoc L);
94 AVRAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
95 const MCInstrInfo &MII)
96 : MCTargetAsmParser(STI, MII), Parser(Parser) {
100 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
103 MCAsmParser &getParser()
const {
return Parser; }
104 AsmLexer &getLexer()
const {
return Parser.getLexer(); }
109 typedef MCParsedAsmOperand Base;
110 enum KindTy { k_Immediate, k_Register, k_Token, k_Memri } Kind;
113 AVROperand(StringRef Tok, SMLoc
const &S)
114 : Kind(k_Token), Tok(Tok), Start(S), End(S) {}
115 AVROperand(MCRegister
Reg, SMLoc
const &S, SMLoc
const &
E)
116 : Kind(k_Register),
RegImm({
Reg,
nullptr}), Start(S), End(
E) {}
117 AVROperand(MCExpr
const *Imm, SMLoc
const &S, SMLoc
const &
E)
118 : Kind(k_Immediate),
RegImm({0,
Imm}), Start(S), End(
E) {}
119 AVROperand(MCRegister
Reg, MCExpr
const *Imm, SMLoc
const &S, SMLoc
const &
E)
122 struct RegisterImmediate {
134 void addRegOperands(MCInst &Inst,
unsigned N)
const {
135 assert(Kind == k_Register &&
"Unexpected operand kind");
136 assert(
N == 1 &&
"Invalid number of operands!");
141 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
151 void addImmOperands(MCInst &Inst,
unsigned N)
const {
152 assert(Kind == k_Immediate &&
"Unexpected operand kind");
153 assert(
N == 1 &&
"Invalid number of operands!");
155 const MCExpr *Expr =
getImm();
160 void addMemriOperands(MCInst &Inst,
unsigned N)
const {
161 assert(Kind == k_Memri &&
"Unexpected operand kind");
162 assert(
N == 2 &&
"Invalid number of operands");
168 void addImmCom8Operands(MCInst &Inst,
unsigned N)
const {
169 assert(
N == 1 &&
"Invalid number of operands!");
176 bool isImmCom8()
const {
182 int64_t
Value =
CE->getValue();
186 bool isReg()
const override {
return Kind == k_Register; }
187 bool isImm()
const override {
return Kind == k_Immediate; }
188 bool isToken()
const override {
return Kind == k_Token; }
189 bool isMem()
const override {
return Kind == k_Memri; }
190 bool isMemri()
const {
return Kind == k_Memri; }
193 assert(Kind == k_Token &&
"Invalid access!");
197 MCRegister
getReg()
const override {
198 assert((Kind == k_Register || Kind == k_Memri) &&
"Invalid access!");
203 const MCExpr *
getImm()
const {
204 assert((Kind == k_Immediate || Kind == k_Memri) &&
"Invalid access!");
208 static std::unique_ptr<AVROperand> CreateToken(StringRef Str, SMLoc S) {
209 return std::make_unique<AVROperand>(Str, S);
212 static std::unique_ptr<AVROperand> CreateReg(MCRegister
Reg, SMLoc S,
214 return std::make_unique<AVROperand>(
Reg, S,
E);
217 static std::unique_ptr<AVROperand> CreateImm(
const MCExpr *Val, SMLoc S,
219 return std::make_unique<AVROperand>(Val, S,
E);
222 static std::unique_ptr<AVROperand>
223 CreateMemri(MCRegister
Reg,
const MCExpr *Val, SMLoc S, SMLoc
E) {
224 return std::make_unique<AVROperand>(
Reg, Val, S,
E);
227 void makeToken(StringRef Token) {
232 void makeReg(MCRegister
Reg) {
237 void makeImm(MCExpr
const *Ex) {
242 void makeMemri(MCRegister
Reg, MCExpr
const *Imm) {
247 SMLoc getStartLoc()
const override {
return Start; }
248 SMLoc getEndLoc()
const override {
return End; }
250 void print(raw_ostream &O,
const MCAsmInfo &MAI)
const override {
259 O <<
"Immediate: \"";
266 O <<
"Memri: \"" <<
getReg().
id() <<
'+';
288bool AVRAsmParser::invalidOperand(
SMLoc const &
Loc,
292 char const *Diag =
nullptr;
296 Diag =
"too few operands for instruction.";
298 AVROperand
const &
Op = (AVROperand
const &)*
Operands[ErrorInfo];
301 if (
Op.getStartLoc() != SMLoc()) {
302 ErrorLoc =
Op.getStartLoc();
308 Diag =
"invalid operand for instruction";
311 return Error(ErrorLoc, Diag);
314bool AVRAsmParser::missingFeature(llvm::SMLoc
const &Loc,
315 uint64_t
const &ErrorInfo) {
316 return Error(Loc,
"instruction requires a CPU feature not currently enabled");
319bool AVRAsmParser::emit(MCInst &Inst, SMLoc
const &Loc, MCStreamer &Out)
const {
326bool AVRAsmParser::matchAndEmitInstruction(SMLoc Loc,
unsigned &Opcode,
328 MCStreamer &Out, uint64_t &ErrorInfo,
329 bool MatchingInlineAsm) {
331 unsigned MatchResult =
332 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MatchingInlineAsm);
334 switch (MatchResult) {
336 return emit(Inst, Loc, Out);
337 case Match_MissingFeature:
338 return missingFeature(Loc, ErrorInfo);
339 case Match_InvalidOperand:
340 return invalidOperand(Loc,
Operands, ErrorInfo);
341 case Match_MnemonicFail:
342 return Error(Loc,
"invalid instruction");
343 case Match_InvalidRegisterOnTiny:
344 return Error(Loc,
"invalid register on avrtiny");
352MCRegister AVRAsmParser::parseRegisterName(MCRegister (*matchFn)(StringRef)) {
355 MCRegister
Reg = matchFn(Name);
371MCRegister AVRAsmParser::parseRegisterName() {
380MCRegister AVRAsmParser::parseRegister(
bool RestoreOnFailure) {
386 AsmToken HighTok = Parser.
getTok();
388 AsmToken ColonTok = Parser.
getTok();
393 Reg = toDREG(parseRegisterName());
395 if (!
Reg && RestoreOnFailure) {
396 getLexer().UnLex(std::move(ColonTok));
397 getLexer().UnLex(std::move(HighTok));
400 Reg = parseRegisterName();
407 MCRegister
Reg = parseRegister();
413 if (AVR::R0 <=
Reg &&
Reg <= AVR::R15 &&
417 AsmToken
const &
T = Parser.
getTok();
418 Operands.push_back(AVROperand::CreateReg(
Reg,
T.getLoc(),
T.getEndLoc()));
427 if (!tryParseRelocExpression(
Operands))
439 MCExpr
const *Expression;
440 if (getParser().parseExpression(Expression))
449 Operands.push_back(AVROperand::CreateImm(Expression, S,
E));
454 bool isNegated =
false;
486 std::string GSModName = ModifierName.
str() +
"_" + GENERATE_STUBS;
502 MCExpr
const *InnerExpression;
503 if (getParser().parseExpression(InnerExpression))
516 MCExpr
const *Expression =
520 Operands.push_back(AVROperand::CreateImm(Expression, S,
E));
528 switch (getLexer().getKind()) {
534 if (maybeReg && !tryParseRegisterOperand(
Operands)) {
540 return tryParseExpression(
Operands, 0);
542 return tryParseExpression(
Operands, 2);
547 switch (getLexer().peekTok().getKind()) {
552 if (!tryParseExpression(
Operands, 0))
574 MCExpr
const *Expression;
579 Reg = parseRegister();
590 if (getParser().parseExpression(Expression))
596 Operands.push_back(AVROperand::CreateMemri(
Reg, Expression, S,
E));
601bool AVRAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
604 Reg = parseRegister(
false);
607 return Reg == AVR::NoRegister;
610ParseStatus AVRAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
613 Reg = parseRegister(
true);
616 if (
Reg == AVR::NoRegister)
621void AVRAsmParser::eatComma() {
629bool AVRAsmParser::parseInstruction(ParseInstructionInfo &Info,
630 StringRef Mnemonic, SMLoc NameLoc,
632 Operands.push_back(AVROperand::CreateToken(Mnemonic, NameLoc));
640 ParseStatus ParseRes = MatchOperandParserImpl(
Operands, Mnemonic);
646 SMLoc Loc = getLexer().getLoc();
649 return Error(Loc,
"failed to parse register and immediate pair");
654 bool maybeReg =
true;
656 if (OperandNum == 1) {
657 std::array<StringRef, 8> Insts = {
"lds",
"adiw",
"sbiw",
"ldi"};
658 for (
auto Inst : Insts) {
659 if (Inst == Mnemonic) {
664 }
else if (OperandNum == 0) {
665 std::array<StringRef, 8> Insts = {
"sts",
"call",
"rcall",
"rjmp",
"jmp"};
666 for (
auto Inst : Insts) {
667 if (Inst == Mnemonic) {
674 if (parseOperand(
Operands, maybeReg)) {
675 SMLoc Loc = getLexer().getLoc();
677 return Error(Loc,
"unexpected token in argument list");
684ParseStatus AVRAsmParser::parseDirective(llvm::AsmToken DirectiveID) {
686 if (IDVal.
lower() ==
".long")
688 if (IDVal.
lower() ==
".word" || IDVal.
lower() ==
".short")
690 if (IDVal.
lower() ==
".byte")
691 return parseLiteralValues(1, DirectiveID.
getLoc());
695ParseStatus AVRAsmParser::parseLiteralValues(
unsigned SizeInBytes, SMLoc L) {
696 MCAsmParser &Parser = getParser();
697 AVRMCELFStreamer &AVRStreamer =
698 static_cast<AVRMCELFStreamer &
>(Parser.
getStreamer());
729 auto parseOne = [&]() ->
bool {
736 return (parseMany(parseOne));
743#define GET_REGISTER_MATCHER
744#define GET_MATCHER_IMPLEMENTATION
745#include "AVRGenAsmMatcher.inc"
749 unsigned ExpectedKind) {
750 AVROperand &
Op =
static_cast<AVROperand &
>(AsmOp);
751 MatchClassKind
Expected =
static_cast<MatchClassKind
>(ExpectedKind);
757 int64_t RegNum = Const->getValue();
760 if (0 <= RegNum && RegNum <= 15 &&
762 return Match_InvalidRegisterOnTiny;
768 if (validateOperandClass(
Op,
Expected, *STI) == Match_Success) {
769 return Match_Success;
779 if (isSubclass(
Expected, MCK_DREGS)) {
782 if (correspondingDREG) {
783 Op.makeReg(correspondingDREG);
784 return validateOperandClass(
Op,
Expected, *STI);
788 return Match_InvalidOperand;
static MCRegister MatchRegisterName(StringRef Name)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file implements a class to represent arbitrary precision integral constant values and operations...
static MCRegister MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
static MCRegister MatchRegisterName(StringRef Name)
Maps from the set of all register names to a register number.
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRAsmParser()
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
void emitValueForModiferKind(const MCSymbol *Sym, unsigned SizeInBytes, SMLoc Loc=SMLoc(), AVRMCExpr::Specifier ModifierKind=AVR::S_AVR_NONE)
static const AVRMCExpr * create(Specifier S, const MCExpr *Expr, bool isNegated, MCContext &Ctx)
Specifies the type of an expression.
static Specifier parseSpecifier(StringRef Name)
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
AsmToken::TokenKind getKind() const
Get the kind of current token.
LLVM_ABI size_t peekTokens(MutableArrayRef< AsmToken > Buf, bool ShouldSkipSpace=true)
Look ahead an arbitrary number of tokens.
Target independent representation for an assembler token.
LLVM_ABI SMLoc getLoc() const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
bool is(TokenKind K) const
TokenKind getKind() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Base class for user error types.
Tagged union holding either a T or a Error.
void printExpr(raw_ostream &, const MCExpr &) const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
MCStreamer & getStreamer()
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
void addOperand(const MCOperand Op)
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
MCRegisterClass - Base class of TargetRegisterClass.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
Wrapper class representing physical registers. Should be passed by value.
constexpr unsigned id() const
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
bool hasFeature(unsigned Feature) const
const FeatureBitset & getFeatureBits() const
MCTargetAsmParser - Generic interface to target specific assembly parsers.
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
Represent a constant reference to a string, i.e.
std::string str() const
Get the contents as an std::string.
LLVM_ABI std::string lower() const
@ CE
Windows NT (Windows on ARM)
This is an optimization pass for GlobalISel generic memory operations.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Target & getTheAVRTarget()
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...