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);
 
   73  bool tryParseExpression(
OperandVector &Operands, int64_t offset);
 
   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;
 
   86  bool invalidOperand(SMLoc 
const &Loc, 
OperandVector const &Operands,
 
   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();
 
  405bool AVRAsmParser::tryParseRegisterOperand(
OperandVector &Operands) {
 
  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()));
 
  423bool AVRAsmParser::tryParseExpression(
OperandVector &Operands, int64_t offset) {
 
  426  if (!tryParseRelocExpression(Operands))
 
  438  MCExpr 
const *Expression;
 
  439  if (getParser().parseExpression(Expression))
 
  448  Operands.
push_back(AVROperand::CreateImm(Expression, S, 
E));
 
  452bool AVRAsmParser::tryParseRelocExpression(
OperandVector &Operands) {
 
  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));
 
  524bool AVRAsmParser::parseOperand(
OperandVector &Operands, 
bool maybeReg) {
 
  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))
 
  569ParseStatus AVRAsmParser::parseMemriOperand(
OperandVector &Operands) {
 
  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, *STI) == Match_Success) {
 
  768          return Match_Success;
 
  778    if (isSubclass(
Expected, MCK_DREGS)) {
 
  781      if (correspondingDREG) {
 
  782        Op.makeReg(correspondingDREG);
 
  783        return validateOperandClass(
Op, 
Expected, *STI);
 
  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
 
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
 
void push_back(const T &Elt)
 
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,...