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