33#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"
55 bool MatchingInlineAsm)
override;
59 SMLoc &EndLoc)
override;
78 unsigned Kind)
override;
81 MCRegisterClass const *Class = &AVRMCRegisterClasses[AVR::DREGSRegClassID];
82 return MRI->getMatchingSuperReg(Reg,
From, Class);
109 enum KindTy { k_Immediate, k_Register, k_Token, k_Memri }
Kind;
113 :
Kind(k_Token), Tok(Tok), Start(S),
End(S) {}
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!");
144 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
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");
164 addExpr(Inst, getImm());
167 void addImmCom8Operands(
MCInst &Inst,
unsigned N)
const {
168 assert(
N == 1 &&
"Invalid number of operands!");
171 const auto *
CE = cast<MCConstantExpr>(getImm());
175 bool isImmCom8()
const {
178 const auto *
CE = dyn_cast<MCConstantExpr>(getImm());
181 int64_t
Value =
CE->getValue();
182 return isUInt<8>(
Value);
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!");
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);
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>
223 return std::make_unique<AVROperand>(Reg, Val, S, E);
236 void makeImm(
MCExpr const *Ex) {
252 O <<
"Token: \"" << getToken() <<
"\"";
258 O <<
"Immediate: \"" << *getImm() <<
"\"";
263 O <<
"Memri: \"" <<
getReg() <<
'+' << *getImm() <<
"\"";
283bool AVRAsmParser::invalidOperand(
SMLoc const &Loc,
286 SMLoc ErrorLoc = Loc;
287 char const *Diag =
nullptr;
291 Diag =
"too few operands for instruction.";
296 if (
Op.getStartLoc() !=
SMLoc()) {
297 ErrorLoc =
Op.getStartLoc();
303 Diag =
"invalid operand for instruction";
306 return Error(ErrorLoc, Diag);
309bool AVRAsmParser::missingFeature(
llvm::SMLoc const &Loc,
311 return Error(Loc,
"instruction requires a CPU feature not currently enabled");
321bool AVRAsmParser::matchAndEmitInstruction(
SMLoc Loc,
unsigned &Opcode,
324 bool MatchingInlineAsm) {
326 unsigned MatchResult =
329 switch (MatchResult) {
331 return emit(Inst, Loc, Out);
332 case Match_MissingFeature:
334 case Match_InvalidOperand:
336 case Match_MnemonicFail:
337 return Error(Loc,
"invalid instruction");
338 case Match_InvalidRegisterOnTiny:
339 return Error(Loc,
"invalid register on avrtiny");
375MCRegister AVRAsmParser::parseRegister(
bool RestoreOnFailure) {
388 Reg = toDREG(parseRegisterName());
390 if (!Reg && RestoreOnFailure) {
391 getLexer().UnLex(std::move(ColonTok));
392 getLexer().UnLex(std::move(HighTok));
395 Reg = parseRegisterName();
408 if (AVR::R0 <= Reg && Reg <= AVR::R15 &&
413 Operands.push_back(AVROperand::CreateReg(Reg,
T.getLoc(),
T.getEndLoc()));
422 if (!tryParseRelocExpression(
Operands))
449 bool isNegated =
false;
481 std::string GSModName = ModifierName.
str() +
"_" + GENERATE_STUBS;
497 MCExpr const *InnerExpression;
498 if (getParser().parseExpression(InnerExpression))
523 switch (getLexer().getKind()) {
529 if (maybeReg && !tryParseRegisterOperand(
Operands)) {
535 return tryParseExpression(
Operands, 0);
537 return tryParseExpression(
Operands, 2);
542 switch (getLexer().peekTok().getKind()) {
547 if (!tryParseExpression(
Operands, 0))
574 Reg = parseRegister();
599 Reg = parseRegister(
false);
602 return Reg == AVR::NoRegister;
608 Reg = parseRegister(
true);
611 if (Reg == AVR::NoRegister)
616void AVRAsmParser::eatComma() {
627 Operands.push_back(AVROperand::CreateToken(Mnemonic, NameLoc));
641 SMLoc Loc = getLexer().getLoc();
644 return Error(Loc,
"failed to parse register and immediate pair");
649 bool maybeReg =
true;
651 if (OperandNum == 1) {
652 std::array<StringRef, 8> Insts = {
"lds",
"adiw",
"sbiw",
"ldi"};
653 for (
auto Inst : Insts) {
654 if (Inst == Mnemonic) {
659 }
else if (OperandNum == 0) {
660 std::array<StringRef, 8> Insts = {
"sts",
"call",
"rcall",
"rjmp",
"jmp"};
661 for (
auto Inst : Insts) {
662 if (Inst == Mnemonic) {
669 if (parseOperand(
Operands, maybeReg)) {
670 SMLoc Loc = getLexer().getLoc();
672 return Error(Loc,
"unexpected token in argument list");
681 if (IDVal.
lower() ==
".long")
683 if (IDVal.
lower() ==
".word" || IDVal.
lower() ==
".short")
685 if (IDVal.
lower() ==
".byte")
686 return parseLiteralValues(1, DirectiveID.
getLoc());
690ParseStatus AVRAsmParser::parseLiteralValues(
unsigned SizeInBytes,
SMLoc L) {
725 auto parseOne = [&]() ->
bool {
732 return (parseMany(parseOne));
739#define GET_REGISTER_MATCHER
740#define GET_MATCHER_IMPLEMENTATION
741#include "AVRGenAsmMatcher.inc"
745 unsigned ExpectedKind) {
746 AVROperand &
Op =
static_cast<AVROperand &
>(AsmOp);
747 MatchClassKind
Expected =
static_cast<MatchClassKind
>(ExpectedKind);
753 int64_t RegNum = Const->getValue();
756 if (0 <= RegNum && RegNum <= 15 &&
758 return Match_InvalidRegisterOnTiny;
764 if (validateOperandClass(
Op,
Expected) == Match_Success) {
765 return Match_Success;
775 if (isSubclass(
Expected, MCK_DREGS)) {
778 if (correspondingDREG) {
779 Op.makeReg(correspondingDREG);
784 return Match_InvalidOperand;
unsigned const MachineRegisterInfo * MRI
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_EXTERNAL_VISIBILITY void LLVMInitializeAVRAsmParser()
BlockVerifier::State From
#define LLVM_EXTERNAL_VISIBILITY
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
mir Rename Register Operands
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void emitValueForModiferKind(const MCSymbol *Sym, unsigned SizeInBytes, SMLoc Loc=SMLoc(), AVRMCExpr::VariantKind ModifierKind=AVRMCExpr::VK_AVR_None)
static const AVRMCExpr * create(VariantKind Kind, const MCExpr *Expr, bool isNegated, MCContext &Ctx)
Creates an AVR machine code expression.
static VariantKind getKindByName(StringRef Name)
VariantKind
Specifies the type of an expression.
Target independent representation for an assembler token.
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.
This class represents an Operation in the Expression.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
Class representing an expression and its matching format.
Generic assembler lexer interface, for use by target specific assembly lexers.
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.
virtual size_t peekTokens(MutableArrayRef< AsmToken > Buf, bool ShouldSkipSpace=true)=0
Look ahead an arbitrary number of tokens.
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
MCAsmParser & getParser()
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 MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
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.
virtual MCAsmLexer & getLexer()=0
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
const MCRegisterInfo * getRegisterInfo() const
Base class for the full range of assembler expressions which are needed for parsing.
Instances of this class represent a single low-level machine instruction.
void addOperand(const MCOperand Op)
Interface to description of machine instruction set.
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.
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual bool isMem() const =0
isMem - Is this a memory operand?
virtual MCRegister getReg() const =0
virtual void print(raw_ostream &OS) const =0
print - Print a debug representation of the operand to the given stream.
virtual bool isToken() const =0
isToken - Is this a token operand?
virtual bool isImm() const =0
isImm - Is this an immediate operand?
virtual SMLoc getEndLoc() const =0
getEndLoc - Get the location of the last token of this 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())
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const FeatureBitset & getFeatureBits() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual ParseStatus parseDirective(AsmToken DirectiveID)
Parses a target-specific assembler directive.
virtual bool parseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
Parse one assembly instruction.
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
virtual bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
Recognize a series of operands of a parsed instruction as an actual MCInst and emit it to the specifi...
void setAvailableFeatures(const FeatureBitset &Value)
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)
Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...
const MCSubtargetInfo * STI
Current STI.
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
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
std::string lower() const
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
@ CE
Windows NT (Windows on ARM)
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Target & getTheAVRTarget()
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...