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 = &getAVRMCRegisterClass(AVR::DREGSRegClassID);
82 return MRI->getMatchingSuperReg(
Reg, From, Class);
85 bool emit(MCInst &Instruction, SMLoc Loc, MCStreamer &Out)
const;
88 bool missingFeature(SMLoc Loc,
uint64_t const &ErrorInfo);
90 ParseStatus parseLiteralValues(
unsigned SizeInBytes, SMLoc L);
93 AVRAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
94 const MCInstrInfo &MII)
95 : MCTargetAsmParser(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 S)
113 : Kind(k_Token), Tok(Tok), Start(S), End(S) {}
114 AVROperand(MCRegister
Reg, SMLoc S, SMLoc
E)
115 : Kind(k_Register),
RegImm({
Reg,
nullptr}), Start(S),
End(
E) {}
116 AVROperand(MCExpr
const *
Imm, SMLoc S, SMLoc
E)
118 AVROperand(MCRegister
Reg, MCExpr
const *
Imm, SMLoc S, SMLoc
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().
id() <<
'+';
290 char const *Diag =
nullptr;
294 Diag =
"too few operands for instruction.";
296 AVROperand
const &
Op = (AVROperand
const &)*
Operands[ErrorInfo];
299 if (
Op.getStartLoc() != SMLoc()) {
300 ErrorLoc =
Op.getStartLoc();
306 Diag =
"invalid operand for instruction";
309 return Error(ErrorLoc, Diag);
312bool AVRAsmParser::missingFeature(SMLoc Loc,
uint64_t const &ErrorInfo) {
313 return Error(Loc,
"instruction requires a CPU feature not currently enabled");
316bool AVRAsmParser::emit(MCInst &Inst, SMLoc Loc, MCStreamer &Out)
const {
318 Out.emitInstruction(Inst, *STI);
323bool AVRAsmParser::matchAndEmitInstruction(SMLoc Loc,
unsigned &Opcode,
325 MCStreamer &Out,
uint64_t &ErrorInfo,
326 bool MatchingInlineAsm) {
328 unsigned MatchResult =
329 MatchInstructionImpl(
Operands, Inst, ErrorInfo, MatchingInlineAsm);
331 switch (MatchResult) {
333 return emit(Inst, Loc, Out);
334 case Match_MissingFeature:
335 return missingFeature(Loc, ErrorInfo);
336 case Match_InvalidOperand:
337 return invalidOperand(Loc,
Operands, ErrorInfo);
338 case Match_MnemonicFail:
339 return Error(Loc,
"invalid instruction");
340 case Match_InvalidRegisterOnTiny:
341 return Error(Loc,
"invalid register on avrtiny");
349MCRegister AVRAsmParser::parseRegisterName(MCRegister (*matchFn)(StringRef)) {
352 MCRegister
Reg = matchFn(Name);
368MCRegister AVRAsmParser::parseRegisterName() {
377MCRegister AVRAsmParser::parseRegister(
bool RestoreOnFailure) {
383 AsmToken HighTok = Parser.
getTok();
385 AsmToken ColonTok = Parser.
getTok();
390 Reg = toDREG(parseRegisterName());
392 if (!
Reg && RestoreOnFailure) {
393 getLexer().UnLex(std::move(ColonTok));
394 getLexer().UnLex(std::move(HighTok));
397 Reg = parseRegisterName();
404 MCRegister
Reg = parseRegister();
410 if (AVR::R0 <=
Reg &&
Reg <= AVR::R15 &&
414 AsmToken
const &
T = Parser.
getTok();
415 Operands.push_back(AVROperand::CreateReg(
Reg,
T.getLoc(),
T.getEndLoc()));
424 if (!tryParseRelocExpression(
Operands))
436 MCExpr
const *Expression;
437 if (getParser().parseExpression(Expression))
446 Operands.push_back(AVROperand::CreateImm(Expression, S,
E));
451 bool isNegated =
false;
483 std::string GSModName = ModifierName.
str() +
"_" + GENERATE_STUBS;
499 MCExpr
const *InnerExpression;
500 if (getParser().parseExpression(InnerExpression))
513 MCExpr
const *Expression =
517 Operands.push_back(AVROperand::CreateImm(Expression, S,
E));
525 switch (getLexer().getKind()) {
531 if (maybeReg && !tryParseRegisterOperand(
Operands)) {
537 return tryParseExpression(
Operands, 0);
539 return tryParseExpression(
Operands, 2);
544 switch (getLexer().peekTok().getKind()) {
549 if (!tryParseExpression(
Operands, 0))
571 MCExpr
const *Expression;
576 Reg = parseRegister();
587 if (getParser().parseExpression(Expression))
593 Operands.push_back(AVROperand::CreateMemri(
Reg, Expression, S,
E));
598bool AVRAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
601 Reg = parseRegister(
false);
604 return Reg == AVR::NoRegister;
607ParseStatus AVRAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
610 Reg = parseRegister(
true);
613 if (
Reg == AVR::NoRegister)
618void AVRAsmParser::eatComma() {
626bool AVRAsmParser::parseInstruction(ParseInstructionInfo &Info,
627 StringRef Mnemonic, SMLoc NameLoc,
629 Operands.push_back(AVROperand::CreateToken(Mnemonic, NameLoc));
637 ParseStatus ParseRes = MatchOperandParserImpl(
Operands, Mnemonic);
643 SMLoc Loc = getLexer().getLoc();
646 return Error(Loc,
"failed to parse register and immediate pair");
651 bool maybeReg =
true;
653 if (OperandNum == 1) {
654 std::array<StringRef, 8> Insts = {
"lds",
"adiw",
"sbiw",
"ldi"};
655 for (
auto Inst : Insts) {
656 if (Inst == Mnemonic) {
661 }
else if (OperandNum == 0) {
662 std::array<StringRef, 8> Insts = {
"sts",
"call",
"rcall",
"rjmp",
"jmp"};
663 for (
auto Inst : Insts) {
664 if (Inst == Mnemonic) {
671 if (parseOperand(
Operands, maybeReg)) {
672 SMLoc Loc = getLexer().getLoc();
674 return Error(Loc,
"unexpected token in argument list");
681ParseStatus AVRAsmParser::parseDirective(llvm::AsmToken DirectiveID) {
683 if (IDVal.
lower() ==
".long")
685 if (IDVal.
lower() ==
".word" || IDVal.
lower() ==
".short")
687 if (IDVal.
lower() ==
".byte")
688 return parseLiteralValues(1, DirectiveID.
getLoc());
692ParseStatus AVRAsmParser::parseLiteralValues(
unsigned SizeInBytes, SMLoc L) {
693 MCAsmParser &Parser = getParser();
694 AVRMCELFStreamer &AVRStreamer =
695 static_cast<AVRMCELFStreamer &
>(Parser.
getStreamer());
726 auto parseOne = [&]() ->
bool {
733 return (parseMany(parseOne));
740#define GET_REGISTER_MATCHER
741#define GET_MATCHER_IMPLEMENTATION
742#include "AVRGenAsmMatcher.inc"
746 unsigned ExpectedKind) {
747 AVROperand &
Op =
static_cast<AVROperand &
>(AsmOp);
748 MatchClassKind
Expected =
static_cast<MatchClassKind
>(ExpectedKind);
754 int64_t RegNum = Const->getValue();
757 if (0 <= RegNum && RegNum <= 15 &&
759 return Match_InvalidRegisterOnTiny;
765 if (validateOperandClass(
Op,
Expected, *STI) == Match_Success) {
766 return Match_Success;
776 if (isSubclass(
Expected, MCK_DREGS)) {
779 if (correspondingDREG) {
780 Op.makeReg(correspondingDREG);
781 return validateOperandClass(
Op,
Expected, *STI);
785 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)
MachineRegisterInfo & MRI
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...
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,...