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