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