1 //===-- RISCVAsmParser.cpp - Parse RISCV assembly to MCInst instructions --===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "MCTargetDesc/RISCVBaseInfo.h" 11 #include "MCTargetDesc/RISCVMCExpr.h" 12 #include "MCTargetDesc/RISCVMCTargetDesc.h" 13 #include "llvm/ADT/STLExtras.h" 14 #include "llvm/ADT/StringSwitch.h" 15 #include "llvm/MC/MCContext.h" 16 #include "llvm/MC/MCExpr.h" 17 #include "llvm/MC/MCInst.h" 18 #include "llvm/MC/MCParser/MCAsmLexer.h" 19 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 20 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 21 #include "llvm/MC/MCRegisterInfo.h" 22 #include "llvm/MC/MCStreamer.h" 23 #include "llvm/MC/MCSubtargetInfo.h" 24 #include "llvm/Support/Casting.h" 25 #include "llvm/Support/TargetRegistry.h" 26 27 using namespace llvm; 28 29 namespace { 30 struct RISCVOperand; 31 32 class RISCVAsmParser : public MCTargetAsmParser { 33 SMLoc getLoc() const { return getParser().getTok().getLoc(); } 34 35 bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo, 36 int Lower, int Upper, Twine Msg); 37 38 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 39 OperandVector &Operands, MCStreamer &Out, 40 uint64_t &ErrorInfo, 41 bool MatchingInlineAsm) override; 42 43 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 44 45 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 46 SMLoc NameLoc, OperandVector &Operands) override; 47 48 bool ParseDirective(AsmToken DirectiveID) override; 49 50 // Auto-generated instruction matching functions 51 #define GET_ASSEMBLER_HEADER 52 #include "RISCVGenAsmMatcher.inc" 53 54 OperandMatchResultTy parseImmediate(OperandVector &Operands); 55 OperandMatchResultTy parseRegister(OperandVector &Operands, 56 bool AllowParens = false); 57 OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands); 58 OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands); 59 60 bool parseOperand(OperandVector &Operands); 61 62 public: 63 enum RISCVMatchResultTy { 64 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY, 65 #define GET_OPERAND_DIAGNOSTIC_TYPES 66 #include "RISCVGenAsmMatcher.inc" 67 #undef GET_OPERAND_DIAGNOSTIC_TYPES 68 }; 69 70 static bool classifySymbolRef(const MCExpr *Expr, 71 RISCVMCExpr::VariantKind &Kind, 72 int64_t &Addend); 73 74 RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, 75 const MCInstrInfo &MII, const MCTargetOptions &Options) 76 : MCTargetAsmParser(Options, STI, MII) { 77 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 78 } 79 }; 80 81 /// RISCVOperand - Instances of this class represent a parsed machine 82 /// instruction 83 struct RISCVOperand : public MCParsedAsmOperand { 84 85 enum KindTy { 86 Token, 87 Register, 88 Immediate, 89 } Kind; 90 91 struct RegOp { 92 unsigned RegNum; 93 }; 94 95 struct ImmOp { 96 const MCExpr *Val; 97 }; 98 99 SMLoc StartLoc, EndLoc; 100 union { 101 StringRef Tok; 102 RegOp Reg; 103 ImmOp Imm; 104 }; 105 106 RISCVOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 107 108 public: 109 RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() { 110 Kind = o.Kind; 111 StartLoc = o.StartLoc; 112 EndLoc = o.EndLoc; 113 switch (Kind) { 114 case Register: 115 Reg = o.Reg; 116 break; 117 case Immediate: 118 Imm = o.Imm; 119 break; 120 case Token: 121 Tok = o.Tok; 122 break; 123 } 124 } 125 126 bool isToken() const override { return Kind == Token; } 127 bool isReg() const override { return Kind == Register; } 128 bool isImm() const override { return Kind == Immediate; } 129 bool isMem() const override { return false; } 130 131 bool evaluateConstantImm(int64_t &Imm, RISCVMCExpr::VariantKind &VK) const { 132 const MCExpr *Val = getImm(); 133 bool Ret = false; 134 if (auto *RE = dyn_cast<RISCVMCExpr>(Val)) { 135 Ret = RE->evaluateAsConstant(Imm); 136 VK = RE->getKind(); 137 } else if (auto CE = dyn_cast<MCConstantExpr>(Val)) { 138 Ret = true; 139 VK = RISCVMCExpr::VK_RISCV_None; 140 Imm = CE->getValue(); 141 } 142 return Ret; 143 } 144 145 // True if operand is a symbol with no modifiers, or a constant with no 146 // modifiers and isShiftedInt<N-1, 1>(Op). 147 template <int N> bool isBareSimmNLsb0() const { 148 int64_t Imm; 149 RISCVMCExpr::VariantKind VK; 150 if (!isImm()) 151 return false; 152 bool IsConstantImm = evaluateConstantImm(Imm, VK); 153 bool IsValid; 154 if (!IsConstantImm) 155 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 156 else 157 IsValid = isShiftedInt<N - 1, 1>(Imm); 158 return IsValid && VK == RISCVMCExpr::VK_RISCV_None; 159 } 160 161 // Predicate methods for AsmOperands defined in RISCVInstrInfo.td 162 163 /// Return true if the operand is a valid for the fence instruction e.g. 164 /// ('iorw'). 165 bool isFenceArg() const { 166 if (!isImm()) 167 return false; 168 const MCExpr *Val = getImm(); 169 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val); 170 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None) 171 return false; 172 173 StringRef Str = SVal->getSymbol().getName(); 174 // Letters must be unique, taken from 'iorw', and in ascending order. This 175 // holds as long as each individual character is one of 'iorw' and is 176 // greater than the previous character. 177 char Prev = '\0'; 178 for (char c : Str) { 179 if (c != 'i' && c != 'o' && c != 'r' && c != 'w') 180 return false; 181 if (c <= Prev) 182 return false; 183 Prev = c; 184 } 185 return true; 186 } 187 188 bool isUImm5() const { 189 int64_t Imm; 190 RISCVMCExpr::VariantKind VK; 191 if (!isImm()) 192 return false; 193 bool IsConstantImm = evaluateConstantImm(Imm, VK); 194 return IsConstantImm && isUInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; 195 } 196 197 bool isSImm12() const { 198 RISCVMCExpr::VariantKind VK; 199 int64_t Imm; 200 bool IsValid; 201 if (!isImm()) 202 return false; 203 bool IsConstantImm = evaluateConstantImm(Imm, VK); 204 if (!IsConstantImm) 205 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 206 else 207 IsValid = isInt<12>(Imm); 208 return IsValid && 209 (VK == RISCVMCExpr::VK_RISCV_None || VK == RISCVMCExpr::VK_RISCV_LO); 210 } 211 212 bool isUImm12() const { 213 int64_t Imm; 214 RISCVMCExpr::VariantKind VK; 215 if (!isImm()) 216 return false; 217 bool IsConstantImm = evaluateConstantImm(Imm, VK); 218 return IsConstantImm && isUInt<12>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; 219 } 220 221 bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); } 222 223 bool isUImm20() const { 224 RISCVMCExpr::VariantKind VK; 225 int64_t Imm; 226 bool IsValid; 227 if (!isImm()) 228 return false; 229 bool IsConstantImm = evaluateConstantImm(Imm, VK); 230 if (!IsConstantImm) 231 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 232 else 233 IsValid = isUInt<20>(Imm); 234 return IsValid && (VK == RISCVMCExpr::VK_RISCV_None || 235 VK == RISCVMCExpr::VK_RISCV_HI || 236 VK == RISCVMCExpr::VK_RISCV_PCREL_HI); 237 } 238 239 bool isSImm21Lsb0() const { return isBareSimmNLsb0<21>(); } 240 241 /// getStartLoc - Gets location of the first token of this operand 242 SMLoc getStartLoc() const override { return StartLoc; } 243 /// getEndLoc - Gets location of the last token of this operand 244 SMLoc getEndLoc() const override { return EndLoc; } 245 246 unsigned getReg() const override { 247 assert(Kind == Register && "Invalid type access!"); 248 return Reg.RegNum; 249 } 250 251 const MCExpr *getImm() const { 252 assert(Kind == Immediate && "Invalid type access!"); 253 return Imm.Val; 254 } 255 256 StringRef getToken() const { 257 assert(Kind == Token && "Invalid type access!"); 258 return Tok; 259 } 260 261 void print(raw_ostream &OS) const override { 262 switch (Kind) { 263 case Immediate: 264 OS << *getImm(); 265 break; 266 case Register: 267 OS << "<register x"; 268 OS << getReg() << ">"; 269 break; 270 case Token: 271 OS << "'" << getToken() << "'"; 272 break; 273 } 274 } 275 276 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) { 277 auto Op = make_unique<RISCVOperand>(Token); 278 Op->Tok = Str; 279 Op->StartLoc = S; 280 Op->EndLoc = S; 281 return Op; 282 } 283 284 static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S, 285 SMLoc E) { 286 auto Op = make_unique<RISCVOperand>(Register); 287 Op->Reg.RegNum = RegNo; 288 Op->StartLoc = S; 289 Op->EndLoc = E; 290 return Op; 291 } 292 293 static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S, 294 SMLoc E) { 295 auto Op = make_unique<RISCVOperand>(Immediate); 296 Op->Imm.Val = Val; 297 Op->StartLoc = S; 298 Op->EndLoc = E; 299 return Op; 300 } 301 302 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 303 assert(Expr && "Expr shouldn't be null!"); 304 int64_t Imm = 0; 305 bool IsConstant = false; 306 if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) { 307 IsConstant = RE->evaluateAsConstant(Imm); 308 } else if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) { 309 IsConstant = true; 310 Imm = CE->getValue(); 311 } 312 313 if (IsConstant) 314 Inst.addOperand(MCOperand::createImm(Imm)); 315 else 316 Inst.addOperand(MCOperand::createExpr(Expr)); 317 } 318 319 // Used by the TableGen Code 320 void addRegOperands(MCInst &Inst, unsigned N) const { 321 assert(N == 1 && "Invalid number of operands!"); 322 Inst.addOperand(MCOperand::createReg(getReg())); 323 } 324 325 void addImmOperands(MCInst &Inst, unsigned N) const { 326 assert(N == 1 && "Invalid number of operands!"); 327 addExpr(Inst, getImm()); 328 } 329 330 void addFenceArgOperands(MCInst &Inst, unsigned N) const { 331 assert(N == 1 && "Invalid number of operands!"); 332 // isFenceArg has validated the operand, meaning this cast is safe 333 auto SE = cast<MCSymbolRefExpr>(getImm()); 334 335 unsigned Imm = 0; 336 for (char c : SE->getSymbol().getName()) { 337 switch (c) { 338 default: llvm_unreachable("FenceArg must contain only [iorw]"); 339 case 'i': Imm |= RISCVFenceField::I; break; 340 case 'o': Imm |= RISCVFenceField::O; break; 341 case 'r': Imm |= RISCVFenceField::R; break; 342 case 'w': Imm |= RISCVFenceField::W; break; 343 } 344 } 345 Inst.addOperand(MCOperand::createImm(Imm)); 346 } 347 }; 348 } // end anonymous namespace. 349 350 #define GET_REGISTER_MATCHER 351 #define GET_MATCHER_IMPLEMENTATION 352 #include "RISCVGenAsmMatcher.inc" 353 354 bool RISCVAsmParser::generateImmOutOfRangeError( 355 OperandVector &Operands, uint64_t ErrorInfo, int Lower, int Upper, 356 Twine Msg = "immediate must be an integer in the range") { 357 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 358 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); 359 } 360 361 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 362 OperandVector &Operands, 363 MCStreamer &Out, 364 uint64_t &ErrorInfo, 365 bool MatchingInlineAsm) { 366 MCInst Inst; 367 368 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm)) { 369 default: 370 break; 371 case Match_Success: 372 Inst.setLoc(IDLoc); 373 Out.EmitInstruction(Inst, getSTI()); 374 return false; 375 case Match_MissingFeature: 376 return Error(IDLoc, "instruction use requires an option to be enabled"); 377 case Match_MnemonicFail: 378 return Error(IDLoc, "unrecognized instruction mnemonic"); 379 case Match_InvalidOperand: { 380 SMLoc ErrorLoc = IDLoc; 381 if (ErrorInfo != ~0U) { 382 if (ErrorInfo >= Operands.size()) 383 return Error(ErrorLoc, "too few operands for instruction"); 384 385 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 386 if (ErrorLoc == SMLoc()) 387 ErrorLoc = IDLoc; 388 } 389 return Error(ErrorLoc, "invalid operand for instruction"); 390 } 391 case Match_InvalidUImm5: 392 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 393 case Match_InvalidSImm12: 394 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11), 395 (1 << 11) - 1); 396 case Match_InvalidUImm12: 397 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1); 398 case Match_InvalidSImm13Lsb0: 399 return generateImmOutOfRangeError( 400 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2, 401 "immediate must be a multiple of 2 bytes in the range"); 402 case Match_InvalidUImm20: 403 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1); 404 case Match_InvalidSImm21Lsb0: 405 return generateImmOutOfRangeError( 406 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2, 407 "immediate must be a multiple of 2 bytes in the range"); 408 case Match_InvalidFenceArg: { 409 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 410 return Error( 411 ErrorLoc, 412 "operand must be formed of letters selected in-order from 'iorw'"); 413 } 414 } 415 416 llvm_unreachable("Unknown match type detected!"); 417 } 418 419 bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 420 SMLoc &EndLoc) { 421 const AsmToken &Tok = getParser().getTok(); 422 StartLoc = Tok.getLoc(); 423 EndLoc = Tok.getEndLoc(); 424 RegNo = 0; 425 StringRef Name = getLexer().getTok().getIdentifier(); 426 427 if (!MatchRegisterName(Name) || !MatchRegisterAltName(Name)) { 428 getParser().Lex(); // Eat identifier token. 429 return false; 430 } 431 432 return Error(StartLoc, "invalid register name"); 433 } 434 435 OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands, 436 bool AllowParens) { 437 SMLoc FirstS = getLoc(); 438 bool HadParens = false; 439 AsmToken Buf[2]; 440 441 // If this a parenthesised register name is allowed, parse it atomically 442 if (AllowParens && getLexer().is(AsmToken::LParen)) { 443 size_t ReadCount = getLexer().peekTokens(Buf); 444 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) { 445 HadParens = true; 446 getParser().Lex(); // Eat '(' 447 } 448 } 449 450 switch (getLexer().getKind()) { 451 default: 452 return MatchOperand_NoMatch; 453 case AsmToken::Identifier: 454 StringRef Name = getLexer().getTok().getIdentifier(); 455 unsigned RegNo = MatchRegisterName(Name); 456 if (RegNo == 0) { 457 RegNo = MatchRegisterAltName(Name); 458 if (RegNo == 0) { 459 if (HadParens) 460 getLexer().UnLex(Buf[0]); 461 return MatchOperand_NoMatch; 462 } 463 } 464 if (HadParens) 465 Operands.push_back(RISCVOperand::createToken("(", FirstS)); 466 SMLoc S = getLoc(); 467 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 468 getLexer().Lex(); 469 Operands.push_back(RISCVOperand::createReg(RegNo, S, E)); 470 } 471 472 if (HadParens) { 473 getParser().Lex(); // Eat ')' 474 Operands.push_back(RISCVOperand::createToken(")", getLoc())); 475 } 476 477 return MatchOperand_Success; 478 } 479 480 OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) { 481 SMLoc S = getLoc(); 482 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 483 const MCExpr *Res; 484 485 switch (getLexer().getKind()) { 486 default: 487 return MatchOperand_NoMatch; 488 case AsmToken::LParen: 489 case AsmToken::Minus: 490 case AsmToken::Plus: 491 case AsmToken::Integer: 492 case AsmToken::String: 493 if (getParser().parseExpression(Res)) 494 return MatchOperand_ParseFail; 495 break; 496 case AsmToken::Identifier: { 497 StringRef Identifier; 498 if (getParser().parseIdentifier(Identifier)) 499 return MatchOperand_ParseFail; 500 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 501 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 502 break; 503 } 504 case AsmToken::Percent: 505 return parseOperandWithModifier(Operands); 506 } 507 508 Operands.push_back(RISCVOperand::createImm(Res, S, E)); 509 return MatchOperand_Success; 510 } 511 512 OperandMatchResultTy 513 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) { 514 SMLoc S = getLoc(); 515 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 516 517 if (getLexer().getKind() != AsmToken::Percent) { 518 Error(getLoc(), "expected '%' for operand modifier"); 519 return MatchOperand_ParseFail; 520 } 521 522 getParser().Lex(); // Eat '%' 523 524 if (getLexer().getKind() != AsmToken::Identifier) { 525 Error(getLoc(), "expected valid identifier for operand modifier"); 526 return MatchOperand_ParseFail; 527 } 528 StringRef Identifier = getParser().getTok().getIdentifier(); 529 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier); 530 if (VK == RISCVMCExpr::VK_RISCV_Invalid) { 531 Error(getLoc(), "unrecognized operand modifier"); 532 return MatchOperand_ParseFail; 533 } 534 535 getParser().Lex(); // Eat the identifier 536 if (getLexer().getKind() != AsmToken::LParen) { 537 Error(getLoc(), "expected '('"); 538 return MatchOperand_ParseFail; 539 } 540 getParser().Lex(); // Eat '(' 541 542 const MCExpr *SubExpr; 543 if (getParser().parseParenExpression(SubExpr, E)) { 544 return MatchOperand_ParseFail; 545 } 546 547 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext()); 548 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E)); 549 return MatchOperand_Success; 550 } 551 552 OperandMatchResultTy 553 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { 554 if (getLexer().isNot(AsmToken::LParen)) { 555 Error(getLoc(), "expected '('"); 556 return MatchOperand_ParseFail; 557 } 558 559 getParser().Lex(); // Eat '(' 560 Operands.push_back(RISCVOperand::createToken("(", getLoc())); 561 562 if (parseRegister(Operands) != MatchOperand_Success) { 563 Error(getLoc(), "expected register"); 564 return MatchOperand_ParseFail; 565 } 566 567 if (getLexer().isNot(AsmToken::RParen)) { 568 Error(getLoc(), "expected ')'"); 569 return MatchOperand_ParseFail; 570 } 571 572 getParser().Lex(); // Eat ')' 573 Operands.push_back(RISCVOperand::createToken(")", getLoc())); 574 575 return MatchOperand_Success; 576 } 577 578 /// Looks at a token type and creates the relevant operand 579 /// from this information, adding to Operands. 580 /// If operand was parsed, returns false, else true. 581 bool RISCVAsmParser::parseOperand(OperandVector &Operands) { 582 // Attempt to parse token as register 583 if (parseRegister(Operands, true) == MatchOperand_Success) 584 return false; 585 586 // Attempt to parse token as an immediate 587 if (parseImmediate(Operands) == MatchOperand_Success) { 588 // Parse memory base register if present 589 if (getLexer().is(AsmToken::LParen)) 590 return parseMemOpBaseReg(Operands) != MatchOperand_Success; 591 return false; 592 } 593 594 // Finally we have exhausted all options and must declare defeat. 595 Error(getLoc(), "unknown operand"); 596 return true; 597 } 598 599 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info, 600 StringRef Name, SMLoc NameLoc, 601 OperandVector &Operands) { 602 // First operand is token for instruction 603 Operands.push_back(RISCVOperand::createToken(Name, NameLoc)); 604 605 // If there are no more operands, then finish 606 if (getLexer().is(AsmToken::EndOfStatement)) 607 return false; 608 609 // Parse first operand 610 if (parseOperand(Operands)) 611 return true; 612 613 // Parse until end of statement, consuming commas between operands 614 while (getLexer().is(AsmToken::Comma)) { 615 // Consume comma token 616 getLexer().Lex(); 617 618 // Parse next operand 619 if (parseOperand(Operands)) 620 return true; 621 } 622 623 if (getLexer().isNot(AsmToken::EndOfStatement)) { 624 SMLoc Loc = getLexer().getLoc(); 625 getParser().eatToEndOfStatement(); 626 return Error(Loc, "unexpected token"); 627 } 628 629 getParser().Lex(); // Consume the EndOfStatement. 630 return false; 631 } 632 633 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr, 634 RISCVMCExpr::VariantKind &Kind, 635 int64_t &Addend) { 636 Kind = RISCVMCExpr::VK_RISCV_None; 637 Addend = 0; 638 639 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) { 640 Kind = RE->getKind(); 641 Expr = RE->getSubExpr(); 642 } 643 644 // It's a simple symbol reference or constant with no addend. 645 if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr)) 646 return true; 647 648 const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr); 649 if (!BE) 650 return false; 651 652 if (!isa<MCSymbolRefExpr>(BE->getLHS())) 653 return false; 654 655 if (BE->getOpcode() != MCBinaryExpr::Add && 656 BE->getOpcode() != MCBinaryExpr::Sub) 657 return false; 658 659 // We are able to support the subtraction of two symbol references 660 if (BE->getOpcode() == MCBinaryExpr::Sub && 661 isa<MCSymbolRefExpr>(BE->getRHS())) 662 return true; 663 664 // See if the addend is is a constant, otherwise there's more going 665 // on here than we can deal with. 666 auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS()); 667 if (!AddendExpr) 668 return false; 669 670 Addend = AddendExpr->getValue(); 671 if (BE->getOpcode() == MCBinaryExpr::Sub) 672 Addend = -Addend; 673 674 // It's some symbol reference + a constant addend 675 return Kind != RISCVMCExpr::VK_RISCV_Invalid; 676 } 677 678 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) { return true; } 679 680 extern "C" void LLVMInitializeRISCVAsmParser() { 681 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target()); 682 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target()); 683 } 684