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
37using namespace llvm;
38
39namespace {
40/// Parses AVR assembly from a stream.
41class 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
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
90public:
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
100  MCAsmParser &getParser() const { return Parser; }
101  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
102};
103
104/// An parsed AVR assembly operand.
105class AVROperand : public MCParsedAsmOperand {
106  typedef MCParsedAsmOperand Base;
107  enum KindTy { k_Immediate, k_Register, k_Token, k_Memri } Kind;
108
109public:
110  AVROperand(StringRef Tok, SMLoc const &S)
111      : Base(), Kind(k_Token), Tok(Tok), Start(S), End(S) {}
112  AVROperand(unsigned Reg, SMLoc const &S, SMLoc const &E)
113      : Base(), Kind(k_Register), RegImm({Reg, nullptr}), Start(S), End(E) {}
114  AVROperand(MCExpr const *Imm, SMLoc const &S, SMLoc const &E)
115      : Base(), Kind(k_Immediate), RegImm({0, Imm}), Start(S), End(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
130public:
131  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
138  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
148  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.
157  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
165  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
173  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
181  bool isReg() const override { return Kind == k_Register; }
182  bool isImm() const override { return Kind == k_Immediate; }
183  bool isToken() const override { return Kind == k_Token; }
184  bool isMem() const override { return Kind == k_Memri; }
185  bool isMemri() const { return Kind == k_Memri; }
186
187  StringRef getToken() const {
188    assert(Kind == k_Token && "Invalid access!");
189    return Tok;
190  }
191
192  unsigned getReg() const override {
193    assert((Kind == k_Register || Kind == k_Memri) && "Invalid access!");
194
195    return RegImm.Reg;
196  }
197
198  const MCExpr *getImm() const {
199    assert((Kind == k_Immediate || Kind == k_Memri) && "Invalid access!");
200    return RegImm.Imm;
201  }
202
203  static std::unique_ptr<AVROperand> CreateToken(StringRef Str, SMLoc S) {
204    return std::make_unique<AVROperand>(Str, S);
205  }
206
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
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>
218  CreateMemri(unsigned RegNum, const MCExpr *Val, SMLoc S, SMLoc E) {
219    return std::make_unique<AVROperand>(RegNum, Val, S, E);
220  }
221
222  void makeToken(StringRef Token) {
223    Kind = k_Token;
224    Tok = Token;
225  }
226
227  void makeReg(unsigned RegNo) {
228    Kind = k_Register;
229    RegImm = {RegNo, nullptr};
230  }
231
232  void makeImm(MCExpr const *Ex) {
233    Kind = k_Immediate;
234    RegImm = {0, Ex};
235  }
236
237  void makeMemri(unsigned RegNo, MCExpr const *Imm) {
238    Kind = k_Memri;
239    RegImm = {RegNo, Imm};
240  }
241
242  SMLoc getStartLoc() const override { return Start; }
243  SMLoc getEndLoc() const override { return End; }
244
245  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.
273static unsigned MatchRegisterName(StringRef Name);
274
275/// Maps from the set of all alternative registernames to a register number.
276/// \note Generated by TableGen.
277static unsigned MatchRegisterAltName(StringRef Name);
278
279bool 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
305bool 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
310bool 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
317bool 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.
336int 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
355int AVRAsmParser::parseRegisterName() {
356  int RegNum = parseRegisterName(&MatchRegisterName);
357
358  if (RegNum == AVR::NoRegister)
359    RegNum = parseRegisterName(&MatchRegisterAltName);
360
361  return RegNum;
362}
363
364int 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
390bool 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
403bool 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
427bool 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
511bool 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
556OperandMatchResultTy
557AVRAsmParser::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
588bool 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
597OperandMatchResultTy 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
609void AVRAsmParser::eatComma() {
610  if (getLexer().is(AsmToken::Comma)) {
611    Parser.Lex();
612  } else {
613    // GCC allows commas to be omitted.
614  }
615}
616
617bool 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
651bool 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
663bool 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
705extern "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
714unsigned 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