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