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 Loc, MCStreamer &Out)
const;
89 bool missingFeature(SMLoc 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 S)
114 : Kind(k_Token), Tok(Tok), Start(S), End(S) {}
115 AVROperand(MCRegister
Reg, SMLoc S, SMLoc
E)
116 : Kind(k_Register),
RegImm({
Reg,
nullptr}), Start(S),
End(
E) {}
117 AVROperand(MCExpr
const *
Imm, SMLoc S, SMLoc
E)
119 AVROperand(MCRegister
Reg, MCExpr
const *
Imm, SMLoc S, SMLoc
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() <<
'+';
291 char const *Diag =
nullptr;
295 Diag =
"too few operands for instruction.";
297 AVROperand
const &
Op = (AVROperand
const &)*
Operands[ErrorInfo];
300 if (
Op.getStartLoc() != SMLoc()) {
301 ErrorLoc =
Op.getStartLoc();
307 Diag =
"invalid operand for instruction";
310 return Error(ErrorLoc, Diag);
313bool AVRAsmParser::missingFeature(SMLoc Loc,
uint64_t const &ErrorInfo) {
314 return Error(Loc,
"instruction requires a CPU feature not currently enabled");
317bool AVRAsmParser::emit(MCInst &Inst, SMLoc Loc, MCStreamer &Out)
const {
319 Out.emitInstruction(Inst, *STI);
324bool AVRAsmParser::matchAndEmitInstruction(SMLoc Loc,
unsigned &Opcode,
326 MCStreamer &Out,
uint64_t &ErrorInfo,
327 bool MatchingInlineAsm) {
329 unsigned MatchResult =
330 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MatchingInlineAsm);
332 switch (MatchResult) {
334 return emit(Inst, Loc, Out);
335 case Match_MissingFeature:
336 return missingFeature(Loc, ErrorInfo);
337 case Match_InvalidOperand:
338 return invalidOperand(Loc,
Operands, ErrorInfo);
339 case Match_MnemonicFail:
340 return Error(Loc,
"invalid instruction");
341 case Match_InvalidRegisterOnTiny:
342 return Error(Loc,
"invalid register on avrtiny");
350MCRegister AVRAsmParser::parseRegisterName(MCRegister (*matchFn)(StringRef)) {
353 MCRegister
Reg = matchFn(Name);
369MCRegister AVRAsmParser::parseRegisterName() {
378MCRegister AVRAsmParser::parseRegister(
bool RestoreOnFailure) {
384 AsmToken HighTok = Parser.
getTok();
386 AsmToken ColonTok = Parser.
getTok();
391 Reg = toDREG(parseRegisterName());
393 if (!
Reg && RestoreOnFailure) {
394 getLexer().UnLex(std::move(ColonTok));
395 getLexer().UnLex(std::move(HighTok));
398 Reg = parseRegisterName();
405 MCRegister
Reg = parseRegister();
411 if (AVR::R0 <=
Reg &&
Reg <= AVR::R15 &&
415 AsmToken
const &
T = Parser.
getTok();
416 Operands.push_back(AVROperand::CreateReg(
Reg,
T.getLoc(),
T.getEndLoc()));
425 if (!tryParseRelocExpression(
Operands))
437 MCExpr
const *Expression;
438 if (getParser().parseExpression(Expression))
447 Operands.push_back(AVROperand::CreateImm(Expression, S,
E));
452 bool isNegated =
false;
484 std::string GSModName = ModifierName.
str() +
"_" + GENERATE_STUBS;
500 MCExpr
const *InnerExpression;
501 if (getParser().parseExpression(InnerExpression))
514 MCExpr
const *Expression =
518 Operands.push_back(AVROperand::CreateImm(Expression, S,
E));
526 switch (getLexer().getKind()) {
532 if (maybeReg && !tryParseRegisterOperand(
Operands)) {
538 return tryParseExpression(
Operands, 0);
540 return tryParseExpression(
Operands, 2);
545 switch (getLexer().peekTok().getKind()) {
550 if (!tryParseExpression(
Operands, 0))
572 MCExpr
const *Expression;
577 Reg = parseRegister();
588 if (getParser().parseExpression(Expression))
594 Operands.push_back(AVROperand::CreateMemri(
Reg, Expression, S,
E));
599bool AVRAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
602 Reg = parseRegister(
false);
605 return Reg == AVR::NoRegister;
608ParseStatus AVRAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
611 Reg = parseRegister(
true);
614 if (
Reg == AVR::NoRegister)
619void AVRAsmParser::eatComma() {
627bool AVRAsmParser::parseInstruction(ParseInstructionInfo &Info,
628 StringRef Mnemonic, SMLoc NameLoc,
630 Operands.push_back(AVROperand::CreateToken(Mnemonic, NameLoc));
638 ParseStatus ParseRes = MatchOperandParserImpl(
Operands, Mnemonic);
644 SMLoc Loc = getLexer().getLoc();
647 return Error(Loc,
"failed to parse register and immediate pair");
652 bool maybeReg =
true;
654 if (OperandNum == 1) {
655 std::array<StringRef, 8> Insts = {
"lds",
"adiw",
"sbiw",
"ldi"};
656 for (
auto Inst : Insts) {
657 if (Inst == Mnemonic) {
662 }
else if (OperandNum == 0) {
663 std::array<StringRef, 8> Insts = {
"sts",
"call",
"rcall",
"rjmp",
"jmp"};
664 for (
auto Inst : Insts) {
665 if (Inst == Mnemonic) {
672 if (parseOperand(
Operands, maybeReg)) {
673 SMLoc Loc = getLexer().getLoc();
675 return Error(Loc,
"unexpected token in argument list");
682ParseStatus AVRAsmParser::parseDirective(llvm::AsmToken DirectiveID) {
684 if (IDVal.
lower() ==
".long")
686 if (IDVal.
lower() ==
".word" || IDVal.
lower() ==
".short")
688 if (IDVal.
lower() ==
".byte")
689 return parseLiteralValues(1, DirectiveID.
getLoc());
693ParseStatus AVRAsmParser::parseLiteralValues(
unsigned SizeInBytes, SMLoc L) {
694 MCAsmParser &Parser = getParser();
695 AVRMCELFStreamer &AVRStreamer =
696 static_cast<AVRMCELFStreamer &
>(Parser.
getStreamer());
727 auto parseOne = [&]() ->
bool {
734 return (parseMany(parseOne));
741#define GET_REGISTER_MATCHER
742#define GET_MATCHER_IMPLEMENTATION
743#include "AVRGenAsmMatcher.inc"
747 unsigned ExpectedKind) {
748 AVROperand &
Op =
static_cast<AVROperand &
>(AsmOp);
749 MatchClassKind
Expected =
static_cast<MatchClassKind
>(ExpectedKind);
755 int64_t RegNum = Const->getValue();
758 if (0 <= RegNum && RegNum <= 15 &&
760 return Match_InvalidRegisterOnTiny;
766 if (validateOperandClass(
Op,
Expected, *STI) == Match_Success) {
767 return Match_Success;
777 if (isSubclass(
Expected, MCK_DREGS)) {
780 if (correspondingDREG) {
781 Op.makeReg(correspondingDREG);
782 return validateOperandClass(
Op,
Expected, *STI);
786 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.
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.
@ End
Run the machine verifier once, at the end of the pipeline.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...