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