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