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