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