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/RISCVAsmBackend.h" 11 #include "MCTargetDesc/RISCVMCExpr.h" 12 #include "MCTargetDesc/RISCVMCTargetDesc.h" 13 #include "MCTargetDesc/RISCVTargetStreamer.h" 14 #include "Utils/RISCVBaseInfo.h" 15 #include "Utils/RISCVMatInt.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/ADT/SmallVector.h" 18 #include "llvm/ADT/StringSwitch.h" 19 #include "llvm/MC/MCAssembler.h" 20 #include "llvm/MC/MCContext.h" 21 #include "llvm/MC/MCExpr.h" 22 #include "llvm/MC/MCInst.h" 23 #include "llvm/MC/MCInstBuilder.h" 24 #include "llvm/MC/MCParser/MCAsmLexer.h" 25 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 26 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 27 #include "llvm/MC/MCRegisterInfo.h" 28 #include "llvm/MC/MCStreamer.h" 29 #include "llvm/MC/MCSubtargetInfo.h" 30 #include "llvm/Support/Casting.h" 31 #include "llvm/Support/MathExtras.h" 32 #include "llvm/Support/TargetRegistry.h" 33 34 #include <limits> 35 36 using namespace llvm; 37 38 // Include the auto-generated portion of the compress emitter. 39 #define GEN_COMPRESS_INSTR 40 #include "RISCVGenCompressInstEmitter.inc" 41 42 namespace { 43 struct RISCVOperand; 44 45 class RISCVAsmParser : public MCTargetAsmParser { 46 SmallVector<FeatureBitset, 4> FeatureBitStack; 47 48 SMLoc getLoc() const { return getParser().getTok().getLoc(); } 49 bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); } 50 51 RISCVTargetStreamer &getTargetStreamer() { 52 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); 53 return static_cast<RISCVTargetStreamer &>(TS); 54 } 55 56 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 57 unsigned Kind) override; 58 59 bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo, 60 int64_t Lower, int64_t Upper, Twine Msg); 61 62 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 63 OperandVector &Operands, MCStreamer &Out, 64 uint64_t &ErrorInfo, 65 bool MatchingInlineAsm) override; 66 67 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 68 69 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 70 SMLoc NameLoc, OperandVector &Operands) override; 71 72 bool ParseDirective(AsmToken DirectiveID) override; 73 74 // Helper to actually emit an instruction to the MCStreamer. Also, when 75 // possible, compression of the instruction is performed. 76 void emitToStreamer(MCStreamer &S, const MCInst &Inst); 77 78 // Helper to emit a combination of LUI, ADDI(W), and SLLI instructions that 79 // synthesize the desired immedate value into the destination register. 80 void emitLoadImm(unsigned DestReg, int64_t Value, MCStreamer &Out); 81 82 // Helper to emit pseudo instruction "lla" used in PC-rel addressing. 83 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 84 85 /// Helper for processing MC instructions that have been successfully matched 86 /// by MatchAndEmitInstruction. Modifications to the emitted instructions, 87 /// like the expansion of pseudo instructions (e.g., "li"), can be performed 88 /// in this method. 89 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 90 91 // Auto-generated instruction matching functions 92 #define GET_ASSEMBLER_HEADER 93 #include "RISCVGenAsmMatcher.inc" 94 95 OperandMatchResultTy parseCSRSystemRegister(OperandVector &Operands); 96 OperandMatchResultTy parseImmediate(OperandVector &Operands); 97 OperandMatchResultTy parseRegister(OperandVector &Operands, 98 bool AllowParens = false); 99 OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands); 100 OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands); 101 OperandMatchResultTy parseBareSymbol(OperandVector &Operands); 102 OperandMatchResultTy parseJALOffset(OperandVector &Operands); 103 104 bool parseOperand(OperandVector &Operands, StringRef Mnemonic); 105 106 bool parseDirectiveOption(); 107 108 void setFeatureBits(uint64_t Feature, StringRef FeatureString) { 109 if (!(getSTI().getFeatureBits()[Feature])) { 110 MCSubtargetInfo &STI = copySTI(); 111 setAvailableFeatures( 112 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 113 } 114 } 115 116 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) { 117 if (getSTI().getFeatureBits()[Feature]) { 118 MCSubtargetInfo &STI = copySTI(); 119 setAvailableFeatures( 120 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 121 } 122 } 123 124 void pushFeatureBits() { 125 FeatureBitStack.push_back(getSTI().getFeatureBits()); 126 } 127 128 bool popFeatureBits() { 129 if (FeatureBitStack.empty()) 130 return true; 131 132 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val(); 133 copySTI().setFeatureBits(FeatureBits); 134 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits)); 135 136 return false; 137 } 138 public: 139 enum RISCVMatchResultTy { 140 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY, 141 #define GET_OPERAND_DIAGNOSTIC_TYPES 142 #include "RISCVGenAsmMatcher.inc" 143 #undef GET_OPERAND_DIAGNOSTIC_TYPES 144 }; 145 146 static bool classifySymbolRef(const MCExpr *Expr, 147 RISCVMCExpr::VariantKind &Kind, 148 int64_t &Addend); 149 150 RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, 151 const MCInstrInfo &MII, const MCTargetOptions &Options) 152 : MCTargetAsmParser(Options, STI, MII) { 153 Parser.addAliasForDirective(".half", ".2byte"); 154 Parser.addAliasForDirective(".hword", ".2byte"); 155 Parser.addAliasForDirective(".word", ".4byte"); 156 Parser.addAliasForDirective(".dword", ".8byte"); 157 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 158 } 159 }; 160 161 /// RISCVOperand - Instances of this class represent a parsed machine 162 /// instruction 163 struct RISCVOperand : public MCParsedAsmOperand { 164 165 enum KindTy { 166 Token, 167 Register, 168 Immediate, 169 SystemRegister 170 } Kind; 171 172 bool IsRV64; 173 174 struct RegOp { 175 unsigned RegNum; 176 }; 177 178 struct ImmOp { 179 const MCExpr *Val; 180 }; 181 182 struct SysRegOp { 183 const char *Data; 184 unsigned Length; 185 unsigned Encoding; 186 // FIXME: Add the Encoding parsed fields as needed for checks, 187 // e.g.: read/write or user/supervisor/machine privileges. 188 }; 189 190 SMLoc StartLoc, EndLoc; 191 union { 192 StringRef Tok; 193 RegOp Reg; 194 ImmOp Imm; 195 struct SysRegOp SysReg; 196 }; 197 198 RISCVOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 199 200 public: 201 RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() { 202 Kind = o.Kind; 203 IsRV64 = o.IsRV64; 204 StartLoc = o.StartLoc; 205 EndLoc = o.EndLoc; 206 switch (Kind) { 207 case Register: 208 Reg = o.Reg; 209 break; 210 case Immediate: 211 Imm = o.Imm; 212 break; 213 case Token: 214 Tok = o.Tok; 215 break; 216 case SystemRegister: 217 SysReg = o.SysReg; 218 break; 219 } 220 } 221 222 bool isToken() const override { return Kind == Token; } 223 bool isReg() const override { return Kind == Register; } 224 bool isImm() const override { return Kind == Immediate; } 225 bool isMem() const override { return false; } 226 bool isSystemRegister() const { return Kind == SystemRegister; } 227 228 static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm, 229 RISCVMCExpr::VariantKind &VK) { 230 if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) { 231 VK = RE->getKind(); 232 return RE->evaluateAsConstant(Imm); 233 } 234 235 if (auto CE = dyn_cast<MCConstantExpr>(Expr)) { 236 VK = RISCVMCExpr::VK_RISCV_None; 237 Imm = CE->getValue(); 238 return true; 239 } 240 241 return false; 242 } 243 244 // True if operand is a symbol with no modifiers, or a constant with no 245 // modifiers and isShiftedInt<N-1, 1>(Op). 246 template <int N> bool isBareSimmNLsb0() const { 247 int64_t Imm; 248 RISCVMCExpr::VariantKind VK; 249 if (!isImm()) 250 return false; 251 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 252 bool IsValid; 253 if (!IsConstantImm) 254 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 255 else 256 IsValid = isShiftedInt<N - 1, 1>(Imm); 257 return IsValid && VK == RISCVMCExpr::VK_RISCV_None; 258 } 259 260 // Predicate methods for AsmOperands defined in RISCVInstrInfo.td 261 262 bool isBareSymbol() const { 263 int64_t Imm; 264 RISCVMCExpr::VariantKind VK; 265 // Must be of 'immediate' type but not a constant. 266 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 267 return false; 268 return RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm) && 269 VK == RISCVMCExpr::VK_RISCV_None; 270 } 271 272 bool isCSRSystemRegister() const { return isSystemRegister(); } 273 274 /// Return true if the operand is a valid for the fence instruction e.g. 275 /// ('iorw'). 276 bool isFenceArg() const { 277 if (!isImm()) 278 return false; 279 const MCExpr *Val = getImm(); 280 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val); 281 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None) 282 return false; 283 284 StringRef Str = SVal->getSymbol().getName(); 285 // Letters must be unique, taken from 'iorw', and in ascending order. This 286 // holds as long as each individual character is one of 'iorw' and is 287 // greater than the previous character. 288 char Prev = '\0'; 289 for (char c : Str) { 290 if (c != 'i' && c != 'o' && c != 'r' && c != 'w') 291 return false; 292 if (c <= Prev) 293 return false; 294 Prev = c; 295 } 296 return true; 297 } 298 299 /// Return true if the operand is a valid floating point rounding mode. 300 bool isFRMArg() const { 301 if (!isImm()) 302 return false; 303 const MCExpr *Val = getImm(); 304 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val); 305 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None) 306 return false; 307 308 StringRef Str = SVal->getSymbol().getName(); 309 310 return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid; 311 } 312 313 bool isImmXLenLI() const { 314 int64_t Imm; 315 RISCVMCExpr::VariantKind VK; 316 if (!isImm()) 317 return false; 318 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 319 if (VK == RISCVMCExpr::VK_RISCV_LO || VK == RISCVMCExpr::VK_RISCV_PCREL_LO) 320 return true; 321 // Given only Imm, ensuring that the actually specified constant is either 322 // a signed or unsigned 64-bit number is unfortunately impossible. 323 bool IsInRange = isRV64() ? true : isInt<32>(Imm) || isUInt<32>(Imm); 324 return IsConstantImm && IsInRange && VK == RISCVMCExpr::VK_RISCV_None; 325 } 326 327 bool isUImmLog2XLen() const { 328 int64_t Imm; 329 RISCVMCExpr::VariantKind VK; 330 if (!isImm()) 331 return false; 332 if (!evaluateConstantImm(getImm(), Imm, VK) || 333 VK != RISCVMCExpr::VK_RISCV_None) 334 return false; 335 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm); 336 } 337 338 bool isUImmLog2XLenNonZero() const { 339 int64_t Imm; 340 RISCVMCExpr::VariantKind VK; 341 if (!isImm()) 342 return false; 343 if (!evaluateConstantImm(getImm(), Imm, VK) || 344 VK != RISCVMCExpr::VK_RISCV_None) 345 return false; 346 if (Imm == 0) 347 return false; 348 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm); 349 } 350 351 bool isUImm5() const { 352 int64_t Imm; 353 RISCVMCExpr::VariantKind VK; 354 if (!isImm()) 355 return false; 356 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 357 return IsConstantImm && isUInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; 358 } 359 360 bool isUImm5NonZero() const { 361 int64_t Imm; 362 RISCVMCExpr::VariantKind VK; 363 if (!isImm()) 364 return false; 365 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 366 return IsConstantImm && isUInt<5>(Imm) && (Imm != 0) && 367 VK == RISCVMCExpr::VK_RISCV_None; 368 } 369 370 bool isSImm6() const { 371 if (!isImm()) 372 return false; 373 RISCVMCExpr::VariantKind VK; 374 int64_t Imm; 375 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 376 return IsConstantImm && isInt<6>(Imm) && 377 VK == RISCVMCExpr::VK_RISCV_None; 378 } 379 380 bool isSImm6NonZero() const { 381 if (!isImm()) 382 return false; 383 RISCVMCExpr::VariantKind VK; 384 int64_t Imm; 385 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 386 return IsConstantImm && isInt<6>(Imm) && (Imm != 0) && 387 VK == RISCVMCExpr::VK_RISCV_None; 388 } 389 390 bool isCLUIImm() const { 391 if (!isImm()) 392 return false; 393 int64_t Imm; 394 RISCVMCExpr::VariantKind VK; 395 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 396 return IsConstantImm && (Imm != 0) && 397 (isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) && 398 VK == RISCVMCExpr::VK_RISCV_None; 399 } 400 401 bool isUImm7Lsb00() const { 402 if (!isImm()) 403 return false; 404 int64_t Imm; 405 RISCVMCExpr::VariantKind VK; 406 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 407 return IsConstantImm && isShiftedUInt<5, 2>(Imm) && 408 VK == RISCVMCExpr::VK_RISCV_None; 409 } 410 411 bool isUImm8Lsb00() const { 412 if (!isImm()) 413 return false; 414 int64_t Imm; 415 RISCVMCExpr::VariantKind VK; 416 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 417 return IsConstantImm && isShiftedUInt<6, 2>(Imm) && 418 VK == RISCVMCExpr::VK_RISCV_None; 419 } 420 421 bool isUImm8Lsb000() const { 422 if (!isImm()) 423 return false; 424 int64_t Imm; 425 RISCVMCExpr::VariantKind VK; 426 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 427 return IsConstantImm && isShiftedUInt<5, 3>(Imm) && 428 VK == RISCVMCExpr::VK_RISCV_None; 429 } 430 431 bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); } 432 433 bool isUImm9Lsb000() const { 434 if (!isImm()) 435 return false; 436 int64_t Imm; 437 RISCVMCExpr::VariantKind VK; 438 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 439 return IsConstantImm && isShiftedUInt<6, 3>(Imm) && 440 VK == RISCVMCExpr::VK_RISCV_None; 441 } 442 443 bool isUImm10Lsb00NonZero() const { 444 if (!isImm()) 445 return false; 446 int64_t Imm; 447 RISCVMCExpr::VariantKind VK; 448 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 449 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) && 450 VK == RISCVMCExpr::VK_RISCV_None; 451 } 452 453 bool isSImm12() const { 454 RISCVMCExpr::VariantKind VK; 455 int64_t Imm; 456 bool IsValid; 457 if (!isImm()) 458 return false; 459 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 460 if (!IsConstantImm) 461 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 462 else 463 IsValid = isInt<12>(Imm); 464 return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) || 465 VK == RISCVMCExpr::VK_RISCV_LO || 466 VK == RISCVMCExpr::VK_RISCV_PCREL_LO); 467 } 468 469 bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); } 470 471 bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); } 472 473 bool isSImm10Lsb0000NonZero() const { 474 if (!isImm()) 475 return false; 476 int64_t Imm; 477 RISCVMCExpr::VariantKind VK; 478 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 479 return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) && 480 VK == RISCVMCExpr::VK_RISCV_None; 481 } 482 483 bool isUImm20LUI() const { 484 RISCVMCExpr::VariantKind VK; 485 int64_t Imm; 486 bool IsValid; 487 if (!isImm()) 488 return false; 489 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 490 if (!IsConstantImm) { 491 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 492 return IsValid && VK == RISCVMCExpr::VK_RISCV_HI; 493 } else { 494 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None || 495 VK == RISCVMCExpr::VK_RISCV_HI); 496 } 497 } 498 499 bool isUImm20AUIPC() const { 500 RISCVMCExpr::VariantKind VK; 501 int64_t Imm; 502 bool IsValid; 503 if (!isImm()) 504 return false; 505 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 506 if (!IsConstantImm) { 507 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK, Imm); 508 return IsValid && VK == RISCVMCExpr::VK_RISCV_PCREL_HI; 509 } else { 510 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None || 511 VK == RISCVMCExpr::VK_RISCV_PCREL_HI); 512 } 513 } 514 515 bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); } 516 517 /// getStartLoc - Gets location of the first token of this operand 518 SMLoc getStartLoc() const override { return StartLoc; } 519 /// getEndLoc - Gets location of the last token of this operand 520 SMLoc getEndLoc() const override { return EndLoc; } 521 /// True if this operand is for an RV64 instruction 522 bool isRV64() const { return IsRV64; } 523 524 unsigned getReg() const override { 525 assert(Kind == Register && "Invalid type access!"); 526 return Reg.RegNum; 527 } 528 529 StringRef getSysReg() const { 530 assert(Kind == SystemRegister && "Invalid access!"); 531 return StringRef(SysReg.Data, SysReg.Length); 532 } 533 534 const MCExpr *getImm() const { 535 assert(Kind == Immediate && "Invalid type access!"); 536 return Imm.Val; 537 } 538 539 StringRef getToken() const { 540 assert(Kind == Token && "Invalid type access!"); 541 return Tok; 542 } 543 544 void print(raw_ostream &OS) const override { 545 switch (Kind) { 546 case Immediate: 547 OS << *getImm(); 548 break; 549 case Register: 550 OS << "<register x"; 551 OS << getReg() << ">"; 552 break; 553 case Token: 554 OS << "'" << getToken() << "'"; 555 break; 556 case SystemRegister: 557 OS << "<sysreg: " << getSysReg() << '>'; 558 break; 559 } 560 } 561 562 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S, 563 bool IsRV64) { 564 auto Op = make_unique<RISCVOperand>(Token); 565 Op->Tok = Str; 566 Op->StartLoc = S; 567 Op->EndLoc = S; 568 Op->IsRV64 = IsRV64; 569 return Op; 570 } 571 572 static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S, 573 SMLoc E, bool IsRV64) { 574 auto Op = make_unique<RISCVOperand>(Register); 575 Op->Reg.RegNum = RegNo; 576 Op->StartLoc = S; 577 Op->EndLoc = E; 578 Op->IsRV64 = IsRV64; 579 return Op; 580 } 581 582 static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S, 583 SMLoc E, bool IsRV64) { 584 auto Op = make_unique<RISCVOperand>(Immediate); 585 Op->Imm.Val = Val; 586 Op->StartLoc = S; 587 Op->EndLoc = E; 588 Op->IsRV64 = IsRV64; 589 return Op; 590 } 591 592 static std::unique_ptr<RISCVOperand> 593 createSysReg(StringRef Str, SMLoc S, unsigned Encoding, bool IsRV64) { 594 auto Op = make_unique<RISCVOperand>(SystemRegister); 595 Op->SysReg.Data = Str.data(); 596 Op->SysReg.Length = Str.size(); 597 Op->SysReg.Encoding = Encoding; 598 Op->StartLoc = S; 599 Op->IsRV64 = IsRV64; 600 return Op; 601 } 602 603 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 604 assert(Expr && "Expr shouldn't be null!"); 605 int64_t Imm = 0; 606 RISCVMCExpr::VariantKind VK; 607 bool IsConstant = evaluateConstantImm(Expr, Imm, VK); 608 609 if (IsConstant) 610 Inst.addOperand(MCOperand::createImm(Imm)); 611 else 612 Inst.addOperand(MCOperand::createExpr(Expr)); 613 } 614 615 // Used by the TableGen Code 616 void addRegOperands(MCInst &Inst, unsigned N) const { 617 assert(N == 1 && "Invalid number of operands!"); 618 Inst.addOperand(MCOperand::createReg(getReg())); 619 } 620 621 void addImmOperands(MCInst &Inst, unsigned N) const { 622 assert(N == 1 && "Invalid number of operands!"); 623 addExpr(Inst, getImm()); 624 } 625 626 void addFenceArgOperands(MCInst &Inst, unsigned N) const { 627 assert(N == 1 && "Invalid number of operands!"); 628 // isFenceArg has validated the operand, meaning this cast is safe 629 auto SE = cast<MCSymbolRefExpr>(getImm()); 630 631 unsigned Imm = 0; 632 for (char c : SE->getSymbol().getName()) { 633 switch (c) { 634 default: 635 llvm_unreachable("FenceArg must contain only [iorw]"); 636 case 'i': Imm |= RISCVFenceField::I; break; 637 case 'o': Imm |= RISCVFenceField::O; break; 638 case 'r': Imm |= RISCVFenceField::R; break; 639 case 'w': Imm |= RISCVFenceField::W; break; 640 } 641 } 642 Inst.addOperand(MCOperand::createImm(Imm)); 643 } 644 645 void addCSRSystemRegisterOperands(MCInst &Inst, unsigned N) const { 646 assert(N == 1 && "Invalid number of operands!"); 647 Inst.addOperand(MCOperand::createImm(SysReg.Encoding)); 648 } 649 650 // Returns the rounding mode represented by this RISCVOperand. Should only 651 // be called after checking isFRMArg. 652 RISCVFPRndMode::RoundingMode getRoundingMode() const { 653 // isFRMArg has validated the operand, meaning this cast is safe. 654 auto SE = cast<MCSymbolRefExpr>(getImm()); 655 RISCVFPRndMode::RoundingMode FRM = 656 RISCVFPRndMode::stringToRoundingMode(SE->getSymbol().getName()); 657 assert(FRM != RISCVFPRndMode::Invalid && "Invalid rounding mode"); 658 return FRM; 659 } 660 661 void addFRMArgOperands(MCInst &Inst, unsigned N) const { 662 assert(N == 1 && "Invalid number of operands!"); 663 Inst.addOperand(MCOperand::createImm(getRoundingMode())); 664 } 665 }; 666 } // end anonymous namespace. 667 668 #define GET_REGISTER_MATCHER 669 #define GET_MATCHER_IMPLEMENTATION 670 #include "RISCVGenAsmMatcher.inc" 671 672 // Return the matching FPR64 register for the given FPR32. 673 // FIXME: Ideally this function could be removed in favour of using 674 // information from TableGen. 675 unsigned convertFPR32ToFPR64(unsigned Reg) { 676 switch (Reg) { 677 default: 678 llvm_unreachable("Not a recognised FPR32 register"); 679 case RISCV::F0_32: return RISCV::F0_64; 680 case RISCV::F1_32: return RISCV::F1_64; 681 case RISCV::F2_32: return RISCV::F2_64; 682 case RISCV::F3_32: return RISCV::F3_64; 683 case RISCV::F4_32: return RISCV::F4_64; 684 case RISCV::F5_32: return RISCV::F5_64; 685 case RISCV::F6_32: return RISCV::F6_64; 686 case RISCV::F7_32: return RISCV::F7_64; 687 case RISCV::F8_32: return RISCV::F8_64; 688 case RISCV::F9_32: return RISCV::F9_64; 689 case RISCV::F10_32: return RISCV::F10_64; 690 case RISCV::F11_32: return RISCV::F11_64; 691 case RISCV::F12_32: return RISCV::F12_64; 692 case RISCV::F13_32: return RISCV::F13_64; 693 case RISCV::F14_32: return RISCV::F14_64; 694 case RISCV::F15_32: return RISCV::F15_64; 695 case RISCV::F16_32: return RISCV::F16_64; 696 case RISCV::F17_32: return RISCV::F17_64; 697 case RISCV::F18_32: return RISCV::F18_64; 698 case RISCV::F19_32: return RISCV::F19_64; 699 case RISCV::F20_32: return RISCV::F20_64; 700 case RISCV::F21_32: return RISCV::F21_64; 701 case RISCV::F22_32: return RISCV::F22_64; 702 case RISCV::F23_32: return RISCV::F23_64; 703 case RISCV::F24_32: return RISCV::F24_64; 704 case RISCV::F25_32: return RISCV::F25_64; 705 case RISCV::F26_32: return RISCV::F26_64; 706 case RISCV::F27_32: return RISCV::F27_64; 707 case RISCV::F28_32: return RISCV::F28_64; 708 case RISCV::F29_32: return RISCV::F29_64; 709 case RISCV::F30_32: return RISCV::F30_64; 710 case RISCV::F31_32: return RISCV::F31_64; 711 } 712 } 713 714 unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, 715 unsigned Kind) { 716 RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp); 717 if (!Op.isReg()) 718 return Match_InvalidOperand; 719 720 unsigned Reg = Op.getReg(); 721 bool IsRegFPR32 = 722 RISCVMCRegisterClasses[RISCV::FPR32RegClassID].contains(Reg); 723 bool IsRegFPR32C = 724 RISCVMCRegisterClasses[RISCV::FPR32CRegClassID].contains(Reg); 725 726 // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the 727 // register from FPR32 to FPR64 or FPR32C to FPR64C if necessary. 728 if ((IsRegFPR32 && Kind == MCK_FPR64) || 729 (IsRegFPR32C && Kind == MCK_FPR64C)) { 730 Op.Reg.RegNum = convertFPR32ToFPR64(Reg); 731 return Match_Success; 732 } 733 return Match_InvalidOperand; 734 } 735 736 bool RISCVAsmParser::generateImmOutOfRangeError( 737 OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper, 738 Twine Msg = "immediate must be an integer in the range") { 739 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 740 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); 741 } 742 743 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 744 OperandVector &Operands, 745 MCStreamer &Out, 746 uint64_t &ErrorInfo, 747 bool MatchingInlineAsm) { 748 MCInst Inst; 749 750 auto Result = 751 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); 752 switch (Result) { 753 default: 754 break; 755 case Match_Success: 756 return processInstruction(Inst, IDLoc, Out); 757 case Match_MissingFeature: 758 return Error(IDLoc, "instruction use requires an option to be enabled"); 759 case Match_MnemonicFail: 760 return Error(IDLoc, "unrecognized instruction mnemonic"); 761 case Match_InvalidOperand: { 762 SMLoc ErrorLoc = IDLoc; 763 if (ErrorInfo != ~0U) { 764 if (ErrorInfo >= Operands.size()) 765 return Error(ErrorLoc, "too few operands for instruction"); 766 767 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 768 if (ErrorLoc == SMLoc()) 769 ErrorLoc = IDLoc; 770 } 771 return Error(ErrorLoc, "invalid operand for instruction"); 772 } 773 } 774 775 // Handle the case when the error message is of specific type 776 // other than the generic Match_InvalidOperand, and the 777 // corresponding operand is missing. 778 if (Result > FIRST_TARGET_MATCH_RESULT_TY) { 779 SMLoc ErrorLoc = IDLoc; 780 if (ErrorInfo != ~0U && ErrorInfo >= Operands.size()) 781 return Error(ErrorLoc, "too few operands for instruction"); 782 } 783 784 switch(Result) { 785 default: 786 break; 787 case Match_InvalidImmXLenLI: 788 if (isRV64()) { 789 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 790 return Error(ErrorLoc, "operand must be a constant 64-bit integer"); 791 } 792 return generateImmOutOfRangeError(Operands, ErrorInfo, 793 std::numeric_limits<int32_t>::min(), 794 std::numeric_limits<uint32_t>::max()); 795 case Match_InvalidUImmLog2XLen: 796 if (isRV64()) 797 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); 798 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 799 case Match_InvalidUImmLog2XLenNonZero: 800 if (isRV64()) 801 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1); 802 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1); 803 case Match_InvalidUImm5: 804 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 805 case Match_InvalidSImm6: 806 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5), 807 (1 << 5) - 1); 808 case Match_InvalidSImm6NonZero: 809 return generateImmOutOfRangeError( 810 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1, 811 "immediate must be non-zero in the range"); 812 case Match_InvalidCLUIImm: 813 return generateImmOutOfRangeError( 814 Operands, ErrorInfo, 1, (1 << 5) - 1, 815 "immediate must be in [0xfffe0, 0xfffff] or"); 816 case Match_InvalidUImm7Lsb00: 817 return generateImmOutOfRangeError( 818 Operands, ErrorInfo, 0, (1 << 7) - 4, 819 "immediate must be a multiple of 4 bytes in the range"); 820 case Match_InvalidUImm8Lsb00: 821 return generateImmOutOfRangeError( 822 Operands, ErrorInfo, 0, (1 << 8) - 4, 823 "immediate must be a multiple of 4 bytes in the range"); 824 case Match_InvalidUImm8Lsb000: 825 return generateImmOutOfRangeError( 826 Operands, ErrorInfo, 0, (1 << 8) - 8, 827 "immediate must be a multiple of 8 bytes in the range"); 828 case Match_InvalidSImm9Lsb0: 829 return generateImmOutOfRangeError( 830 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2, 831 "immediate must be a multiple of 2 bytes in the range"); 832 case Match_InvalidUImm9Lsb000: 833 return generateImmOutOfRangeError( 834 Operands, ErrorInfo, 0, (1 << 9) - 8, 835 "immediate must be a multiple of 8 bytes in the range"); 836 case Match_InvalidUImm10Lsb00NonZero: 837 return generateImmOutOfRangeError( 838 Operands, ErrorInfo, 4, (1 << 10) - 4, 839 "immediate must be a multiple of 4 bytes in the range"); 840 case Match_InvalidSImm10Lsb0000NonZero: 841 return generateImmOutOfRangeError( 842 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16, 843 "immediate must be a multiple of 16 bytes and non-zero in the range"); 844 case Match_InvalidSImm12: 845 return generateImmOutOfRangeError( 846 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1, 847 "operand must be a symbol with %lo/%pcrel_lo modifier or an integer in " 848 "the range"); 849 case Match_InvalidSImm12Lsb0: 850 return generateImmOutOfRangeError( 851 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2, 852 "immediate must be a multiple of 2 bytes in the range"); 853 case Match_InvalidSImm13Lsb0: 854 return generateImmOutOfRangeError( 855 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2, 856 "immediate must be a multiple of 2 bytes in the range"); 857 case Match_InvalidUImm20LUI: 858 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1, 859 "operand must be a symbol with %hi() " 860 "modifier or an integer in the range"); 861 case Match_InvalidUImm20AUIPC: 862 return generateImmOutOfRangeError( 863 Operands, ErrorInfo, 0, (1 << 20) - 1, 864 "operand must be a symbol with %pcrel_hi() modifier or an integer in " 865 "the range"); 866 case Match_InvalidSImm21Lsb0JAL: 867 return generateImmOutOfRangeError( 868 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2, 869 "immediate must be a multiple of 2 bytes in the range"); 870 case Match_InvalidCSRSystemRegister: { 871 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1, 872 "operand must be a valid system register " 873 "name or an integer in the range"); 874 } 875 case Match_InvalidFenceArg: { 876 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 877 return Error( 878 ErrorLoc, 879 "operand must be formed of letters selected in-order from 'iorw'"); 880 } 881 case Match_InvalidFRMArg: { 882 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 883 return Error( 884 ErrorLoc, 885 "operand must be a valid floating point rounding mode mnemonic"); 886 } 887 case Match_InvalidBareSymbol: { 888 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 889 return Error(ErrorLoc, "operand must be a bare symbol name"); 890 } 891 } 892 893 llvm_unreachable("Unknown match type detected!"); 894 } 895 896 bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 897 SMLoc &EndLoc) { 898 const AsmToken &Tok = getParser().getTok(); 899 StartLoc = Tok.getLoc(); 900 EndLoc = Tok.getEndLoc(); 901 RegNo = 0; 902 StringRef Name = getLexer().getTok().getIdentifier(); 903 904 if (!MatchRegisterName(Name) || !MatchRegisterAltName(Name)) { 905 getParser().Lex(); // Eat identifier token. 906 return false; 907 } 908 909 return Error(StartLoc, "invalid register name"); 910 } 911 912 OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands, 913 bool AllowParens) { 914 SMLoc FirstS = getLoc(); 915 bool HadParens = false; 916 AsmToken Buf[2]; 917 918 // If this a parenthesised register name is allowed, parse it atomically 919 if (AllowParens && getLexer().is(AsmToken::LParen)) { 920 size_t ReadCount = getLexer().peekTokens(Buf); 921 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) { 922 HadParens = true; 923 getParser().Lex(); // Eat '(' 924 } 925 } 926 927 switch (getLexer().getKind()) { 928 default: 929 return MatchOperand_NoMatch; 930 case AsmToken::Identifier: 931 StringRef Name = getLexer().getTok().getIdentifier(); 932 unsigned RegNo = MatchRegisterName(Name); 933 if (RegNo == 0) { 934 RegNo = MatchRegisterAltName(Name); 935 if (RegNo == 0) { 936 if (HadParens) 937 getLexer().UnLex(Buf[0]); 938 return MatchOperand_NoMatch; 939 } 940 } 941 if (HadParens) 942 Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64())); 943 SMLoc S = getLoc(); 944 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 945 getLexer().Lex(); 946 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64())); 947 } 948 949 if (HadParens) { 950 getParser().Lex(); // Eat ')' 951 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 952 } 953 954 return MatchOperand_Success; 955 } 956 957 OperandMatchResultTy 958 RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) { 959 SMLoc S = getLoc(); 960 const MCExpr *Res; 961 962 switch (getLexer().getKind()) { 963 default: 964 return MatchOperand_NoMatch; 965 case AsmToken::LParen: 966 case AsmToken::Minus: 967 case AsmToken::Plus: 968 case AsmToken::Integer: 969 case AsmToken::String: { 970 if (getParser().parseExpression(Res)) 971 return MatchOperand_ParseFail; 972 973 auto *CE = dyn_cast<MCConstantExpr>(Res); 974 if (CE) { 975 int64_t Imm = CE->getValue(); 976 if (isUInt<12>(Imm)) { 977 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm); 978 // Accept an immediate representing a named or un-named Sys Reg 979 // if the range is valid, regardless of the required features. 980 Operands.push_back(RISCVOperand::createSysReg( 981 SysReg ? SysReg->Name : "", S, Imm, isRV64())); 982 return MatchOperand_Success; 983 } 984 } 985 986 Twine Msg = "immediate must be an integer in the range"; 987 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 988 return MatchOperand_ParseFail; 989 } 990 case AsmToken::Identifier: { 991 StringRef Identifier; 992 if (getParser().parseIdentifier(Identifier)) 993 return MatchOperand_ParseFail; 994 995 auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier); 996 // Accept a named Sys Reg if the required features are present. 997 if (SysReg) { 998 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits())) { 999 Error(S, "system register use requires an option to be enabled"); 1000 return MatchOperand_ParseFail; 1001 } 1002 Operands.push_back(RISCVOperand::createSysReg( 1003 Identifier, S, SysReg->Encoding, isRV64())); 1004 return MatchOperand_Success; 1005 } 1006 1007 Twine Msg = "operand must be a valid system register name " 1008 "or an integer in the range"; 1009 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1010 return MatchOperand_ParseFail; 1011 } 1012 case AsmToken::Percent: { 1013 // Discard operand with modifier. 1014 Twine Msg = "immediate must be an integer in the range"; 1015 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1016 return MatchOperand_ParseFail; 1017 } 1018 } 1019 1020 return MatchOperand_NoMatch; 1021 } 1022 1023 OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) { 1024 SMLoc S = getLoc(); 1025 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1026 const MCExpr *Res; 1027 1028 switch (getLexer().getKind()) { 1029 default: 1030 return MatchOperand_NoMatch; 1031 case AsmToken::LParen: 1032 case AsmToken::Minus: 1033 case AsmToken::Plus: 1034 case AsmToken::Integer: 1035 case AsmToken::String: 1036 case AsmToken::Identifier: 1037 if (getParser().parseExpression(Res)) 1038 return MatchOperand_ParseFail; 1039 break; 1040 case AsmToken::Percent: 1041 return parseOperandWithModifier(Operands); 1042 } 1043 1044 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1045 return MatchOperand_Success; 1046 } 1047 1048 OperandMatchResultTy 1049 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) { 1050 SMLoc S = getLoc(); 1051 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1052 1053 if (getLexer().getKind() != AsmToken::Percent) { 1054 Error(getLoc(), "expected '%' for operand modifier"); 1055 return MatchOperand_ParseFail; 1056 } 1057 1058 getParser().Lex(); // Eat '%' 1059 1060 if (getLexer().getKind() != AsmToken::Identifier) { 1061 Error(getLoc(), "expected valid identifier for operand modifier"); 1062 return MatchOperand_ParseFail; 1063 } 1064 StringRef Identifier = getParser().getTok().getIdentifier(); 1065 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier); 1066 if (VK == RISCVMCExpr::VK_RISCV_Invalid) { 1067 Error(getLoc(), "unrecognized operand modifier"); 1068 return MatchOperand_ParseFail; 1069 } 1070 1071 getParser().Lex(); // Eat the identifier 1072 if (getLexer().getKind() != AsmToken::LParen) { 1073 Error(getLoc(), "expected '('"); 1074 return MatchOperand_ParseFail; 1075 } 1076 getParser().Lex(); // Eat '(' 1077 1078 const MCExpr *SubExpr; 1079 if (getParser().parseParenExpression(SubExpr, E)) { 1080 return MatchOperand_ParseFail; 1081 } 1082 1083 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext()); 1084 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64())); 1085 return MatchOperand_Success; 1086 } 1087 1088 OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) { 1089 SMLoc S = getLoc(); 1090 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1091 const MCExpr *Res; 1092 1093 if (getLexer().getKind() != AsmToken::Identifier) 1094 return MatchOperand_NoMatch; 1095 1096 StringRef Identifier; 1097 if (getParser().parseIdentifier(Identifier)) 1098 return MatchOperand_ParseFail; 1099 1100 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1101 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1102 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1103 return MatchOperand_Success; 1104 } 1105 1106 OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) { 1107 // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo` 1108 // both being acceptable forms. When parsing `jal ra, foo` this function 1109 // will be called for the `ra` register operand in an attempt to match the 1110 // single-operand alias. parseJALOffset must fail for this case. It would 1111 // seem logical to try parse the operand using parseImmediate and return 1112 // NoMatch if the next token is a comma (meaning we must be parsing a jal in 1113 // the second form rather than the first). We can't do this as there's no 1114 // way of rewinding the lexer state. Instead, return NoMatch if this operand 1115 // is an identifier and is followed by a comma. 1116 if (getLexer().is(AsmToken::Identifier) && 1117 getLexer().peekTok().is(AsmToken::Comma)) 1118 return MatchOperand_NoMatch; 1119 1120 return parseImmediate(Operands); 1121 } 1122 1123 OperandMatchResultTy 1124 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { 1125 if (getLexer().isNot(AsmToken::LParen)) { 1126 Error(getLoc(), "expected '('"); 1127 return MatchOperand_ParseFail; 1128 } 1129 1130 getParser().Lex(); // Eat '(' 1131 Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64())); 1132 1133 if (parseRegister(Operands) != MatchOperand_Success) { 1134 Error(getLoc(), "expected register"); 1135 return MatchOperand_ParseFail; 1136 } 1137 1138 if (getLexer().isNot(AsmToken::RParen)) { 1139 Error(getLoc(), "expected ')'"); 1140 return MatchOperand_ParseFail; 1141 } 1142 1143 getParser().Lex(); // Eat ')' 1144 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 1145 1146 return MatchOperand_Success; 1147 } 1148 1149 /// Looks at a token type and creates the relevant operand from this 1150 /// information, adding to Operands. If operand was parsed, returns false, else 1151 /// true. 1152 bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 1153 // Check if the current operand has a custom associated parser, if so, try to 1154 // custom parse the operand, or fallback to the general approach. 1155 OperandMatchResultTy Result = 1156 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); 1157 if (Result == MatchOperand_Success) 1158 return false; 1159 if (Result == MatchOperand_ParseFail) 1160 return true; 1161 1162 // Attempt to parse token as a register. 1163 if (parseRegister(Operands, true) == MatchOperand_Success) 1164 return false; 1165 1166 // Attempt to parse token as an immediate 1167 if (parseImmediate(Operands) == MatchOperand_Success) { 1168 // Parse memory base register if present 1169 if (getLexer().is(AsmToken::LParen)) 1170 return parseMemOpBaseReg(Operands) != MatchOperand_Success; 1171 return false; 1172 } 1173 1174 // Finally we have exhausted all options and must declare defeat. 1175 Error(getLoc(), "unknown operand"); 1176 return true; 1177 } 1178 1179 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info, 1180 StringRef Name, SMLoc NameLoc, 1181 OperandVector &Operands) { 1182 // Ensure that if the instruction occurs when relaxation is enabled, 1183 // relocations are forced for the file. Ideally this would be done when there 1184 // is enough information to reliably determine if the instruction itself may 1185 // cause relaxations. Unfortunately instruction processing stage occurs in the 1186 // same pass as relocation emission, so it's too late to set a 'sticky bit' 1187 // for the entire file. 1188 if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) { 1189 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr(); 1190 if (Assembler != nullptr) { 1191 RISCVAsmBackend &MAB = 1192 static_cast<RISCVAsmBackend &>(Assembler->getBackend()); 1193 MAB.setForceRelocs(); 1194 } 1195 } 1196 1197 // First operand is token for instruction 1198 Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64())); 1199 1200 // If there are no more operands, then finish 1201 if (getLexer().is(AsmToken::EndOfStatement)) 1202 return false; 1203 1204 // Parse first operand 1205 if (parseOperand(Operands, Name)) 1206 return true; 1207 1208 // Parse until end of statement, consuming commas between operands 1209 unsigned OperandIdx = 1; 1210 while (getLexer().is(AsmToken::Comma)) { 1211 // Consume comma token 1212 getLexer().Lex(); 1213 1214 // Parse next operand 1215 if (parseOperand(Operands, Name)) 1216 return true; 1217 1218 ++OperandIdx; 1219 } 1220 1221 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1222 SMLoc Loc = getLexer().getLoc(); 1223 getParser().eatToEndOfStatement(); 1224 return Error(Loc, "unexpected token"); 1225 } 1226 1227 getParser().Lex(); // Consume the EndOfStatement. 1228 return false; 1229 } 1230 1231 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr, 1232 RISCVMCExpr::VariantKind &Kind, 1233 int64_t &Addend) { 1234 Kind = RISCVMCExpr::VK_RISCV_None; 1235 Addend = 0; 1236 1237 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) { 1238 Kind = RE->getKind(); 1239 Expr = RE->getSubExpr(); 1240 } 1241 1242 // It's a simple symbol reference or constant with no addend. 1243 if (isa<MCConstantExpr>(Expr) || isa<MCSymbolRefExpr>(Expr)) 1244 return true; 1245 1246 const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr); 1247 if (!BE) 1248 return false; 1249 1250 if (!isa<MCSymbolRefExpr>(BE->getLHS())) 1251 return false; 1252 1253 if (BE->getOpcode() != MCBinaryExpr::Add && 1254 BE->getOpcode() != MCBinaryExpr::Sub) 1255 return false; 1256 1257 // We are able to support the subtraction of two symbol references 1258 if (BE->getOpcode() == MCBinaryExpr::Sub && 1259 isa<MCSymbolRefExpr>(BE->getRHS())) 1260 return true; 1261 1262 // See if the addend is a constant, otherwise there's more going 1263 // on here than we can deal with. 1264 auto AddendExpr = dyn_cast<MCConstantExpr>(BE->getRHS()); 1265 if (!AddendExpr) 1266 return false; 1267 1268 Addend = AddendExpr->getValue(); 1269 if (BE->getOpcode() == MCBinaryExpr::Sub) 1270 Addend = -Addend; 1271 1272 // It's some symbol reference + a constant addend 1273 return Kind != RISCVMCExpr::VK_RISCV_Invalid; 1274 } 1275 1276 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) { 1277 // This returns false if this function recognizes the directive 1278 // regardless of whether it is successfully handles or reports an 1279 // error. Otherwise it returns true to give the generic parser a 1280 // chance at recognizing it. 1281 StringRef IDVal = DirectiveID.getString(); 1282 1283 if (IDVal == ".option") 1284 return parseDirectiveOption(); 1285 1286 return true; 1287 } 1288 1289 bool RISCVAsmParser::parseDirectiveOption() { 1290 MCAsmParser &Parser = getParser(); 1291 // Get the option token. 1292 AsmToken Tok = Parser.getTok(); 1293 // At the moment only identifiers are supported. 1294 if (Tok.isNot(AsmToken::Identifier)) 1295 return Error(Parser.getTok().getLoc(), 1296 "unexpected token, expected identifier"); 1297 1298 StringRef Option = Tok.getIdentifier(); 1299 1300 if (Option == "push") { 1301 getTargetStreamer().emitDirectiveOptionPush(); 1302 1303 Parser.Lex(); 1304 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1305 return Error(Parser.getTok().getLoc(), 1306 "unexpected token, expected end of statement"); 1307 1308 pushFeatureBits(); 1309 return false; 1310 } 1311 1312 if (Option == "pop") { 1313 SMLoc StartLoc = Parser.getTok().getLoc(); 1314 getTargetStreamer().emitDirectiveOptionPop(); 1315 1316 Parser.Lex(); 1317 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1318 return Error(Parser.getTok().getLoc(), 1319 "unexpected token, expected end of statement"); 1320 1321 if (popFeatureBits()) 1322 return Error(StartLoc, ".option pop with no .option push"); 1323 1324 return false; 1325 } 1326 1327 if (Option == "rvc") { 1328 getTargetStreamer().emitDirectiveOptionRVC(); 1329 1330 Parser.Lex(); 1331 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1332 return Error(Parser.getTok().getLoc(), 1333 "unexpected token, expected end of statement"); 1334 1335 setFeatureBits(RISCV::FeatureStdExtC, "c"); 1336 return false; 1337 } 1338 1339 if (Option == "norvc") { 1340 getTargetStreamer().emitDirectiveOptionNoRVC(); 1341 1342 Parser.Lex(); 1343 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1344 return Error(Parser.getTok().getLoc(), 1345 "unexpected token, expected end of statement"); 1346 1347 clearFeatureBits(RISCV::FeatureStdExtC, "c"); 1348 return false; 1349 } 1350 1351 if (Option == "relax") { 1352 getTargetStreamer().emitDirectiveOptionRelax(); 1353 1354 Parser.Lex(); 1355 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1356 return Error(Parser.getTok().getLoc(), 1357 "unexpected token, expected end of statement"); 1358 1359 setFeatureBits(RISCV::FeatureRelax, "relax"); 1360 return false; 1361 } 1362 1363 if (Option == "norelax") { 1364 getTargetStreamer().emitDirectiveOptionNoRelax(); 1365 1366 Parser.Lex(); 1367 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1368 return Error(Parser.getTok().getLoc(), 1369 "unexpected token, expected end of statement"); 1370 1371 clearFeatureBits(RISCV::FeatureRelax, "relax"); 1372 return false; 1373 } 1374 1375 // Unknown option. 1376 Warning(Parser.getTok().getLoc(), 1377 "unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'relax' or " 1378 "'norelax'"); 1379 Parser.eatToEndOfStatement(); 1380 return false; 1381 } 1382 1383 void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { 1384 MCInst CInst; 1385 bool Res = compressInst(CInst, Inst, getSTI(), S.getContext()); 1386 CInst.setLoc(Inst.getLoc()); 1387 S.EmitInstruction((Res ? CInst : Inst), getSTI()); 1388 } 1389 1390 void RISCVAsmParser::emitLoadImm(unsigned DestReg, int64_t Value, 1391 MCStreamer &Out) { 1392 RISCVMatInt::InstSeq Seq; 1393 RISCVMatInt::generateInstSeq(Value, isRV64(), Seq); 1394 1395 unsigned SrcReg = RISCV::X0; 1396 for (RISCVMatInt::Inst &Inst : Seq) { 1397 if (Inst.Opc == RISCV::LUI) { 1398 emitToStreamer( 1399 Out, MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Inst.Imm)); 1400 } else { 1401 emitToStreamer( 1402 Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm( 1403 Inst.Imm)); 1404 } 1405 1406 // Only the first instruction has X0 as its source. 1407 SrcReg = DestReg; 1408 } 1409 } 1410 1411 void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, 1412 MCStreamer &Out) { 1413 // The local load address pseudo-instruction "lla" is used in PC-relative 1414 // addressing of symbols: 1415 // lla rdest, symbol 1416 // expands to 1417 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) 1418 // ADDI rdest, %pcrel_lo(TmpLabel) 1419 MCContext &Ctx = getContext(); 1420 1421 MCSymbol *TmpLabel = Ctx.createTempSymbol( 1422 "pcrel_hi", /* AlwaysAddSuffix */ true, /* CanBeUnnamed */ false); 1423 Out.EmitLabel(TmpLabel); 1424 1425 MCOperand DestReg = Inst.getOperand(0); 1426 const RISCVMCExpr *Symbol = RISCVMCExpr::create( 1427 Inst.getOperand(1).getExpr(), RISCVMCExpr::VK_RISCV_PCREL_HI, Ctx); 1428 1429 emitToStreamer( 1430 Out, MCInstBuilder(RISCV::AUIPC).addOperand(DestReg).addExpr(Symbol)); 1431 1432 const MCExpr *RefToLinkTmpLabel = 1433 RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx), 1434 RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx); 1435 1436 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI) 1437 .addOperand(DestReg) 1438 .addOperand(DestReg) 1439 .addExpr(RefToLinkTmpLabel)); 1440 } 1441 1442 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 1443 MCStreamer &Out) { 1444 Inst.setLoc(IDLoc); 1445 1446 if (Inst.getOpcode() == RISCV::PseudoLI) { 1447 unsigned Reg = Inst.getOperand(0).getReg(); 1448 const MCOperand &Op1 = Inst.getOperand(1); 1449 if (Op1.isExpr()) { 1450 // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar. 1451 // Just convert to an addi. This allows compatibility with gas. 1452 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI) 1453 .addReg(Reg) 1454 .addReg(RISCV::X0) 1455 .addExpr(Op1.getExpr())); 1456 return false; 1457 } 1458 int64_t Imm = Inst.getOperand(1).getImm(); 1459 // On RV32 the immediate here can either be a signed or an unsigned 1460 // 32-bit number. Sign extension has to be performed to ensure that Imm 1461 // represents the expected signed 64-bit number. 1462 if (!isRV64()) 1463 Imm = SignExtend64<32>(Imm); 1464 emitLoadImm(Reg, Imm, Out); 1465 return false; 1466 } else if (Inst.getOpcode() == RISCV::PseudoLLA) { 1467 emitLoadLocalAddress(Inst, IDLoc, Out); 1468 return false; 1469 } 1470 1471 emitToStreamer(Out, Inst); 1472 return false; 1473 } 1474 1475 extern "C" void LLVMInitializeRISCVAsmParser() { 1476 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target()); 1477 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target()); 1478 } 1479