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