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