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