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