xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/AVR/AsmParser/AVRAsmParser.cpp (revision 6c4b055cfb6bf549e9145dde6454cc6b178c35e4)
10b57cec5SDimitry Andric //===---- AVRAsmParser.cpp - Parse AVR assembly to MCInst instructions ----===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "AVR.h"
100b57cec5SDimitry Andric #include "AVRRegisterInfo.h"
110b57cec5SDimitry Andric #include "MCTargetDesc/AVRMCELFStreamer.h"
120b57cec5SDimitry Andric #include "MCTargetDesc/AVRMCExpr.h"
130b57cec5SDimitry Andric #include "MCTargetDesc/AVRMCTargetDesc.h"
140b57cec5SDimitry Andric #include "TargetInfo/AVRTargetInfo.h"
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "llvm/ADT/APInt.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCInst.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCInstBuilder.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCAsmLexer.h"
220b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
230b57cec5SDimitry Andric #include "llvm/MC/MCParser/MCTargetAsmParser.h"
240b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h"
250b57cec5SDimitry Andric #include "llvm/MC/MCSubtargetInfo.h"
260b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h"
270b57cec5SDimitry Andric #include "llvm/MC/MCValue.h"
28349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
290b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
300b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h"
310b57cec5SDimitry Andric 
32bdd1243dSDimitry Andric #include <array>
330b57cec5SDimitry Andric #include <sstream>
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric #define DEBUG_TYPE "avr-asm-parser"
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric using namespace llvm;
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric namespace {
400b57cec5SDimitry Andric /// Parses AVR assembly from a stream.
410b57cec5SDimitry Andric class AVRAsmParser : public MCTargetAsmParser {
420b57cec5SDimitry Andric   const MCSubtargetInfo &STI;
430b57cec5SDimitry Andric   MCAsmParser &Parser;
440b57cec5SDimitry Andric   const MCRegisterInfo *MRI;
450b57cec5SDimitry Andric   const std::string GENERATE_STUBS = "gs";
460b57cec5SDimitry Andric 
4781ad6265SDimitry Andric   enum AVRMatchResultTy {
4881ad6265SDimitry Andric     Match_InvalidRegisterOnTiny = FIRST_TARGET_MATCH_RESULT_TY + 1,
4981ad6265SDimitry Andric   };
5081ad6265SDimitry Andric 
510b57cec5SDimitry Andric #define GET_ASSEMBLER_HEADER
520b57cec5SDimitry Andric #include "AVRGenAsmMatcher.inc"
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric   bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
550b57cec5SDimitry Andric                                OperandVector &Operands, MCStreamer &Out,
560b57cec5SDimitry Andric                                uint64_t &ErrorInfo,
570b57cec5SDimitry Andric                                bool MatchingInlineAsm) override;
580b57cec5SDimitry Andric 
595f757f3fSDimitry Andric   bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
605f757f3fSDimitry Andric   ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
615ffd83dbSDimitry Andric                                SMLoc &EndLoc) override;
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
640b57cec5SDimitry Andric                         SMLoc NameLoc, OperandVector &Operands) override;
650b57cec5SDimitry Andric 
6606c3fb27SDimitry Andric   ParseStatus parseDirective(AsmToken DirectiveID) override;
670b57cec5SDimitry Andric 
685f757f3fSDimitry Andric   ParseStatus parseMemriOperand(OperandVector &Operands);
690b57cec5SDimitry Andric 
70bdd1243dSDimitry Andric   bool parseOperand(OperandVector &Operands, bool maybeReg);
710fca6ea1SDimitry Andric   int parseRegisterName(MCRegister (*matchFn)(StringRef));
720b57cec5SDimitry Andric   int parseRegisterName();
735ffd83dbSDimitry Andric   int parseRegister(bool RestoreOnFailure = false);
740b57cec5SDimitry Andric   bool tryParseRegisterOperand(OperandVector &Operands);
75*6c4b055cSDimitry Andric   bool tryParseExpression(OperandVector &Operands, int64_t offset);
760b57cec5SDimitry Andric   bool tryParseRelocExpression(OperandVector &Operands);
770b57cec5SDimitry Andric   void eatComma();
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric   unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
800b57cec5SDimitry Andric                                       unsigned Kind) override;
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   unsigned toDREG(unsigned Reg, unsigned From = AVR::sub_lo) {
830b57cec5SDimitry Andric     MCRegisterClass const *Class = &AVRMCRegisterClasses[AVR::DREGSRegClassID];
840b57cec5SDimitry Andric     return MRI->getMatchingSuperReg(Reg, From, Class);
850b57cec5SDimitry Andric   }
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric   bool emit(MCInst &Instruction, SMLoc const &Loc, MCStreamer &Out) const;
880b57cec5SDimitry Andric   bool invalidOperand(SMLoc const &Loc, OperandVector const &Operands,
890b57cec5SDimitry Andric                       uint64_t const &ErrorInfo);
900b57cec5SDimitry Andric   bool missingFeature(SMLoc const &Loc, uint64_t const &ErrorInfo);
910b57cec5SDimitry Andric 
9206c3fb27SDimitry Andric   ParseStatus parseLiteralValues(unsigned SizeInBytes, SMLoc L);
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric public:
950b57cec5SDimitry Andric   AVRAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser,
960b57cec5SDimitry Andric                const MCInstrInfo &MII, const MCTargetOptions &Options)
970b57cec5SDimitry Andric       : MCTargetAsmParser(Options, STI, MII), STI(STI), Parser(Parser) {
980b57cec5SDimitry Andric     MCAsmParserExtension::Initialize(Parser);
990b57cec5SDimitry Andric     MRI = getContext().getRegisterInfo();
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric     setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
1020b57cec5SDimitry Andric   }
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric   MCAsmParser &getParser() const { return Parser; }
1050b57cec5SDimitry Andric   MCAsmLexer &getLexer() const { return Parser.getLexer(); }
1060b57cec5SDimitry Andric };
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric /// An parsed AVR assembly operand.
1090b57cec5SDimitry Andric class AVROperand : public MCParsedAsmOperand {
1100b57cec5SDimitry Andric   typedef MCParsedAsmOperand Base;
1110b57cec5SDimitry Andric   enum KindTy { k_Immediate, k_Register, k_Token, k_Memri } Kind;
1120b57cec5SDimitry Andric 
1130b57cec5SDimitry Andric public:
1140b57cec5SDimitry Andric   AVROperand(StringRef Tok, SMLoc const &S)
11504eeddc0SDimitry Andric       : Kind(k_Token), Tok(Tok), Start(S), End(S) {}
1160b57cec5SDimitry Andric   AVROperand(unsigned Reg, SMLoc const &S, SMLoc const &E)
11704eeddc0SDimitry Andric       : Kind(k_Register), RegImm({Reg, nullptr}), Start(S), End(E) {}
1180b57cec5SDimitry Andric   AVROperand(MCExpr const *Imm, SMLoc const &S, SMLoc const &E)
11904eeddc0SDimitry Andric       : Kind(k_Immediate), RegImm({0, Imm}), Start(S), End(E) {}
1200b57cec5SDimitry Andric   AVROperand(unsigned Reg, MCExpr const *Imm, SMLoc const &S, SMLoc const &E)
12104eeddc0SDimitry Andric       : Kind(k_Memri), RegImm({Reg, Imm}), Start(S), End(E) {}
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric   struct RegisterImmediate {
1240b57cec5SDimitry Andric     unsigned Reg;
1250b57cec5SDimitry Andric     MCExpr const *Imm;
1260b57cec5SDimitry Andric   };
1270b57cec5SDimitry Andric   union {
1280b57cec5SDimitry Andric     StringRef Tok;
1290b57cec5SDimitry Andric     RegisterImmediate RegImm;
1300b57cec5SDimitry Andric   };
1310b57cec5SDimitry Andric 
1320b57cec5SDimitry Andric   SMLoc Start, End;
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric public:
1350b57cec5SDimitry Andric   void addRegOperands(MCInst &Inst, unsigned N) const {
1360b57cec5SDimitry Andric     assert(Kind == k_Register && "Unexpected operand kind");
1370b57cec5SDimitry Andric     assert(N == 1 && "Invalid number of operands!");
1380b57cec5SDimitry Andric 
1390b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(getReg()));
1400b57cec5SDimitry Andric   }
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric   void addExpr(MCInst &Inst, const MCExpr *Expr) const {
1430b57cec5SDimitry Andric     // Add as immediate when possible
1440b57cec5SDimitry Andric     if (!Expr)
1450b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(0));
1460b57cec5SDimitry Andric     else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1470b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createImm(CE->getValue()));
1480b57cec5SDimitry Andric     else
1490b57cec5SDimitry Andric       Inst.addOperand(MCOperand::createExpr(Expr));
1500b57cec5SDimitry Andric   }
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric   void addImmOperands(MCInst &Inst, unsigned N) const {
1530b57cec5SDimitry Andric     assert(Kind == k_Immediate && "Unexpected operand kind");
1540b57cec5SDimitry Andric     assert(N == 1 && "Invalid number of operands!");
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric     const MCExpr *Expr = getImm();
1570b57cec5SDimitry Andric     addExpr(Inst, Expr);
1580b57cec5SDimitry Andric   }
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric   /// Adds the contained reg+imm operand to an instruction.
1610b57cec5SDimitry Andric   void addMemriOperands(MCInst &Inst, unsigned N) const {
1620b57cec5SDimitry Andric     assert(Kind == k_Memri && "Unexpected operand kind");
1630b57cec5SDimitry Andric     assert(N == 2 && "Invalid number of operands");
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createReg(getReg()));
1660b57cec5SDimitry Andric     addExpr(Inst, getImm());
1670b57cec5SDimitry Andric   }
1680b57cec5SDimitry Andric 
1690b57cec5SDimitry Andric   void addImmCom8Operands(MCInst &Inst, unsigned N) const {
1700b57cec5SDimitry Andric     assert(N == 1 && "Invalid number of operands!");
1710b57cec5SDimitry Andric     // The operand is actually a imm8, but we have its bitwise
1720b57cec5SDimitry Andric     // negation in the assembly source, so twiddle it here.
173e8d8bef9SDimitry Andric     const auto *CE = cast<MCConstantExpr>(getImm());
1740b57cec5SDimitry Andric     Inst.addOperand(MCOperand::createImm(~(uint8_t)CE->getValue()));
1750b57cec5SDimitry Andric   }
1760b57cec5SDimitry Andric 
1770b57cec5SDimitry Andric   bool isImmCom8() const {
178349cc55cSDimitry Andric     if (!isImm())
179349cc55cSDimitry Andric       return false;
180e8d8bef9SDimitry Andric     const auto *CE = dyn_cast<MCConstantExpr>(getImm());
181349cc55cSDimitry Andric     if (!CE)
182349cc55cSDimitry Andric       return false;
1830b57cec5SDimitry Andric     int64_t Value = CE->getValue();
1840b57cec5SDimitry Andric     return isUInt<8>(Value);
1850b57cec5SDimitry Andric   }
1860b57cec5SDimitry Andric 
1875ffd83dbSDimitry Andric   bool isReg() const override { return Kind == k_Register; }
1885ffd83dbSDimitry Andric   bool isImm() const override { return Kind == k_Immediate; }
1895ffd83dbSDimitry Andric   bool isToken() const override { return Kind == k_Token; }
1905ffd83dbSDimitry Andric   bool isMem() const override { return Kind == k_Memri; }
1910b57cec5SDimitry Andric   bool isMemri() const { return Kind == k_Memri; }
1920b57cec5SDimitry Andric 
1930b57cec5SDimitry Andric   StringRef getToken() const {
1940b57cec5SDimitry Andric     assert(Kind == k_Token && "Invalid access!");
1950b57cec5SDimitry Andric     return Tok;
1960b57cec5SDimitry Andric   }
1970b57cec5SDimitry Andric 
1980fca6ea1SDimitry Andric   MCRegister getReg() const override {
1990b57cec5SDimitry Andric     assert((Kind == k_Register || Kind == k_Memri) && "Invalid access!");
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric     return RegImm.Reg;
2020b57cec5SDimitry Andric   }
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric   const MCExpr *getImm() const {
2050b57cec5SDimitry Andric     assert((Kind == k_Immediate || Kind == k_Memri) && "Invalid access!");
2060b57cec5SDimitry Andric     return RegImm.Imm;
2070b57cec5SDimitry Andric   }
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric   static std::unique_ptr<AVROperand> CreateToken(StringRef Str, SMLoc S) {
2108bcb0991SDimitry Andric     return std::make_unique<AVROperand>(Str, S);
2110b57cec5SDimitry Andric   }
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric   static std::unique_ptr<AVROperand> CreateReg(unsigned RegNum, SMLoc S,
2140b57cec5SDimitry Andric                                                SMLoc E) {
2158bcb0991SDimitry Andric     return std::make_unique<AVROperand>(RegNum, S, E);
2160b57cec5SDimitry Andric   }
2170b57cec5SDimitry Andric 
2180b57cec5SDimitry Andric   static std::unique_ptr<AVROperand> CreateImm(const MCExpr *Val, SMLoc S,
2190b57cec5SDimitry Andric                                                SMLoc E) {
2208bcb0991SDimitry Andric     return std::make_unique<AVROperand>(Val, S, E);
2210b57cec5SDimitry Andric   }
2220b57cec5SDimitry Andric 
2230b57cec5SDimitry Andric   static std::unique_ptr<AVROperand>
2240b57cec5SDimitry Andric   CreateMemri(unsigned RegNum, const MCExpr *Val, SMLoc S, SMLoc E) {
2258bcb0991SDimitry Andric     return std::make_unique<AVROperand>(RegNum, Val, S, E);
2260b57cec5SDimitry Andric   }
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric   void makeToken(StringRef Token) {
2290b57cec5SDimitry Andric     Kind = k_Token;
2300b57cec5SDimitry Andric     Tok = Token;
2310b57cec5SDimitry Andric   }
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric   void makeReg(unsigned RegNo) {
2340b57cec5SDimitry Andric     Kind = k_Register;
2350b57cec5SDimitry Andric     RegImm = {RegNo, nullptr};
2360b57cec5SDimitry Andric   }
2370b57cec5SDimitry Andric 
2380b57cec5SDimitry Andric   void makeImm(MCExpr const *Ex) {
2390b57cec5SDimitry Andric     Kind = k_Immediate;
2400b57cec5SDimitry Andric     RegImm = {0, Ex};
2410b57cec5SDimitry Andric   }
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric   void makeMemri(unsigned RegNo, MCExpr const *Imm) {
2440b57cec5SDimitry Andric     Kind = k_Memri;
2450b57cec5SDimitry Andric     RegImm = {RegNo, Imm};
2460b57cec5SDimitry Andric   }
2470b57cec5SDimitry Andric 
2485ffd83dbSDimitry Andric   SMLoc getStartLoc() const override { return Start; }
2495ffd83dbSDimitry Andric   SMLoc getEndLoc() const override { return End; }
2500b57cec5SDimitry Andric 
2515ffd83dbSDimitry Andric   void print(raw_ostream &O) const override {
2520b57cec5SDimitry Andric     switch (Kind) {
2530b57cec5SDimitry Andric     case k_Token:
2540b57cec5SDimitry Andric       O << "Token: \"" << getToken() << "\"";
2550b57cec5SDimitry Andric       break;
2560b57cec5SDimitry Andric     case k_Register:
2570b57cec5SDimitry Andric       O << "Register: " << getReg();
2580b57cec5SDimitry Andric       break;
2590b57cec5SDimitry Andric     case k_Immediate:
2600b57cec5SDimitry Andric       O << "Immediate: \"" << *getImm() << "\"";
2610b57cec5SDimitry Andric       break;
2620b57cec5SDimitry Andric     case k_Memri: {
2630b57cec5SDimitry Andric       // only manually print the size for non-negative values,
2640b57cec5SDimitry Andric       // as the sign is inserted automatically.
2650b57cec5SDimitry Andric       O << "Memri: \"" << getReg() << '+' << *getImm() << "\"";
2660b57cec5SDimitry Andric       break;
2670b57cec5SDimitry Andric     }
2680b57cec5SDimitry Andric     }
2690b57cec5SDimitry Andric     O << "\n";
2700b57cec5SDimitry Andric   }
2710b57cec5SDimitry Andric };
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric } // end anonymous namespace.
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric // Auto-generated Match Functions
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric /// Maps from the set of all register names to a register number.
2780b57cec5SDimitry Andric /// \note Generated by TableGen.
2790fca6ea1SDimitry Andric static MCRegister MatchRegisterName(StringRef Name);
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric /// Maps from the set of all alternative registernames to a register number.
2820b57cec5SDimitry Andric /// \note Generated by TableGen.
2830fca6ea1SDimitry Andric static MCRegister MatchRegisterAltName(StringRef Name);
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric bool AVRAsmParser::invalidOperand(SMLoc const &Loc,
2860b57cec5SDimitry Andric                                   OperandVector const &Operands,
2870b57cec5SDimitry Andric                                   uint64_t const &ErrorInfo) {
2880b57cec5SDimitry Andric   SMLoc ErrorLoc = Loc;
28904eeddc0SDimitry Andric   char const *Diag = nullptr;
2900b57cec5SDimitry Andric 
2910b57cec5SDimitry Andric   if (ErrorInfo != ~0U) {
2920b57cec5SDimitry Andric     if (ErrorInfo >= Operands.size()) {
2930b57cec5SDimitry Andric       Diag = "too few operands for instruction.";
2940b57cec5SDimitry Andric     } else {
2950b57cec5SDimitry Andric       AVROperand const &Op = (AVROperand const &)*Operands[ErrorInfo];
2960b57cec5SDimitry Andric 
2970b57cec5SDimitry Andric       // TODO: See if we can do a better error than just "invalid ...".
2980b57cec5SDimitry Andric       if (Op.getStartLoc() != SMLoc()) {
2990b57cec5SDimitry Andric         ErrorLoc = Op.getStartLoc();
3000b57cec5SDimitry Andric       }
3010b57cec5SDimitry Andric     }
3020b57cec5SDimitry Andric   }
3030b57cec5SDimitry Andric 
3040b57cec5SDimitry Andric   if (!Diag) {
3050b57cec5SDimitry Andric     Diag = "invalid operand for instruction";
3060b57cec5SDimitry Andric   }
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric   return Error(ErrorLoc, Diag);
3090b57cec5SDimitry Andric }
3100b57cec5SDimitry Andric 
3110b57cec5SDimitry Andric bool AVRAsmParser::missingFeature(llvm::SMLoc const &Loc,
3120b57cec5SDimitry Andric                                   uint64_t const &ErrorInfo) {
3130b57cec5SDimitry Andric   return Error(Loc, "instruction requires a CPU feature not currently enabled");
3140b57cec5SDimitry Andric }
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric bool AVRAsmParser::emit(MCInst &Inst, SMLoc const &Loc, MCStreamer &Out) const {
3170b57cec5SDimitry Andric   Inst.setLoc(Loc);
3185ffd83dbSDimitry Andric   Out.emitInstruction(Inst, STI);
3190b57cec5SDimitry Andric 
3200b57cec5SDimitry Andric   return false;
3210b57cec5SDimitry Andric }
3220b57cec5SDimitry Andric 
3230b57cec5SDimitry Andric bool AVRAsmParser::MatchAndEmitInstruction(SMLoc Loc, unsigned &Opcode,
3240b57cec5SDimitry Andric                                            OperandVector &Operands,
3250b57cec5SDimitry Andric                                            MCStreamer &Out, uint64_t &ErrorInfo,
3260b57cec5SDimitry Andric                                            bool MatchingInlineAsm) {
3270b57cec5SDimitry Andric   MCInst Inst;
3280b57cec5SDimitry Andric   unsigned MatchResult =
3290b57cec5SDimitry Andric       MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3300b57cec5SDimitry Andric 
3310b57cec5SDimitry Andric   switch (MatchResult) {
332349cc55cSDimitry Andric   case Match_Success:
333349cc55cSDimitry Andric     return emit(Inst, Loc, Out);
334349cc55cSDimitry Andric   case Match_MissingFeature:
335349cc55cSDimitry Andric     return missingFeature(Loc, ErrorInfo);
336349cc55cSDimitry Andric   case Match_InvalidOperand:
337349cc55cSDimitry Andric     return invalidOperand(Loc, Operands, ErrorInfo);
338349cc55cSDimitry Andric   case Match_MnemonicFail:
339349cc55cSDimitry Andric     return Error(Loc, "invalid instruction");
34081ad6265SDimitry Andric   case Match_InvalidRegisterOnTiny:
34181ad6265SDimitry Andric     return Error(Loc, "invalid register on avrtiny");
342349cc55cSDimitry Andric   default:
343349cc55cSDimitry Andric     return true;
3440b57cec5SDimitry Andric   }
3450b57cec5SDimitry Andric }
3460b57cec5SDimitry Andric 
3470b57cec5SDimitry Andric /// Parses a register name using a given matching function.
3480b57cec5SDimitry Andric /// Checks for lowercase or uppercase if necessary.
3490fca6ea1SDimitry Andric int AVRAsmParser::parseRegisterName(MCRegister (*matchFn)(StringRef)) {
3500b57cec5SDimitry Andric   StringRef Name = Parser.getTok().getString();
3510b57cec5SDimitry Andric 
3520b57cec5SDimitry Andric   int RegNum = matchFn(Name);
3530b57cec5SDimitry Andric 
3540b57cec5SDimitry Andric   // GCC supports case insensitive register names. Some of the AVR registers
3550b57cec5SDimitry Andric   // are all lower case, some are all upper case but non are mixed. We prefer
3560b57cec5SDimitry Andric   // to use the original names in the register definitions. That is why we
3570b57cec5SDimitry Andric   // have to test both upper and lower case here.
3580b57cec5SDimitry Andric   if (RegNum == AVR::NoRegister) {
3590b57cec5SDimitry Andric     RegNum = matchFn(Name.lower());
3600b57cec5SDimitry Andric   }
3610b57cec5SDimitry Andric   if (RegNum == AVR::NoRegister) {
3620b57cec5SDimitry Andric     RegNum = matchFn(Name.upper());
3630b57cec5SDimitry Andric   }
3640b57cec5SDimitry Andric 
3650b57cec5SDimitry Andric   return RegNum;
3660b57cec5SDimitry Andric }
3670b57cec5SDimitry Andric 
3680b57cec5SDimitry Andric int AVRAsmParser::parseRegisterName() {
3690b57cec5SDimitry Andric   int RegNum = parseRegisterName(&MatchRegisterName);
3700b57cec5SDimitry Andric 
3710b57cec5SDimitry Andric   if (RegNum == AVR::NoRegister)
3720b57cec5SDimitry Andric     RegNum = parseRegisterName(&MatchRegisterAltName);
3730b57cec5SDimitry Andric 
3740b57cec5SDimitry Andric   return RegNum;
3750b57cec5SDimitry Andric }
3760b57cec5SDimitry Andric 
3775ffd83dbSDimitry Andric int AVRAsmParser::parseRegister(bool RestoreOnFailure) {
3780b57cec5SDimitry Andric   int RegNum = AVR::NoRegister;
3790b57cec5SDimitry Andric 
3800b57cec5SDimitry Andric   if (Parser.getTok().is(AsmToken::Identifier)) {
3810b57cec5SDimitry Andric     // Check for register pair syntax
3820b57cec5SDimitry Andric     if (Parser.getLexer().peekTok().is(AsmToken::Colon)) {
3835ffd83dbSDimitry Andric       AsmToken HighTok = Parser.getTok();
3840b57cec5SDimitry Andric       Parser.Lex();
3855ffd83dbSDimitry Andric       AsmToken ColonTok = Parser.getTok();
3860b57cec5SDimitry Andric       Parser.Lex(); // Eat high (odd) register and colon
3870b57cec5SDimitry Andric 
3880b57cec5SDimitry Andric       if (Parser.getTok().is(AsmToken::Identifier)) {
3890b57cec5SDimitry Andric         // Convert lower (even) register to DREG
3900b57cec5SDimitry Andric         RegNum = toDREG(parseRegisterName());
3910b57cec5SDimitry Andric       }
3925ffd83dbSDimitry Andric       if (RegNum == AVR::NoRegister && RestoreOnFailure) {
3935ffd83dbSDimitry Andric         getLexer().UnLex(std::move(ColonTok));
3945ffd83dbSDimitry Andric         getLexer().UnLex(std::move(HighTok));
3955ffd83dbSDimitry Andric       }
3960b57cec5SDimitry Andric     } else {
3970b57cec5SDimitry Andric       RegNum = parseRegisterName();
3980b57cec5SDimitry Andric     }
3990b57cec5SDimitry Andric   }
4000b57cec5SDimitry Andric   return RegNum;
4010b57cec5SDimitry Andric }
4020b57cec5SDimitry Andric 
4030b57cec5SDimitry Andric bool AVRAsmParser::tryParseRegisterOperand(OperandVector &Operands) {
4040b57cec5SDimitry Andric   int RegNo = parseRegister();
4050b57cec5SDimitry Andric 
4060b57cec5SDimitry Andric   if (RegNo == AVR::NoRegister)
4070b57cec5SDimitry Andric     return true;
4080b57cec5SDimitry Andric 
40981ad6265SDimitry Andric   // Reject R0~R15 on avrtiny.
41081ad6265SDimitry Andric   if (AVR::R0 <= RegNo && RegNo <= AVR::R15 &&
41181ad6265SDimitry Andric       STI.hasFeature(AVR::FeatureTinyEncoding))
41281ad6265SDimitry Andric     return Error(Parser.getTok().getLoc(), "invalid register on avrtiny");
41381ad6265SDimitry Andric 
4140b57cec5SDimitry Andric   AsmToken const &T = Parser.getTok();
4150b57cec5SDimitry Andric   Operands.push_back(AVROperand::CreateReg(RegNo, T.getLoc(), T.getEndLoc()));
4160b57cec5SDimitry Andric   Parser.Lex(); // Eat register token.
4170b57cec5SDimitry Andric 
4180b57cec5SDimitry Andric   return false;
4190b57cec5SDimitry Andric }
4200b57cec5SDimitry Andric 
421*6c4b055cSDimitry Andric bool AVRAsmParser::tryParseExpression(OperandVector &Operands, int64_t offset) {
4220b57cec5SDimitry Andric   SMLoc S = Parser.getTok().getLoc();
4230b57cec5SDimitry Andric 
4240b57cec5SDimitry Andric   if (!tryParseRelocExpression(Operands))
4250b57cec5SDimitry Andric     return false;
4260b57cec5SDimitry Andric 
4270b57cec5SDimitry Andric   if ((Parser.getTok().getKind() == AsmToken::Plus ||
4280b57cec5SDimitry Andric        Parser.getTok().getKind() == AsmToken::Minus) &&
4290b57cec5SDimitry Andric       Parser.getLexer().peekTok().getKind() == AsmToken::Identifier) {
4300b57cec5SDimitry Andric     // Don't handle this case - it should be split into two
4310b57cec5SDimitry Andric     // separate tokens.
4320b57cec5SDimitry Andric     return true;
4330b57cec5SDimitry Andric   }
4340b57cec5SDimitry Andric 
4350b57cec5SDimitry Andric   // Parse (potentially inner) expression
4360b57cec5SDimitry Andric   MCExpr const *Expression;
4370b57cec5SDimitry Andric   if (getParser().parseExpression(Expression))
4380b57cec5SDimitry Andric     return true;
4390b57cec5SDimitry Andric 
440*6c4b055cSDimitry Andric   if (offset) {
441*6c4b055cSDimitry Andric     Expression = MCBinaryExpr::createAdd(
442*6c4b055cSDimitry Andric         Expression, MCConstantExpr::create(offset, getContext()), getContext());
443*6c4b055cSDimitry Andric   }
444*6c4b055cSDimitry Andric 
4450b57cec5SDimitry Andric   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4460b57cec5SDimitry Andric   Operands.push_back(AVROperand::CreateImm(Expression, S, E));
4470b57cec5SDimitry Andric   return false;
4480b57cec5SDimitry Andric }
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric bool AVRAsmParser::tryParseRelocExpression(OperandVector &Operands) {
4510b57cec5SDimitry Andric   bool isNegated = false;
4520b57cec5SDimitry Andric   AVRMCExpr::VariantKind ModifierKind = AVRMCExpr::VK_AVR_None;
4530b57cec5SDimitry Andric 
4540b57cec5SDimitry Andric   SMLoc S = Parser.getTok().getLoc();
4550b57cec5SDimitry Andric 
456bdd1243dSDimitry Andric   // Reject the form in which sign comes first. This behaviour is
457bdd1243dSDimitry Andric   // in accordance with avr-gcc.
4580b57cec5SDimitry Andric   AsmToken::TokenKind CurTok = Parser.getLexer().getKind();
4590b57cec5SDimitry Andric   if (CurTok == AsmToken::Minus || CurTok == AsmToken::Plus)
460bdd1243dSDimitry Andric     return true;
461bdd1243dSDimitry Andric 
462bdd1243dSDimitry Andric   // Check for sign.
463bdd1243dSDimitry Andric   AsmToken tokens[2];
464bdd1243dSDimitry Andric   if (Parser.getLexer().peekTokens(tokens) == 2)
465bdd1243dSDimitry Andric     if (tokens[0].getKind() == AsmToken::LParen &&
466bdd1243dSDimitry Andric         tokens[1].getKind() == AsmToken::Minus)
467bdd1243dSDimitry Andric       isNegated = true;
4680b57cec5SDimitry Andric 
4690b57cec5SDimitry Andric   // Check if we have a target specific modifier (lo8, hi8, &c)
470bdd1243dSDimitry Andric   if (CurTok != AsmToken::Identifier ||
4710b57cec5SDimitry Andric       Parser.getLexer().peekTok().getKind() != AsmToken::LParen) {
4720b57cec5SDimitry Andric     // Not a reloc expr
4730b57cec5SDimitry Andric     return true;
4740b57cec5SDimitry Andric   }
4750b57cec5SDimitry Andric   StringRef ModifierName = Parser.getTok().getString();
476349cc55cSDimitry Andric   ModifierKind = AVRMCExpr::getKindByName(ModifierName);
4770b57cec5SDimitry Andric 
4780b57cec5SDimitry Andric   if (ModifierKind != AVRMCExpr::VK_AVR_None) {
4790b57cec5SDimitry Andric     Parser.Lex();
4800b57cec5SDimitry Andric     Parser.Lex(); // Eat modifier name and parenthesis
4810b57cec5SDimitry Andric     if (Parser.getTok().getString() == GENERATE_STUBS &&
4820b57cec5SDimitry Andric         Parser.getTok().getKind() == AsmToken::Identifier) {
4830b57cec5SDimitry Andric       std::string GSModName = ModifierName.str() + "_" + GENERATE_STUBS;
484349cc55cSDimitry Andric       ModifierKind = AVRMCExpr::getKindByName(GSModName);
4850b57cec5SDimitry Andric       if (ModifierKind != AVRMCExpr::VK_AVR_None)
4860b57cec5SDimitry Andric         Parser.Lex(); // Eat gs modifier name
4870b57cec5SDimitry Andric     }
4880b57cec5SDimitry Andric   } else {
4890b57cec5SDimitry Andric     return Error(Parser.getTok().getLoc(), "unknown modifier");
4900b57cec5SDimitry Andric   }
4910b57cec5SDimitry Andric 
4920b57cec5SDimitry Andric   if (tokens[1].getKind() == AsmToken::Minus ||
4930b57cec5SDimitry Andric       tokens[1].getKind() == AsmToken::Plus) {
4940b57cec5SDimitry Andric     Parser.Lex();
4950b57cec5SDimitry Andric     assert(Parser.getTok().getKind() == AsmToken::LParen);
4960b57cec5SDimitry Andric     Parser.Lex(); // Eat the sign and parenthesis
4970b57cec5SDimitry Andric   }
4980b57cec5SDimitry Andric 
4990b57cec5SDimitry Andric   MCExpr const *InnerExpression;
5000b57cec5SDimitry Andric   if (getParser().parseExpression(InnerExpression))
5010b57cec5SDimitry Andric     return true;
5020b57cec5SDimitry Andric 
5030b57cec5SDimitry Andric   if (tokens[1].getKind() == AsmToken::Minus ||
5040b57cec5SDimitry Andric       tokens[1].getKind() == AsmToken::Plus) {
5050b57cec5SDimitry Andric     assert(Parser.getTok().getKind() == AsmToken::RParen);
5060b57cec5SDimitry Andric     Parser.Lex(); // Eat closing parenthesis
5070b57cec5SDimitry Andric   }
5080b57cec5SDimitry Andric 
5090b57cec5SDimitry Andric   // If we have a modifier wrap the inner expression
5100b57cec5SDimitry Andric   assert(Parser.getTok().getKind() == AsmToken::RParen);
5110b57cec5SDimitry Andric   Parser.Lex(); // Eat closing parenthesis
5120b57cec5SDimitry Andric 
513349cc55cSDimitry Andric   MCExpr const *Expression =
514349cc55cSDimitry Andric       AVRMCExpr::create(ModifierKind, InnerExpression, isNegated, getContext());
5150b57cec5SDimitry Andric 
5160b57cec5SDimitry Andric   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5170b57cec5SDimitry Andric   Operands.push_back(AVROperand::CreateImm(Expression, S, E));
5180b57cec5SDimitry Andric 
5190b57cec5SDimitry Andric   return false;
5200b57cec5SDimitry Andric }
5210b57cec5SDimitry Andric 
522bdd1243dSDimitry Andric bool AVRAsmParser::parseOperand(OperandVector &Operands, bool maybeReg) {
5230b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "parseOperand\n");
5240b57cec5SDimitry Andric 
5250b57cec5SDimitry Andric   switch (getLexer().getKind()) {
5260b57cec5SDimitry Andric   default:
5270b57cec5SDimitry Andric     return Error(Parser.getTok().getLoc(), "unexpected token in operand");
5280b57cec5SDimitry Andric 
5290b57cec5SDimitry Andric   case AsmToken::Identifier:
530bdd1243dSDimitry Andric     // Try to parse a register, fall through to the next case if it fails.
531bdd1243dSDimitry Andric     if (maybeReg && !tryParseRegisterOperand(Operands)) {
5320b57cec5SDimitry Andric       return false;
5330b57cec5SDimitry Andric     }
534bdd1243dSDimitry Andric     [[fallthrough]];
5350b57cec5SDimitry Andric   case AsmToken::LParen:
5360b57cec5SDimitry Andric   case AsmToken::Integer:
537*6c4b055cSDimitry Andric     return tryParseExpression(Operands, 0);
5380b57cec5SDimitry Andric   case AsmToken::Dot:
539*6c4b055cSDimitry Andric     return tryParseExpression(Operands, 2);
5400b57cec5SDimitry Andric   case AsmToken::Plus:
5410b57cec5SDimitry Andric   case AsmToken::Minus: {
5420b57cec5SDimitry Andric     // If the sign preceeds a number, parse the number,
5430b57cec5SDimitry Andric     // otherwise treat the sign a an independent token.
5440b57cec5SDimitry Andric     switch (getLexer().peekTok().getKind()) {
5450b57cec5SDimitry Andric     case AsmToken::Integer:
5460b57cec5SDimitry Andric     case AsmToken::BigNum:
5470b57cec5SDimitry Andric     case AsmToken::Identifier:
5480b57cec5SDimitry Andric     case AsmToken::Real:
549*6c4b055cSDimitry Andric       if (!tryParseExpression(Operands, 0))
5500b57cec5SDimitry Andric         return false;
5510b57cec5SDimitry Andric       break;
5520b57cec5SDimitry Andric     default:
5530b57cec5SDimitry Andric       break;
5540b57cec5SDimitry Andric     }
5550b57cec5SDimitry Andric     // Treat the token as an independent token.
5560b57cec5SDimitry Andric     Operands.push_back(AVROperand::CreateToken(Parser.getTok().getString(),
5570b57cec5SDimitry Andric                                                Parser.getTok().getLoc()));
5580b57cec5SDimitry Andric     Parser.Lex(); // Eat the token.
5590b57cec5SDimitry Andric     return false;
5600b57cec5SDimitry Andric   }
5610b57cec5SDimitry Andric   }
5620b57cec5SDimitry Andric 
5630b57cec5SDimitry Andric   // Could not parse operand
5640b57cec5SDimitry Andric   return true;
5650b57cec5SDimitry Andric }
5660b57cec5SDimitry Andric 
5675f757f3fSDimitry Andric ParseStatus AVRAsmParser::parseMemriOperand(OperandVector &Operands) {
5680b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "parseMemriOperand()\n");
5690b57cec5SDimitry Andric 
5700b57cec5SDimitry Andric   SMLoc E, S;
5710b57cec5SDimitry Andric   MCExpr const *Expression;
5720b57cec5SDimitry Andric   int RegNo;
5730b57cec5SDimitry Andric 
5740b57cec5SDimitry Andric   // Parse register.
5750b57cec5SDimitry Andric   {
5760b57cec5SDimitry Andric     RegNo = parseRegister();
5770b57cec5SDimitry Andric 
5780b57cec5SDimitry Andric     if (RegNo == AVR::NoRegister)
5795f757f3fSDimitry Andric       return ParseStatus::Failure;
5800b57cec5SDimitry Andric 
5810b57cec5SDimitry Andric     S = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5820b57cec5SDimitry Andric     Parser.Lex(); // Eat register token.
5830b57cec5SDimitry Andric   }
5840b57cec5SDimitry Andric 
5850b57cec5SDimitry Andric   // Parse immediate;
5860b57cec5SDimitry Andric   {
5870b57cec5SDimitry Andric     if (getParser().parseExpression(Expression))
5885f757f3fSDimitry Andric       return ParseStatus::Failure;
5890b57cec5SDimitry Andric 
5900b57cec5SDimitry Andric     E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5910b57cec5SDimitry Andric   }
5920b57cec5SDimitry Andric 
5930b57cec5SDimitry Andric   Operands.push_back(AVROperand::CreateMemri(RegNo, Expression, S, E));
5940b57cec5SDimitry Andric 
5955f757f3fSDimitry Andric   return ParseStatus::Success;
5960b57cec5SDimitry Andric }
5970b57cec5SDimitry Andric 
5985f757f3fSDimitry Andric bool AVRAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
5990b57cec5SDimitry Andric                                  SMLoc &EndLoc) {
6000b57cec5SDimitry Andric   StartLoc = Parser.getTok().getLoc();
6015f757f3fSDimitry Andric   Reg = parseRegister(/*RestoreOnFailure=*/false);
6020b57cec5SDimitry Andric   EndLoc = Parser.getTok().getLoc();
6030b57cec5SDimitry Andric 
6045f757f3fSDimitry Andric   return Reg == AVR::NoRegister;
6050b57cec5SDimitry Andric }
6060b57cec5SDimitry Andric 
6075f757f3fSDimitry Andric ParseStatus AVRAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
6085ffd83dbSDimitry Andric                                            SMLoc &EndLoc) {
6095ffd83dbSDimitry Andric   StartLoc = Parser.getTok().getLoc();
6105f757f3fSDimitry Andric   Reg = parseRegister(/*RestoreOnFailure=*/true);
6115ffd83dbSDimitry Andric   EndLoc = Parser.getTok().getLoc();
6125ffd83dbSDimitry Andric 
6135f757f3fSDimitry Andric   if (Reg == AVR::NoRegister)
6145f757f3fSDimitry Andric     return ParseStatus::NoMatch;
6155f757f3fSDimitry Andric   return ParseStatus::Success;
6165ffd83dbSDimitry Andric }
6175ffd83dbSDimitry Andric 
6180b57cec5SDimitry Andric void AVRAsmParser::eatComma() {
6190b57cec5SDimitry Andric   if (getLexer().is(AsmToken::Comma)) {
6200b57cec5SDimitry Andric     Parser.Lex();
6210b57cec5SDimitry Andric   } else {
6220b57cec5SDimitry Andric     // GCC allows commas to be omitted.
6230b57cec5SDimitry Andric   }
6240b57cec5SDimitry Andric }
6250b57cec5SDimitry Andric 
6260b57cec5SDimitry Andric bool AVRAsmParser::ParseInstruction(ParseInstructionInfo &Info,
6270b57cec5SDimitry Andric                                     StringRef Mnemonic, SMLoc NameLoc,
6280b57cec5SDimitry Andric                                     OperandVector &Operands) {
6290b57cec5SDimitry Andric   Operands.push_back(AVROperand::CreateToken(Mnemonic, NameLoc));
6300b57cec5SDimitry Andric 
631bdd1243dSDimitry Andric   int OperandNum = -1;
6320b57cec5SDimitry Andric   while (getLexer().isNot(AsmToken::EndOfStatement)) {
633bdd1243dSDimitry Andric     OperandNum++;
634bdd1243dSDimitry Andric     if (OperandNum > 0)
635349cc55cSDimitry Andric       eatComma();
6360b57cec5SDimitry Andric 
6375f757f3fSDimitry Andric     ParseStatus ParseRes = MatchOperandParserImpl(Operands, Mnemonic);
6380b57cec5SDimitry Andric 
6395f757f3fSDimitry Andric     if (ParseRes.isSuccess())
6400b57cec5SDimitry Andric       continue;
6410b57cec5SDimitry Andric 
6425f757f3fSDimitry Andric     if (ParseRes.isFailure()) {
6430b57cec5SDimitry Andric       SMLoc Loc = getLexer().getLoc();
6440b57cec5SDimitry Andric       Parser.eatToEndOfStatement();
6450b57cec5SDimitry Andric 
6460b57cec5SDimitry Andric       return Error(Loc, "failed to parse register and immediate pair");
6470b57cec5SDimitry Andric     }
6480b57cec5SDimitry Andric 
649bdd1243dSDimitry Andric     // These specific operands should be treated as addresses/symbols/labels,
650bdd1243dSDimitry Andric     // other than registers.
651bdd1243dSDimitry Andric     bool maybeReg = true;
652*6c4b055cSDimitry Andric 
653bdd1243dSDimitry Andric     if (OperandNum == 1) {
654bdd1243dSDimitry Andric       std::array<StringRef, 8> Insts = {"lds", "adiw", "sbiw", "ldi"};
655bdd1243dSDimitry Andric       for (auto Inst : Insts) {
656bdd1243dSDimitry Andric         if (Inst == Mnemonic) {
657bdd1243dSDimitry Andric           maybeReg = false;
658bdd1243dSDimitry Andric           break;
659bdd1243dSDimitry Andric         }
660bdd1243dSDimitry Andric       }
661bdd1243dSDimitry Andric     } else if (OperandNum == 0) {
662bdd1243dSDimitry Andric       std::array<StringRef, 8> Insts = {"sts", "call", "rcall", "rjmp", "jmp"};
663bdd1243dSDimitry Andric       for (auto Inst : Insts) {
664bdd1243dSDimitry Andric         if (Inst == Mnemonic) {
665bdd1243dSDimitry Andric           maybeReg = false;
666bdd1243dSDimitry Andric           break;
667bdd1243dSDimitry Andric         }
668bdd1243dSDimitry Andric       }
669bdd1243dSDimitry Andric     }
670bdd1243dSDimitry Andric 
671bdd1243dSDimitry Andric     if (parseOperand(Operands, maybeReg)) {
6720b57cec5SDimitry Andric       SMLoc Loc = getLexer().getLoc();
6730b57cec5SDimitry Andric       Parser.eatToEndOfStatement();
6740b57cec5SDimitry Andric       return Error(Loc, "unexpected token in argument list");
6750b57cec5SDimitry Andric     }
6760b57cec5SDimitry Andric   }
6770b57cec5SDimitry Andric   Parser.Lex(); // Consume the EndOfStatement
6780b57cec5SDimitry Andric   return false;
6790b57cec5SDimitry Andric }
6800b57cec5SDimitry Andric 
68106c3fb27SDimitry Andric ParseStatus AVRAsmParser::parseDirective(llvm::AsmToken DirectiveID) {
6820b57cec5SDimitry Andric   StringRef IDVal = DirectiveID.getIdentifier();
68306c3fb27SDimitry Andric   if (IDVal.lower() == ".long")
68406c3fb27SDimitry Andric     return parseLiteralValues(SIZE_LONG, DirectiveID.getLoc());
68506c3fb27SDimitry Andric   if (IDVal.lower() == ".word" || IDVal.lower() == ".short")
68606c3fb27SDimitry Andric     return parseLiteralValues(SIZE_WORD, DirectiveID.getLoc());
68706c3fb27SDimitry Andric   if (IDVal.lower() == ".byte")
68806c3fb27SDimitry Andric     return parseLiteralValues(1, DirectiveID.getLoc());
68906c3fb27SDimitry Andric   return ParseStatus::NoMatch;
6900b57cec5SDimitry Andric }
6910b57cec5SDimitry Andric 
69206c3fb27SDimitry Andric ParseStatus AVRAsmParser::parseLiteralValues(unsigned SizeInBytes, SMLoc L) {
6930b57cec5SDimitry Andric   MCAsmParser &Parser = getParser();
6940b57cec5SDimitry Andric   AVRMCELFStreamer &AVRStreamer =
6950b57cec5SDimitry Andric       static_cast<AVRMCELFStreamer &>(Parser.getStreamer());
6960b57cec5SDimitry Andric   AsmToken Tokens[2];
6970b57cec5SDimitry Andric   size_t ReadCount = Parser.getLexer().peekTokens(Tokens);
6980b57cec5SDimitry Andric   if (ReadCount == 2 && Parser.getTok().getKind() == AsmToken::Identifier &&
6990b57cec5SDimitry Andric       Tokens[0].getKind() == AsmToken::Minus &&
7000b57cec5SDimitry Andric       Tokens[1].getKind() == AsmToken::Identifier) {
7010b57cec5SDimitry Andric     MCSymbol *Symbol = getContext().getOrCreateSymbol(".text");
7025ffd83dbSDimitry Andric     AVRStreamer.emitValueForModiferKind(Symbol, SizeInBytes, L,
7030b57cec5SDimitry Andric                                         AVRMCExpr::VK_AVR_None);
70406c3fb27SDimitry Andric     return ParseStatus::NoMatch;
7050b57cec5SDimitry Andric   }
7060b57cec5SDimitry Andric 
7070b57cec5SDimitry Andric   if (Parser.getTok().getKind() == AsmToken::Identifier &&
7080b57cec5SDimitry Andric       Parser.getLexer().peekTok().getKind() == AsmToken::LParen) {
7090b57cec5SDimitry Andric     StringRef ModifierName = Parser.getTok().getString();
7100b57cec5SDimitry Andric     AVRMCExpr::VariantKind ModifierKind =
711349cc55cSDimitry Andric         AVRMCExpr::getKindByName(ModifierName);
7120b57cec5SDimitry Andric     if (ModifierKind != AVRMCExpr::VK_AVR_None) {
7130b57cec5SDimitry Andric       Parser.Lex();
7140b57cec5SDimitry Andric       Parser.Lex(); // Eat the modifier and parenthesis
7150b57cec5SDimitry Andric     } else {
7160b57cec5SDimitry Andric       return Error(Parser.getTok().getLoc(), "unknown modifier");
7170b57cec5SDimitry Andric     }
7180b57cec5SDimitry Andric     MCSymbol *Symbol =
7190b57cec5SDimitry Andric         getContext().getOrCreateSymbol(Parser.getTok().getString());
7205ffd83dbSDimitry Andric     AVRStreamer.emitValueForModiferKind(Symbol, SizeInBytes, L, ModifierKind);
72106c3fb27SDimitry Andric     Lex(); // Eat the symbol name.
72206c3fb27SDimitry Andric     if (parseToken(AsmToken::RParen))
72306c3fb27SDimitry Andric       return ParseStatus::Failure;
72406c3fb27SDimitry Andric     return parseEOL();
7250b57cec5SDimitry Andric   }
7260b57cec5SDimitry Andric 
7270b57cec5SDimitry Andric   auto parseOne = [&]() -> bool {
7280b57cec5SDimitry Andric     const MCExpr *Value;
7290b57cec5SDimitry Andric     if (Parser.parseExpression(Value))
7300b57cec5SDimitry Andric       return true;
7315ffd83dbSDimitry Andric     Parser.getStreamer().emitValue(Value, SizeInBytes, L);
7320b57cec5SDimitry Andric     return false;
7330b57cec5SDimitry Andric   };
7340b57cec5SDimitry Andric   return (parseMany(parseOne));
7350b57cec5SDimitry Andric }
7360b57cec5SDimitry Andric 
737480093f4SDimitry Andric extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAVRAsmParser() {
7380b57cec5SDimitry Andric   RegisterMCAsmParser<AVRAsmParser> X(getTheAVRTarget());
7390b57cec5SDimitry Andric }
7400b57cec5SDimitry Andric 
7410b57cec5SDimitry Andric #define GET_REGISTER_MATCHER
7420b57cec5SDimitry Andric #define GET_MATCHER_IMPLEMENTATION
7430b57cec5SDimitry Andric #include "AVRGenAsmMatcher.inc"
7440b57cec5SDimitry Andric 
7450b57cec5SDimitry Andric // Uses enums defined in AVRGenAsmMatcher.inc
7460b57cec5SDimitry Andric unsigned AVRAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp,
7470b57cec5SDimitry Andric                                                   unsigned ExpectedKind) {
7480b57cec5SDimitry Andric   AVROperand &Op = static_cast<AVROperand &>(AsmOp);
7490b57cec5SDimitry Andric   MatchClassKind Expected = static_cast<MatchClassKind>(ExpectedKind);
7500b57cec5SDimitry Andric 
7510b57cec5SDimitry Andric   // If need be, GCC converts bare numbers to register names
7520b57cec5SDimitry Andric   // It's ugly, but GCC supports it.
7530b57cec5SDimitry Andric   if (Op.isImm()) {
7540b57cec5SDimitry Andric     if (MCConstantExpr const *Const = dyn_cast<MCConstantExpr>(Op.getImm())) {
7550b57cec5SDimitry Andric       int64_t RegNum = Const->getValue();
75681ad6265SDimitry Andric 
75781ad6265SDimitry Andric       // Reject R0~R15 on avrtiny.
75881ad6265SDimitry Andric       if (0 <= RegNum && RegNum <= 15 &&
75981ad6265SDimitry Andric           STI.hasFeature(AVR::FeatureTinyEncoding))
76081ad6265SDimitry Andric         return Match_InvalidRegisterOnTiny;
76181ad6265SDimitry Andric 
7620b57cec5SDimitry Andric       std::ostringstream RegName;
7630b57cec5SDimitry Andric       RegName << "r" << RegNum;
764349cc55cSDimitry Andric       RegNum = MatchRegisterName(RegName.str());
7650b57cec5SDimitry Andric       if (RegNum != AVR::NoRegister) {
7660b57cec5SDimitry Andric         Op.makeReg(RegNum);
7670b57cec5SDimitry Andric         if (validateOperandClass(Op, Expected) == Match_Success) {
7680b57cec5SDimitry Andric           return Match_Success;
7690b57cec5SDimitry Andric         }
7700b57cec5SDimitry Andric       }
7710b57cec5SDimitry Andric       // Let the other quirks try their magic.
7720b57cec5SDimitry Andric     }
7730b57cec5SDimitry Andric   }
7740b57cec5SDimitry Andric 
7750b57cec5SDimitry Andric   if (Op.isReg()) {
7760b57cec5SDimitry Andric     // If the instruction uses a register pair but we got a single, lower
7770b57cec5SDimitry Andric     // register we perform a "class cast".
7780b57cec5SDimitry Andric     if (isSubclass(Expected, MCK_DREGS)) {
7790b57cec5SDimitry Andric       unsigned correspondingDREG = toDREG(Op.getReg());
7800b57cec5SDimitry Andric 
7810b57cec5SDimitry Andric       if (correspondingDREG != AVR::NoRegister) {
7820b57cec5SDimitry Andric         Op.makeReg(correspondingDREG);
7830b57cec5SDimitry Andric         return validateOperandClass(Op, Expected);
7840b57cec5SDimitry Andric       }
7850b57cec5SDimitry Andric     }
7860b57cec5SDimitry Andric   }
7870b57cec5SDimitry Andric   return Match_InvalidOperand;
7880b57cec5SDimitry Andric }
789