LCOV - code coverage report
Current view: top level - lib/Target/AVR/AsmParser - AVRAsmParser.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 189 262 72.1 %
Date: 2018-10-20 13:21:21 Functions: 21 38 55.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===---- AVRAsmParser.cpp - Parse AVR assembly to MCInst instructions ----===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #include "AVR.h"
      11             : #include "AVRRegisterInfo.h"
      12             : #include "MCTargetDesc/AVRMCELFStreamer.h"
      13             : #include "MCTargetDesc/AVRMCExpr.h"
      14             : #include "MCTargetDesc/AVRMCTargetDesc.h"
      15             : 
      16             : #include "llvm/ADT/APInt.h"
      17             : #include "llvm/ADT/StringSwitch.h"
      18             : #include "llvm/MC/MCContext.h"
      19             : #include "llvm/MC/MCExpr.h"
      20             : #include "llvm/MC/MCInst.h"
      21             : #include "llvm/MC/MCInstBuilder.h"
      22             : #include "llvm/MC/MCParser/MCAsmLexer.h"
      23             : #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
      24             : #include "llvm/MC/MCParser/MCTargetAsmParser.h"
      25             : #include "llvm/MC/MCStreamer.h"
      26             : #include "llvm/MC/MCSubtargetInfo.h"
      27             : #include "llvm/MC/MCSymbol.h"
      28             : #include "llvm/MC/MCValue.h"
      29             : #include "llvm/Support/Debug.h"
      30             : #include "llvm/Support/MathExtras.h"
      31             : #include "llvm/Support/TargetRegistry.h"
      32             : 
      33             : #include <sstream>
      34             : 
      35             : #define DEBUG_TYPE "avr-asm-parser"
      36             : 
      37             : namespace llvm {
      38             : 
      39             : /// Parses AVR assembly from a stream.
      40             : class AVRAsmParser : public MCTargetAsmParser {
      41             :   const MCSubtargetInfo &STI;
      42             :   MCAsmParser &Parser;
      43             :   const MCRegisterInfo *MRI;
      44             :   const std::string GENERATE_STUBS = "gs";
      45             : 
      46             : #define GET_ASSEMBLER_HEADER
      47             : #include "AVRGenAsmMatcher.inc"
      48             : 
      49             :   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
      50             :                                OperandVector &Operands, MCStreamer &Out,
      51             :                                uint64_t &ErrorInfo,
      52             :                                bool MatchingInlineAsm) override;
      53             : 
      54             :   bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
      55             : 
      56             :   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
      57             :                         SMLoc NameLoc, OperandVector &Operands) override;
      58             : 
      59             :   bool ParseDirective(AsmToken DirectiveID) override;
      60             : 
      61             :   OperandMatchResultTy parseMemriOperand(OperandVector &Operands);
      62             : 
      63             :   bool parseOperand(OperandVector &Operands);
      64             :   int parseRegisterName(unsigned (*matchFn)(StringRef));
      65             :   int parseRegisterName();
      66             :   int parseRegister();
      67             :   bool tryParseRegisterOperand(OperandVector &Operands);
      68             :   bool tryParseExpression(OperandVector &Operands);
      69             :   bool tryParseRelocExpression(OperandVector &Operands);
      70             :   void eatComma();
      71             : 
      72             :   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
      73             :                                       unsigned Kind) override;
      74             : 
      75           0 :   unsigned toDREG(unsigned Reg, unsigned From = AVR::sub_lo) {
      76             :     MCRegisterClass const *Class = &AVRMCRegisterClasses[AVR::DREGSRegClassID];
      77           0 :     return MRI->getMatchingSuperReg(Reg, From, Class);
      78             :   }
      79             : 
      80             :   bool emit(MCInst &Instruction, SMLoc const &Loc, MCStreamer &Out) const;
      81             :   bool invalidOperand(SMLoc const &Loc, OperandVector const &Operands,
      82             :                       uint64_t const &ErrorInfo);
      83             :   bool missingFeature(SMLoc const &Loc, uint64_t const &ErrorInfo);
      84             : 
      85             :   bool parseLiteralValues(unsigned SizeInBytes, SMLoc L);
      86             : 
      87             : public:
      88        4259 :   AVRAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
      89             :                const MCInstrInfo &MII, const MCTargetOptions &Options)
      90        4259 :       : MCTargetAsmParser(Options, STI, MII), STI(STI), Parser(Parser) {
      91        4259 :     MCAsmParserExtension::Initialize(Parser);
      92        4259 :     MRI = getContext().getRegisterInfo();
      93             : 
      94        4259 :     setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
      95        4259 :   }
      96             : 
      97           0 :   MCAsmParser &getParser() const { return Parser; }
      98           0 :   MCAsmLexer &getLexer() const { return Parser.getLexer(); }
      99             : };
     100             : 
     101             : /// An parsed AVR assembly operand.
     102             : class AVROperand : public MCParsedAsmOperand {
     103             :   typedef MCParsedAsmOperand Base;
     104             :   enum KindTy { k_Immediate, k_Register, k_Token, k_Memri } Kind;
     105             : 
     106             : public:
     107             :   AVROperand(StringRef Tok, SMLoc const &S)
     108           0 :       : Base(), Kind(k_Token), Tok(Tok), Start(S), End(S) {}
     109             :   AVROperand(unsigned Reg, SMLoc const &S, SMLoc const &E)
     110           0 :       : Base(), Kind(k_Register), RegImm({Reg, nullptr}), Start(S), End(E) {}
     111             :   AVROperand(MCExpr const *Imm, SMLoc const &S, SMLoc const &E)
     112           0 :       : Base(), Kind(k_Immediate), RegImm({0, Imm}), Start(S), End(E) {}
     113             :   AVROperand(unsigned Reg, MCExpr const *Imm, SMLoc const &S, SMLoc const &E)
     114           0 :       : Base(), Kind(k_Memri), RegImm({Reg, Imm}), Start(S), End(E) {}
     115             : 
     116             :   struct RegisterImmediate {
     117             :     unsigned Reg;
     118             :     MCExpr const *Imm;
     119             :   };
     120             :   union {
     121             :     StringRef Tok;
     122             :     RegisterImmediate RegImm;
     123             :   };
     124             : 
     125             :   SMLoc Start, End;
     126             : 
     127             : public:
     128           0 :   void addRegOperands(MCInst &Inst, unsigned N) const {
     129             :     assert(Kind == k_Register && "Unexpected operand kind");
     130             :     assert(N == 1 && "Invalid number of operands!");
     131             : 
     132           0 :     Inst.addOperand(MCOperand::createReg(getReg()));
     133           0 :   }
     134             : 
     135           0 :   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
     136             :     // Add as immediate when possible
     137           0 :     if (!Expr)
     138           0 :       Inst.addOperand(MCOperand::createImm(0));
     139             :     else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
     140           0 :       Inst.addOperand(MCOperand::createImm(CE->getValue()));
     141             :     else
     142           0 :       Inst.addOperand(MCOperand::createExpr(Expr));
     143           0 :   }
     144             : 
     145           0 :   void addImmOperands(MCInst &Inst, unsigned N) const {
     146             :     assert(Kind == k_Immediate && "Unexpected operand kind");
     147             :     assert(N == 1 && "Invalid number of operands!");
     148             : 
     149         356 :     const MCExpr *Expr = getImm();
     150         356 :     addExpr(Inst, Expr);
     151           0 :   }
     152             : 
     153             :   /// Adds the contained reg+imm operand to an instruction.
     154           0 :   void addMemriOperands(MCInst &Inst, unsigned N) const {
     155             :     assert(Kind == k_Memri && "Unexpected operand kind");
     156             :     assert(N == 2 && "Invalid number of operands");
     157             : 
     158           0 :     Inst.addOperand(MCOperand::createReg(getReg()));
     159           0 :     addExpr(Inst, getImm());
     160           0 :   }
     161             : 
     162         720 :   bool isReg() const { return Kind == k_Register; }
     163         437 :   bool isImm() const { return Kind == k_Immediate; }
     164        1028 :   bool isToken() const { return Kind == k_Token; }
     165           0 :   bool isMem() const { return Kind == k_Memri; }
     166           0 :   bool isMemri() const { return Kind == k_Memri; }
     167             : 
     168           0 :   StringRef getToken() const {
     169             :     assert(Kind == k_Token && "Invalid access!");
     170           0 :     return Tok;
     171             :   }
     172             : 
     173        1144 :   unsigned getReg() const {
     174             :     assert((Kind == k_Register || Kind == k_Memri) && "Invalid access!");
     175             : 
     176        1144 :     return RegImm.Reg;
     177             :   }
     178             : 
     179           0 :   const MCExpr *getImm() const {
     180             :     assert((Kind == k_Immediate || Kind == k_Memri) && "Invalid access!");
     181           0 :     return RegImm.Imm;
     182             :   }
     183             : 
     184             :   static std::unique_ptr<AVROperand> CreateToken(StringRef Str, SMLoc S) {
     185          29 :     return make_unique<AVROperand>(Str, S);
     186             :   }
     187             : 
     188             :   static std::unique_ptr<AVROperand> CreateReg(unsigned RegNum, SMLoc S,
     189             :                                                SMLoc E) {
     190         525 :     return make_unique<AVROperand>(RegNum, S, E);
     191             :   }
     192             : 
     193             :   static std::unique_ptr<AVROperand> CreateImm(const MCExpr *Val, SMLoc S,
     194             :                                                SMLoc E) {
     195         363 :     return make_unique<AVROperand>(Val, S, E);
     196             :   }
     197             : 
     198             :   static std::unique_ptr<AVROperand>
     199             :   CreateMemri(unsigned RegNum, const MCExpr *Val, SMLoc S, SMLoc E) {
     200          10 :     return make_unique<AVROperand>(RegNum, Val, S, E);
     201             :   }
     202             : 
     203             :   void makeToken(StringRef Token) {
     204             :     Kind = k_Token;
     205             :     Tok = Token;
     206             :   }
     207             : 
     208             :   void makeReg(unsigned RegNo) {
     209          33 :     Kind = k_Register;
     210          33 :     RegImm = {RegNo, nullptr};
     211             :   }
     212             : 
     213             :   void makeImm(MCExpr const *Ex) {
     214             :     Kind = k_Immediate;
     215             :     RegImm = {0, Ex};
     216             :   }
     217             : 
     218             :   void makeMemri(unsigned RegNo, MCExpr const *Imm) {
     219             :     Kind = k_Memri;
     220             :     RegImm = {RegNo, Imm};
     221             :   }
     222             : 
     223           0 :   SMLoc getStartLoc() const { return Start; }
     224           0 :   SMLoc getEndLoc() const { return End; }
     225             : 
     226           0 :   virtual void print(raw_ostream &O) const {
     227           0 :     switch (Kind) {
     228           0 :     case k_Token:
     229           0 :       O << "Token: \"" << getToken() << "\"";
     230           0 :       break;
     231           0 :     case k_Register:
     232           0 :       O << "Register: " << getReg();
     233             :       break;
     234           0 :     case k_Immediate:
     235           0 :       O << "Immediate: \"" << *getImm() << "\"";
     236           0 :       break;
     237           0 :     case k_Memri: {
     238             :       // only manually print the size for non-negative values,
     239             :       // as the sign is inserted automatically.
     240           0 :       O << "Memri: \"" << getReg() << '+' << *getImm() << "\"";
     241           0 :       break;
     242             :     }
     243             :     }
     244           0 :     O << "\n";
     245           0 :   }
     246             : };
     247             : 
     248             : // Auto-generated Match Functions
     249             : 
     250             : /// Maps from the set of all register names to a register number.
     251             : /// \note Generated by TableGen.
     252             : static unsigned MatchRegisterName(StringRef Name);
     253             : 
     254             : /// Maps from the set of all alternative registernames to a register number.
     255             : /// \note Generated by TableGen.
     256             : static unsigned MatchRegisterAltName(StringRef Name);
     257             : 
     258           0 : bool AVRAsmParser::invalidOperand(SMLoc const &Loc,
     259             :                                   OperandVector const &Operands,
     260             :                                   uint64_t const &ErrorInfo) {
     261           0 :   SMLoc ErrorLoc = Loc;
     262             :   char const *Diag = 0;
     263             : 
     264           0 :   if (ErrorInfo != ~0U) {
     265           0 :     if (ErrorInfo >= Operands.size()) {
     266             :       Diag = "too few operands for instruction.";
     267             :     } else {
     268             :       AVROperand const &Op = (AVROperand const &)*Operands[ErrorInfo];
     269             : 
     270             :       // TODO: See if we can do a better error than just "invalid ...".
     271           0 :       if (Op.getStartLoc() != SMLoc()) {
     272           0 :         ErrorLoc = Op.getStartLoc();
     273             :       }
     274             :     }
     275             :   }
     276             : 
     277             :   if (!Diag) {
     278             :     Diag = "invalid operand for instruction";
     279             :   }
     280             : 
     281           0 :   return Error(ErrorLoc, Diag);
     282             : }
     283             : 
     284           0 : bool AVRAsmParser::missingFeature(llvm::SMLoc const &Loc,
     285             :                                   uint64_t const &ErrorInfo) {
     286           0 :   return Error(Loc, "instruction requires a CPU feature not currently enabled");
     287             : }
     288             : 
     289        4720 : bool AVRAsmParser::emit(MCInst &Inst, SMLoc const &Loc, MCStreamer &Out) const {
     290             :   Inst.setLoc(Loc);
     291        4720 :   Out.EmitInstruction(Inst, STI);
     292             : 
     293        4720 :   return false;
     294             : }
     295             : 
     296        4720 : bool AVRAsmParser::MatchAndEmitInstruction(SMLoc Loc, unsigned &Opcode,
     297             :                                            OperandVector &Operands,
     298             :                                            MCStreamer &Out, uint64_t &ErrorInfo,
     299             :                                            bool MatchingInlineAsm) {
     300             :   MCInst Inst;
     301             :   unsigned MatchResult =
     302        4720 :       MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
     303             : 
     304        4720 :   switch (MatchResult) {
     305        4720 :   case Match_Success:        return emit(Inst, Loc, Out);
     306           0 :   case Match_MissingFeature: return missingFeature(Loc, ErrorInfo);
     307           0 :   case Match_InvalidOperand: return invalidOperand(Loc, Operands, ErrorInfo);
     308           0 :   case Match_MnemonicFail:   return Error(Loc, "invalid instruction");
     309             :   default:                   return true;
     310             :   }
     311             : }
     312             : 
     313             : /// Parses a register name using a given matching function.
     314             : /// Checks for lowercase or uppercase if necessary.
     315         832 : int AVRAsmParser::parseRegisterName(unsigned (*matchFn)(StringRef)) {
     316         832 :   StringRef Name = Parser.getTok().getString();
     317             : 
     318         832 :   int RegNum = matchFn(Name);
     319             : 
     320             :   // GCC supports case insensitive register names. Some of the AVR registers
     321             :   // are all lower case, some are all upper case but non are mixed. We prefer
     322             :   // to use the original names in the register definitions. That is why we
     323             :   // have to test both upper and lower case here.
     324         832 :   if (RegNum == AVR::NoRegister) {
     325         303 :     RegNum = matchFn(Name.lower());
     326             :   }
     327         832 :   if (RegNum == AVR::NoRegister) {
     328         303 :     RegNum = matchFn(Name.upper());
     329             :   }
     330             : 
     331         832 :   return RegNum;
     332             : }
     333             : 
     334         647 : int AVRAsmParser::parseRegisterName() {
     335         647 :   int RegNum = parseRegisterName(&MatchRegisterName);
     336             : 
     337         647 :   if (RegNum == AVR::NoRegister)
     338         185 :     RegNum = parseRegisterName(&MatchRegisterAltName);
     339             : 
     340         647 :   return RegNum;
     341             : }
     342             : 
     343         647 : int AVRAsmParser::parseRegister() {
     344             :   int RegNum = AVR::NoRegister;
     345             : 
     346         647 :   if (Parser.getTok().is(AsmToken::Identifier)) {
     347             :     // Check for register pair syntax
     348        1294 :     if (Parser.getLexer().peekTok().is(AsmToken::Colon)) {
     349           2 :       Parser.Lex();
     350           2 :       Parser.Lex(); // Eat high (odd) register and colon
     351             : 
     352           2 :       if (Parser.getTok().is(AsmToken::Identifier)) {
     353             :         // Convert lower (even) register to DREG
     354           2 :         RegNum = toDREG(parseRegisterName());
     355             :       }
     356             :     } else {
     357         645 :       RegNum = parseRegisterName();
     358             :     }
     359             :   }
     360         647 :   return RegNum;
     361             : }
     362             : 
     363         637 : bool AVRAsmParser::tryParseRegisterOperand(OperandVector &Operands) {
     364         637 :   int RegNo = parseRegister();
     365             : 
     366         637 :   if (RegNo == AVR::NoRegister)
     367             :     return true;
     368             : 
     369         525 :   AsmToken const &T = Parser.getTok();
     370        1050 :   Operands.push_back(AVROperand::CreateReg(RegNo, T.getLoc(), T.getEndLoc()));
     371         525 :   Parser.Lex(); // Eat register token.
     372             : 
     373         525 :   return false;
     374             : }
     375             : 
     376         375 : bool AVRAsmParser::tryParseExpression(OperandVector &Operands) {
     377         375 :   SMLoc S = Parser.getTok().getLoc();
     378             : 
     379         375 :   if (!tryParseRelocExpression(Operands))
     380             :     return false;
     381             : 
     382         284 :   if ((Parser.getTok().getKind() == AsmToken::Plus ||
     383         284 :        Parser.getTok().getKind() == AsmToken::Minus) &&
     384         314 :       Parser.getLexer().peekTok().getKind() == AsmToken::Identifier) {
     385             :     // Don't handle this case - it should be split into two
     386             :     // separate tokens.
     387             :     return true;
     388             :   }
     389             : 
     390             :   // Parse (potentially inner) expression
     391             :   MCExpr const *Expression;
     392         272 :   if (getParser().parseExpression(Expression))
     393             :     return true;
     394             : 
     395         272 :   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
     396         544 :   Operands.push_back(AVROperand::CreateImm(Expression, S, E));
     397         272 :   return false;
     398             : }
     399             : 
     400         375 : bool AVRAsmParser::tryParseRelocExpression(OperandVector &Operands) {
     401             :   bool isNegated = false;
     402             :   AVRMCExpr::VariantKind ModifierKind = AVRMCExpr::VK_AVR_None;
     403             : 
     404         375 :   SMLoc S = Parser.getTok().getLoc();
     405             : 
     406             :   // Check for sign
     407        2250 :   AsmToken tokens[2];
     408         375 :   size_t ReadCount = Parser.getLexer().peekTokens(tokens);
     409             : 
     410         375 :   if (ReadCount == 2) {
     411         422 :     if ((tokens[0].getKind() == AsmToken::Identifier &&
     412         375 :          tokens[1].getKind() == AsmToken::LParen) ||
     413          56 :         (tokens[0].getKind() == AsmToken::LParen &&
     414          56 :          tokens[1].getKind() == AsmToken::Minus)) {
     415             : 
     416          43 :       AsmToken::TokenKind CurTok = Parser.getLexer().getKind();
     417          43 :       if (CurTok == AsmToken::Minus ||
     418          16 :           tokens[1].getKind() == AsmToken::Minus) {
     419             :         isNegated = true;
     420             :       } else {
     421             :         assert(CurTok == AsmToken::Plus);
     422             :         isNegated = false;
     423             :       }
     424             : 
     425             :       // Eat the sign
     426          43 :       if (CurTok == AsmToken::Minus || CurTok == AsmToken::Plus)
     427          35 :         Parser.Lex();
     428             :     }
     429             :   }
     430             : 
     431             :   // Check if we have a target specific modifier (lo8, hi8, &c)
     432         375 :   if (Parser.getTok().getKind() != AsmToken::Identifier ||
     433         669 :       Parser.getLexer().peekTok().getKind() != AsmToken::LParen) {
     434             :     // Not a reloc expr
     435             :     return true;
     436             :   }
     437          91 :   StringRef ModifierName = Parser.getTok().getString();
     438          91 :   ModifierKind = AVRMCExpr::getKindByName(ModifierName.str().c_str());
     439             : 
     440          91 :   if (ModifierKind != AVRMCExpr::VK_AVR_None) {
     441          91 :     Parser.Lex();
     442          91 :     Parser.Lex(); // Eat modifier name and parenthesis
     443          91 :     if (Parser.getTok().getString() == GENERATE_STUBS &&
     444           2 :         Parser.getTok().getKind() == AsmToken::Identifier) {
     445           6 :       std::string GSModName = ModifierName.str() + "_" + GENERATE_STUBS;
     446           2 :       ModifierKind = AVRMCExpr::getKindByName(GSModName.c_str());
     447           2 :       if (ModifierKind != AVRMCExpr::VK_AVR_None)
     448           2 :         Parser.Lex(); // Eat gs modifier name
     449             :     }
     450             :   } else {
     451           0 :     return Error(Parser.getTok().getLoc(), "unknown modifier");
     452             :   }
     453             : 
     454          91 :   if (tokens[1].getKind() == AsmToken::Minus ||
     455             :       tokens[1].getKind() == AsmToken::Plus) {
     456          16 :     Parser.Lex();
     457             :     assert(Parser.getTok().getKind() == AsmToken::LParen);
     458          16 :     Parser.Lex(); // Eat the sign and parenthesis
     459             :   }
     460             : 
     461             :   MCExpr const *InnerExpression;
     462          91 :   if (getParser().parseExpression(InnerExpression))
     463             :     return true;
     464             : 
     465          91 :   if (tokens[1].getKind() == AsmToken::Minus ||
     466             :       tokens[1].getKind() == AsmToken::Plus) {
     467             :     assert(Parser.getTok().getKind() == AsmToken::RParen);
     468          16 :     Parser.Lex(); // Eat closing parenthesis
     469             :   }
     470             : 
     471             :   // If we have a modifier wrap the inner expression
     472             :   assert(Parser.getTok().getKind() == AsmToken::RParen);
     473          91 :   Parser.Lex(); // Eat closing parenthesis
     474             : 
     475          91 :   MCExpr const *Expression = AVRMCExpr::create(ModifierKind, InnerExpression,
     476          91 :                                                isNegated, getContext());
     477             : 
     478          91 :   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
     479         182 :   Operands.push_back(AVROperand::CreateImm(Expression, S, E));
     480             : 
     481          91 :   return false;
     482             : }
     483             : 
     484         917 : bool AVRAsmParser::parseOperand(OperandVector &Operands) {
     485             :   LLVM_DEBUG(dbgs() << "parseOperand\n");
     486             : 
     487         917 :   switch (getLexer().getKind()) {
     488           0 :   default:
     489           0 :     return Error(Parser.getTok().getLoc(), "unexpected token in operand");
     490             : 
     491         637 :   case AsmToken::Identifier:
     492             :     // Try to parse a register, if it fails,
     493             :     // fall through to the next case.
     494         637 :     if (!tryParseRegisterOperand(Operands)) {
     495             :       return false;
     496             :     }
     497             :     LLVM_FALLTHROUGH;
     498             :   case AsmToken::LParen:
     499             :   case AsmToken::Integer:
     500             :   case AsmToken::Dot:
     501         325 :     return tryParseExpression(Operands);
     502          67 :   case AsmToken::Plus:
     503             :   case AsmToken::Minus: {
     504             :     // If the sign preceeds a number, parse the number,
     505             :     // otherwise treat the sign a an independent token.
     506         137 :     switch (getLexer().peekTok().getKind()) {
     507          50 :     case AsmToken::Integer:
     508             :     case AsmToken::BigNum:
     509             :     case AsmToken::Identifier:
     510             :     case AsmToken::Real:
     511          50 :       if (!tryParseExpression(Operands))
     512             :         return false;
     513             :     default:
     514             :       break;
     515             :     }
     516             :     // Treat the token as an independent token.
     517         116 :     Operands.push_back(AVROperand::CreateToken(Parser.getTok().getString(),
     518          29 :                                                Parser.getTok().getLoc()));
     519          29 :     Parser.Lex(); // Eat the token.
     520          29 :     return false;
     521             :   }
     522             :   }
     523             : 
     524             :   // Could not parse operand
     525             :   return true;
     526             : }
     527             : 
     528             : OperandMatchResultTy
     529          10 : AVRAsmParser::parseMemriOperand(OperandVector &Operands) {
     530             :   LLVM_DEBUG(dbgs() << "parseMemriOperand()\n");
     531             : 
     532             :   SMLoc E, S;
     533             :   MCExpr const *Expression;
     534             :   int RegNo;
     535             : 
     536             :   // Parse register.
     537             :   {
     538          10 :     RegNo = parseRegister();
     539             : 
     540          10 :     if (RegNo == AVR::NoRegister)
     541             :       return MatchOperand_ParseFail;
     542             : 
     543          10 :     S = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
     544          10 :     Parser.Lex(); // Eat register token.
     545             :   }
     546             : 
     547             :   // Parse immediate;
     548             :   {
     549          10 :     if (getParser().parseExpression(Expression))
     550             :       return MatchOperand_ParseFail;
     551             : 
     552          10 :     E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
     553             :   }
     554             : 
     555          20 :   Operands.push_back(AVROperand::CreateMemri(RegNo, Expression, S, E));
     556             : 
     557          10 :   return MatchOperand_Success;
     558             : }
     559             : 
     560           0 : bool AVRAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
     561             :                                  SMLoc &EndLoc) {
     562           0 :   StartLoc = Parser.getTok().getLoc();
     563           0 :   RegNo = parseRegister();
     564           0 :   EndLoc = Parser.getTok().getLoc();
     565             : 
     566           0 :   return (RegNo == AVR::NoRegister);
     567             : }
     568             : 
     569         398 : void AVRAsmParser::eatComma() {
     570         398 :   if (getLexer().is(AsmToken::Comma)) {
     571         369 :     Parser.Lex();
     572             :   } else {
     573             :     // GCC allows commas to be omitted.
     574             :   }
     575         398 : }
     576             : 
     577        4720 : bool AVRAsmParser::ParseInstruction(ParseInstructionInfo &Info,
     578             :                                     StringRef Mnemonic, SMLoc NameLoc,
     579             :                                     OperandVector &Operands) {
     580        9440 :   Operands.push_back(AVROperand::CreateToken(Mnemonic, NameLoc));
     581             : 
     582             :   bool first = true;
     583        5647 :   while (getLexer().isNot(AsmToken::EndOfStatement)) {
     584         927 :     if (!first) eatComma();
     585             : 
     586             :     first = false;
     587             : 
     588         927 :     auto MatchResult = MatchOperandParserImpl(Operands, Mnemonic);
     589             : 
     590         927 :     if (MatchResult == MatchOperand_Success) {
     591             :       continue;
     592             :     }
     593             : 
     594         917 :     if (MatchResult == MatchOperand_ParseFail) {
     595           0 :       SMLoc Loc = getLexer().getLoc();
     596           0 :       Parser.eatToEndOfStatement();
     597             : 
     598           0 :       return Error(Loc, "failed to parse register and immediate pair");
     599             :     }
     600             : 
     601         917 :     if (parseOperand(Operands)) {
     602           0 :       SMLoc Loc = getLexer().getLoc();
     603           0 :       Parser.eatToEndOfStatement();
     604           0 :       return Error(Loc, "unexpected token in argument list");
     605             :     }
     606             :   }
     607        4720 :   Parser.Lex(); // Consume the EndOfStatement
     608        4720 :   return false;
     609             : }
     610             : 
     611          12 : bool AVRAsmParser::ParseDirective(llvm::AsmToken DirectiveID) {
     612          12 :   StringRef IDVal = DirectiveID.getIdentifier();
     613          24 :   if (IDVal.lower() == ".long") {
     614           1 :     parseLiteralValues(SIZE_LONG, DirectiveID.getLoc());
     615          44 :   } else if (IDVal.lower() == ".word" || IDVal.lower() == ".short") {
     616           4 :     parseLiteralValues(SIZE_WORD, DirectiveID.getLoc());
     617          14 :   } else if (IDVal.lower() == ".byte") {
     618           5 :     parseLiteralValues(1, DirectiveID.getLoc());
     619             :   }
     620          12 :   return true;
     621             : }
     622             : 
     623          10 : bool AVRAsmParser::parseLiteralValues(unsigned SizeInBytes, SMLoc L) {
     624          10 :   MCAsmParser &Parser = getParser();
     625             :   AVRMCELFStreamer &AVRStreamer =
     626          10 :       static_cast<AVRMCELFStreamer &>(Parser.getStreamer());
     627          60 :   AsmToken Tokens[2];
     628          10 :   size_t ReadCount = Parser.getLexer().peekTokens(Tokens);
     629          10 :   if (ReadCount == 2 && Parser.getTok().getKind() == AsmToken::Identifier &&
     630          20 :       Tokens[0].getKind() == AsmToken::Minus &&
     631           3 :       Tokens[1].getKind() == AsmToken::Identifier) {
     632           3 :     MCSymbol *Symbol = getContext().getOrCreateSymbol(".text");
     633           3 :     AVRStreamer.EmitValueForModiferKind(Symbol, SizeInBytes, L,
     634             :             AVRMCExpr::VK_AVR_None);
     635           3 :     return false;
     636             :   }
     637             : 
     638           7 :   if (Parser.getTok().getKind() == AsmToken::Identifier &&
     639          21 :       Parser.getLexer().peekTok().getKind() == AsmToken::LParen) {
     640           5 :     StringRef ModifierName = Parser.getTok().getString();
     641             :     AVRMCExpr::VariantKind ModifierKind =
     642           5 :         AVRMCExpr::getKindByName(ModifierName.str().c_str());
     643           5 :     if (ModifierKind != AVRMCExpr::VK_AVR_None) {
     644           5 :       Parser.Lex();
     645           5 :       Parser.Lex(); // Eat the modifier and parenthesis
     646             :     } else {
     647           0 :       return Error(Parser.getTok().getLoc(), "unknown modifier");
     648             :     }
     649             :     MCSymbol *Symbol =
     650           5 :         getContext().getOrCreateSymbol(Parser.getTok().getString());
     651           5 :     AVRStreamer.EmitValueForModiferKind(Symbol, SizeInBytes, L, ModifierKind);
     652           5 :     return false;
     653             :   }
     654             : 
     655             :   auto parseOne = [&]() -> bool {
     656             :     const MCExpr *Value;
     657             :     if (Parser.parseExpression(Value))
     658             :       return true;
     659             :     Parser.getStreamer().EmitValue(Value, SizeInBytes, L);
     660             :     return false;
     661           2 :   };
     662           2 :   return (parseMany(parseOne));
     663             : }
     664             : 
     665       75416 : extern "C" void LLVMInitializeAVRAsmParser() {
     666       75416 :   RegisterMCAsmParser<AVRAsmParser> X(getTheAVRTarget());
     667       75416 : }
     668             : 
     669             : #define GET_REGISTER_MATCHER
     670             : #define GET_MATCHER_IMPLEMENTATION
     671             : #include "AVRGenAsmMatcher.inc"
     672             : 
     673             : // Uses enums defined in AVRGenAsmMatcher.inc
     674          81 : unsigned AVRAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
     675             :                                                   unsigned ExpectedKind) {
     676             :   AVROperand &Op = static_cast<AVROperand &>(AsmOp);
     677             :   MatchClassKind Expected = static_cast<MatchClassKind>(ExpectedKind);
     678             : 
     679             :   // If need be, GCC converts bare numbers to register names
     680             :   // It's ugly, but GCC supports it.
     681          81 :   if (Op.isImm()) {
     682           7 :     if (MCConstantExpr const *Const = dyn_cast<MCConstantExpr>(Op.getImm())) {
     683           7 :       int64_t RegNum = Const->getValue();
     684           8 :       std::ostringstream RegName;
     685             :       RegName << "r" << RegNum;
     686           7 :       RegNum = MatchRegisterName(RegName.str().c_str());
     687           7 :       if (RegNum != AVR::NoRegister) {
     688             :         Op.makeReg(RegNum);
     689           7 :         if (validateOperandClass(Op, Expected) == Match_Success) {
     690           6 :           return Match_Success;
     691             :         }
     692             :       }
     693             :       // Let the other quirks try their magic.
     694             :     }
     695             :   }
     696             : 
     697          75 :   if (Op.isReg()) {
     698             :     // If the instruction uses a register pair but we got a single, lower
     699             :     // register we perform a "class cast".
     700          47 :     if (isSubclass(Expected, MCK_DREGS)) {
     701          26 :       unsigned correspondingDREG = toDREG(Op.getReg());
     702             : 
     703          26 :       if (correspondingDREG != AVR::NoRegister) {
     704             :         Op.makeReg(correspondingDREG);
     705          26 :         return validateOperandClass(Op, Expected);
     706             :       }
     707             :     }
     708             :   }
     709             :   return Match_InvalidOperand;
     710             : }
     711             : 
     712             : } // end of namespace llvm

Generated by: LCOV version 1.13