34#define DEBUG_TYPE "avr-asm-parser"
43 const std::string GENERATE_STUBS =
"gs";
45 enum AVRMatchResultTy {
46 Match_InvalidRegisterOnTiny = FIRST_TARGET_MATCH_RESULT_TY + 1,
49#define GET_ASSEMBLER_HEADER
50#include "AVRGenAsmMatcher.inc"
52 bool matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
55 bool MatchingInlineAsm)
override;
59 SMLoc &EndLoc)
override;
71 MCRegister parseRegister(
bool RestoreOnFailure =
false);
78 unsigned Kind)
override;
81 MCRegisterClass const *Class = &AVRMCRegisterClasses[AVR::DREGSRegClassID];
82 return MRI->getMatchingSuperReg(
Reg, From, Class);
85 bool emit(MCInst &Instruction, SMLoc
const &Loc, MCStreamer &Out)
const;
87 uint64_t
const &ErrorInfo);
88 bool missingFeature(SMLoc
const &Loc, uint64_t
const &ErrorInfo);
90 ParseStatus parseLiteralValues(
unsigned SizeInBytes, SMLoc L);
93 AVRAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
94 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
95 : MCTargetAsmParser(
Options, STI, MII), Parser(Parser) {
99 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
102 MCAsmParser &getParser()
const {
return Parser; }
103 AsmLexer &getLexer()
const {
return Parser.getLexer(); }
108 typedef MCParsedAsmOperand Base;
109 enum KindTy { k_Immediate, k_Register, k_Token, k_Memri } Kind;
112 AVROperand(StringRef Tok, SMLoc
const &S)
113 : Kind(k_Token), Tok(Tok), Start(S), End(S) {}
114 AVROperand(MCRegister
Reg, SMLoc
const &S, SMLoc
const &
E)
115 : Kind(k_Register),
RegImm({
Reg,
nullptr}), Start(S), End(
E) {}
116 AVROperand(MCExpr
const *Imm, SMLoc
const &S, SMLoc
const &
E)
117 : Kind(k_Immediate),
RegImm({0,
Imm}), Start(S), End(
E) {}
118 AVROperand(MCRegister
Reg, MCExpr
const *Imm, SMLoc
const &S, SMLoc
const &
E)
121 struct RegisterImmediate {
133 void addRegOperands(MCInst &Inst,
unsigned N)
const {
134 assert(Kind == k_Register &&
"Unexpected operand kind");
135 assert(
N == 1 &&
"Invalid number of operands!");
140 void addExpr(MCInst &Inst,
const MCExpr *Expr)
const {
150 void addImmOperands(MCInst &Inst,
unsigned N)
const {
151 assert(Kind == k_Immediate &&
"Unexpected operand kind");
152 assert(
N == 1 &&
"Invalid number of operands!");
154 const MCExpr *Expr =
getImm();
159 void addMemriOperands(MCInst &Inst,
unsigned N)
const {
160 assert(Kind == k_Memri &&
"Unexpected operand kind");
161 assert(
N == 2 &&
"Invalid number of operands");
167 void addImmCom8Operands(MCInst &Inst,
unsigned N)
const {
168 assert(
N == 1 &&
"Invalid number of operands!");
175 bool isImmCom8()
const {
181 int64_t
Value =
CE->getValue();
185 bool isReg()
const override {
return Kind == k_Register; }
186 bool isImm()
const override {
return Kind == k_Immediate; }
187 bool isToken()
const override {
return Kind == k_Token; }
188 bool isMem()
const override {
return Kind == k_Memri; }
189 bool isMemri()
const {
return Kind == k_Memri; }
192 assert(Kind == k_Token &&
"Invalid access!");
196 MCRegister
getReg()
const override {
197 assert((Kind == k_Register || Kind == k_Memri) &&
"Invalid access!");
202 const MCExpr *
getImm()
const {
203 assert((Kind == k_Immediate || Kind == k_Memri) &&
"Invalid access!");
207 static std::unique_ptr<AVROperand> CreateToken(StringRef Str, SMLoc S) {
208 return std::make_unique<AVROperand>(Str, S);
211 static std::unique_ptr<AVROperand> CreateReg(MCRegister
Reg, SMLoc S,
213 return std::make_unique<AVROperand>(
Reg, S,
E);
216 static std::unique_ptr<AVROperand> CreateImm(
const MCExpr *Val, SMLoc S,
218 return std::make_unique<AVROperand>(Val, S,
E);
221 static std::unique_ptr<AVROperand>
222 CreateMemri(MCRegister
Reg,
const MCExpr *Val, SMLoc S, SMLoc
E) {
223 return std::make_unique<AVROperand>(
Reg, Val, S,
E);
226 void makeToken(StringRef Token) {
231 void makeReg(MCRegister
Reg) {
236 void makeImm(MCExpr
const *Ex) {
241 void makeMemri(MCRegister
Reg, MCExpr
const *Imm) {
246 SMLoc getStartLoc()
const override {
return Start; }
247 SMLoc getEndLoc()
const override {
return End; }
249 void print(raw_ostream &O,
const MCAsmInfo &MAI)
const override {
258 O <<
"Immediate: \"";
265 O <<
"Memri: \"" <<
getReg() <<
'+';
287bool AVRAsmParser::invalidOperand(
SMLoc const &
Loc,
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(llvm::SMLoc
const &Loc,
314 uint64_t
const &ErrorInfo) {
315 return Error(Loc,
"instruction requires a CPU feature not currently enabled");
318bool AVRAsmParser::emit(MCInst &Inst, SMLoc
const &Loc, MCStreamer &Out)
const {
325bool AVRAsmParser::matchAndEmitInstruction(SMLoc Loc,
unsigned &Opcode,
327 MCStreamer &Out, uint64_t &ErrorInfo,
328 bool MatchingInlineAsm) {
330 unsigned MatchResult =
331 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MatchingInlineAsm);
333 switch (MatchResult) {
335 return emit(Inst, Loc, Out);
336 case Match_MissingFeature:
337 return missingFeature(Loc, ErrorInfo);
338 case Match_InvalidOperand:
339 return invalidOperand(Loc,
Operands, ErrorInfo);
340 case Match_MnemonicFail:
341 return Error(Loc,
"invalid instruction");
342 case Match_InvalidRegisterOnTiny:
343 return Error(Loc,
"invalid register on avrtiny");
351MCRegister AVRAsmParser::parseRegisterName(MCRegister (*matchFn)(StringRef)) {
354 MCRegister
Reg = matchFn(Name);
370MCRegister AVRAsmParser::parseRegisterName() {
379MCRegister AVRAsmParser::parseRegister(
bool RestoreOnFailure) {
385 AsmToken HighTok = Parser.
getTok();
387 AsmToken ColonTok = Parser.
getTok();
392 Reg = toDREG(parseRegisterName());
394 if (!
Reg && RestoreOnFailure) {
395 getLexer().UnLex(std::move(ColonTok));
396 getLexer().UnLex(std::move(HighTok));
399 Reg = parseRegisterName();
406 MCRegister
Reg = parseRegister();
412 if (AVR::R0 <=
Reg &&
Reg <= AVR::R15 &&
416 AsmToken
const &
T = Parser.
getTok();
417 Operands.push_back(AVROperand::CreateReg(
Reg,
T.getLoc(),
T.getEndLoc()));
426 if (!tryParseRelocExpression(
Operands))
438 MCExpr
const *Expression;
439 if (getParser().parseExpression(Expression))
448 Operands.push_back(AVROperand::CreateImm(Expression, S,
E));
453 bool isNegated =
false;
485 std::string GSModName = ModifierName.
str() +
"_" + GENERATE_STUBS;
501 MCExpr
const *InnerExpression;
502 if (getParser().parseExpression(InnerExpression))
515 MCExpr
const *Expression =
519 Operands.push_back(AVROperand::CreateImm(Expression, S,
E));
527 switch (getLexer().getKind()) {
533 if (maybeReg && !tryParseRegisterOperand(
Operands)) {
539 return tryParseExpression(
Operands, 0);
541 return tryParseExpression(
Operands, 2);
546 switch (getLexer().peekTok().getKind()) {
551 if (!tryParseExpression(
Operands, 0))
573 MCExpr
const *Expression;
578 Reg = parseRegister();
589 if (getParser().parseExpression(Expression))
595 Operands.push_back(AVROperand::CreateMemri(
Reg, Expression, S,
E));
600bool AVRAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
603 Reg = parseRegister(
false);
606 return Reg == AVR::NoRegister;
609ParseStatus AVRAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
612 Reg = parseRegister(
true);
615 if (
Reg == AVR::NoRegister)
620void AVRAsmParser::eatComma() {
628bool AVRAsmParser::parseInstruction(ParseInstructionInfo &
Info,
629 StringRef Mnemonic, SMLoc NameLoc,
631 Operands.push_back(AVROperand::CreateToken(Mnemonic, NameLoc));
639 ParseStatus ParseRes = MatchOperandParserImpl(
Operands, Mnemonic);
645 SMLoc Loc = getLexer().getLoc();
648 return Error(Loc,
"failed to parse register and immediate pair");
653 bool maybeReg =
true;
655 if (OperandNum == 1) {
656 std::array<StringRef, 8> Insts = {
"lds",
"adiw",
"sbiw",
"ldi"};
657 for (
auto Inst : Insts) {
658 if (Inst == Mnemonic) {
663 }
else if (OperandNum == 0) {
664 std::array<StringRef, 8> Insts = {
"sts",
"call",
"rcall",
"rjmp",
"jmp"};
665 for (
auto Inst : Insts) {
666 if (Inst == Mnemonic) {
673 if (parseOperand(
Operands, maybeReg)) {
674 SMLoc Loc = getLexer().getLoc();
676 return Error(Loc,
"unexpected token in argument list");
683ParseStatus AVRAsmParser::parseDirective(llvm::AsmToken DirectiveID) {
685 if (IDVal.
lower() ==
".long")
687 if (IDVal.
lower() ==
".word" || IDVal.
lower() ==
".short")
689 if (IDVal.
lower() ==
".byte")
690 return parseLiteralValues(1, DirectiveID.
getLoc());
694ParseStatus AVRAsmParser::parseLiteralValues(
unsigned SizeInBytes, SMLoc L) {
695 MCAsmParser &Parser = getParser();
696 AVRMCELFStreamer &AVRStreamer =
697 static_cast<AVRMCELFStreamer &
>(Parser.
getStreamer());
728 auto parseOne = [&]() ->
bool {
735 return (parseMany(parseOne));
742#define GET_REGISTER_MATCHER
743#define GET_MATCHER_IMPLEMENTATION
744#include "AVRGenAsmMatcher.inc"
748 unsigned ExpectedKind) {
749 AVROperand &
Op =
static_cast<AVROperand &
>(AsmOp);
750 MatchClassKind
Expected =
static_cast<MatchClassKind
>(ExpectedKind);
756 int64_t RegNum = Const->getValue();
759 if (0 <= RegNum && RegNum <= 15 &&
761 return Match_InvalidRegisterOnTiny;
767 if (validateOperandClass(
Op,
Expected) == Match_Success) {
768 return Match_Success;
778 if (isSubclass(
Expected, MCK_DREGS)) {
781 if (correspondingDREG) {
782 Op.makeReg(correspondingDREG);
787 return Match_InvalidOperand;
unsigned const MachineRegisterInfo * MRI
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")
Analysis containing CSE Info
#define LLVM_EXTERNAL_VISIBILITY
mir Rename Register Operands
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
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...
Wrapper class representing physical registers. Should be passed by value.
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
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
LLVM_ABI std::string lower() const
@ CE
Windows NT (Windows on ARM)
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
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()
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,...