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/RISCVBaseInfo.h" 11 #include "MCTargetDesc/RISCVInstPrinter.h" 12 #include "MCTargetDesc/RISCVMCExpr.h" 13 #include "MCTargetDesc/RISCVMCTargetDesc.h" 14 #include "MCTargetDesc/RISCVMatInt.h" 15 #include "MCTargetDesc/RISCVTargetStreamer.h" 16 #include "TargetInfo/RISCVTargetInfo.h" 17 #include "llvm/ADT/STLExtras.h" 18 #include "llvm/ADT/SmallBitVector.h" 19 #include "llvm/ADT/SmallString.h" 20 #include "llvm/ADT/SmallVector.h" 21 #include "llvm/ADT/Statistic.h" 22 #include "llvm/MC/MCAssembler.h" 23 #include "llvm/MC/MCContext.h" 24 #include "llvm/MC/MCExpr.h" 25 #include "llvm/MC/MCInst.h" 26 #include "llvm/MC/MCInstBuilder.h" 27 #include "llvm/MC/MCObjectFileInfo.h" 28 #include "llvm/MC/MCParser/MCAsmLexer.h" 29 #include "llvm/MC/MCParser/MCParsedAsmOperand.h" 30 #include "llvm/MC/MCParser/MCTargetAsmParser.h" 31 #include "llvm/MC/MCRegisterInfo.h" 32 #include "llvm/MC/MCStreamer.h" 33 #include "llvm/MC/MCSubtargetInfo.h" 34 #include "llvm/MC/MCValue.h" 35 #include "llvm/MC/TargetRegistry.h" 36 #include "llvm/Support/Casting.h" 37 #include "llvm/Support/MathExtras.h" 38 #include "llvm/Support/RISCVAttributes.h" 39 #include "llvm/Support/RISCVISAInfo.h" 40 41 #include <limits> 42 43 using namespace llvm; 44 45 #define DEBUG_TYPE "riscv-asm-parser" 46 47 // Include the auto-generated portion of the compress emitter. 48 #define GEN_COMPRESS_INSTR 49 #include "RISCVGenCompressInstEmitter.inc" 50 51 STATISTIC(RISCVNumInstrsCompressed, 52 "Number of RISC-V Compressed instructions emitted"); 53 54 namespace llvm { 55 extern const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures]; 56 } // namespace llvm 57 58 namespace { 59 struct RISCVOperand; 60 61 struct ParserOptionsSet { 62 bool IsPicEnabled; 63 }; 64 65 class RISCVAsmParser : public MCTargetAsmParser { 66 SmallVector<FeatureBitset, 4> FeatureBitStack; 67 68 SmallVector<ParserOptionsSet, 4> ParserOptionsStack; 69 ParserOptionsSet ParserOptions; 70 71 SMLoc getLoc() const { return getParser().getTok().getLoc(); } 72 bool isRV64() const { return getSTI().hasFeature(RISCV::Feature64Bit); } 73 bool isRV32E() const { return getSTI().hasFeature(RISCV::FeatureRV32E); } 74 75 RISCVTargetStreamer &getTargetStreamer() { 76 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer(); 77 return static_cast<RISCVTargetStreamer &>(TS); 78 } 79 80 unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, 81 unsigned Kind) override; 82 83 bool generateImmOutOfRangeError(OperandVector &Operands, uint64_t ErrorInfo, 84 int64_t Lower, int64_t Upper, Twine Msg); 85 86 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 87 OperandVector &Operands, MCStreamer &Out, 88 uint64_t &ErrorInfo, 89 bool MatchingInlineAsm) override; 90 91 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override; 92 OperandMatchResultTy tryParseRegister(unsigned &RegNo, SMLoc &StartLoc, 93 SMLoc &EndLoc) override; 94 95 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 96 SMLoc NameLoc, OperandVector &Operands) override; 97 98 bool ParseDirective(AsmToken DirectiveID) override; 99 100 // Helper to actually emit an instruction to the MCStreamer. Also, when 101 // possible, compression of the instruction is performed. 102 void emitToStreamer(MCStreamer &S, const MCInst &Inst); 103 104 // Helper to emit a combination of LUI, ADDI(W), and SLLI instructions that 105 // synthesize the desired immedate value into the destination register. 106 void emitLoadImm(MCRegister DestReg, int64_t Value, MCStreamer &Out); 107 108 // Helper to emit a combination of AUIPC and SecondOpcode. Used to implement 109 // helpers such as emitLoadLocalAddress and emitLoadAddress. 110 void emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg, 111 const MCExpr *Symbol, RISCVMCExpr::VariantKind VKHi, 112 unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out); 113 114 // Helper to emit pseudo instruction "lla" used in PC-rel addressing. 115 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 116 117 // Helper to emit pseudo instruction "la" used in GOT/PC-rel addressing. 118 void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 119 120 // Helper to emit pseudo instruction "la.tls.ie" used in initial-exec TLS 121 // addressing. 122 void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 123 124 // Helper to emit pseudo instruction "la.tls.gd" used in global-dynamic TLS 125 // addressing. 126 void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out); 127 128 // Helper to emit pseudo load/store instruction with a symbol. 129 void emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, 130 MCStreamer &Out, bool HasTmpReg); 131 132 // Helper to emit pseudo sign/zero extend instruction. 133 void emitPseudoExtend(MCInst &Inst, bool SignExtend, int64_t Width, 134 SMLoc IDLoc, MCStreamer &Out); 135 136 // Helper to emit pseudo vmsge{u}.vx instruction. 137 void emitVMSGE(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, MCStreamer &Out); 138 139 // Checks that a PseudoAddTPRel is using x4/tp in its second input operand. 140 // Enforcing this using a restricted register class for the second input 141 // operand of PseudoAddTPRel results in a poor diagnostic due to the fact 142 // 'add' is an overloaded mnemonic. 143 bool checkPseudoAddTPRel(MCInst &Inst, OperandVector &Operands); 144 145 // Check instruction constraints. 146 bool validateInstruction(MCInst &Inst, OperandVector &Operands); 147 148 /// Helper for processing MC instructions that have been successfully matched 149 /// by MatchAndEmitInstruction. Modifications to the emitted instructions, 150 /// like the expansion of pseudo instructions (e.g., "li"), can be performed 151 /// in this method. 152 bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands, 153 MCStreamer &Out); 154 155 // Auto-generated instruction matching functions 156 #define GET_ASSEMBLER_HEADER 157 #include "RISCVGenAsmMatcher.inc" 158 159 OperandMatchResultTy parseCSRSystemRegister(OperandVector &Operands); 160 OperandMatchResultTy parseImmediate(OperandVector &Operands); 161 OperandMatchResultTy parseRegister(OperandVector &Operands, 162 bool AllowParens = false); 163 OperandMatchResultTy parseMemOpBaseReg(OperandVector &Operands); 164 OperandMatchResultTy parseAtomicMemOp(OperandVector &Operands); 165 OperandMatchResultTy parseOperandWithModifier(OperandVector &Operands); 166 OperandMatchResultTy parseBareSymbol(OperandVector &Operands); 167 OperandMatchResultTy parseCallSymbol(OperandVector &Operands); 168 OperandMatchResultTy parsePseudoJumpSymbol(OperandVector &Operands); 169 OperandMatchResultTy parseJALOffset(OperandVector &Operands); 170 OperandMatchResultTy parseVTypeI(OperandVector &Operands); 171 OperandMatchResultTy parseMaskReg(OperandVector &Operands); 172 173 bool parseOperand(OperandVector &Operands, StringRef Mnemonic); 174 175 bool parseDirectiveOption(); 176 bool parseDirectiveAttribute(); 177 bool parseDirectiveInsn(SMLoc L); 178 179 void setFeatureBits(uint64_t Feature, StringRef FeatureString) { 180 if (!(getSTI().getFeatureBits()[Feature])) { 181 MCSubtargetInfo &STI = copySTI(); 182 setAvailableFeatures( 183 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 184 } 185 } 186 187 bool getFeatureBits(uint64_t Feature) { 188 return getSTI().getFeatureBits()[Feature]; 189 } 190 191 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) { 192 if (getSTI().getFeatureBits()[Feature]) { 193 MCSubtargetInfo &STI = copySTI(); 194 setAvailableFeatures( 195 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString))); 196 } 197 } 198 199 void pushFeatureBits() { 200 assert(FeatureBitStack.size() == ParserOptionsStack.size() && 201 "These two stacks must be kept synchronized"); 202 FeatureBitStack.push_back(getSTI().getFeatureBits()); 203 ParserOptionsStack.push_back(ParserOptions); 204 } 205 206 bool popFeatureBits() { 207 assert(FeatureBitStack.size() == ParserOptionsStack.size() && 208 "These two stacks must be kept synchronized"); 209 if (FeatureBitStack.empty()) 210 return true; 211 212 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val(); 213 copySTI().setFeatureBits(FeatureBits); 214 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits)); 215 216 ParserOptions = ParserOptionsStack.pop_back_val(); 217 218 return false; 219 } 220 221 std::unique_ptr<RISCVOperand> defaultMaskRegOp() const; 222 223 public: 224 enum RISCVMatchResultTy { 225 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY, 226 #define GET_OPERAND_DIAGNOSTIC_TYPES 227 #include "RISCVGenAsmMatcher.inc" 228 #undef GET_OPERAND_DIAGNOSTIC_TYPES 229 }; 230 231 static bool classifySymbolRef(const MCExpr *Expr, 232 RISCVMCExpr::VariantKind &Kind); 233 234 RISCVAsmParser(const MCSubtargetInfo &STI, MCAsmParser &Parser, 235 const MCInstrInfo &MII, const MCTargetOptions &Options) 236 : MCTargetAsmParser(Options, STI, MII) { 237 Parser.addAliasForDirective(".half", ".2byte"); 238 Parser.addAliasForDirective(".hword", ".2byte"); 239 Parser.addAliasForDirective(".word", ".4byte"); 240 Parser.addAliasForDirective(".dword", ".8byte"); 241 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 242 243 auto ABIName = StringRef(Options.ABIName); 244 if (ABIName.endswith("f") && 245 !getSTI().getFeatureBits()[RISCV::FeatureStdExtF]) { 246 errs() << "Hard-float 'f' ABI can't be used for a target that " 247 "doesn't support the F instruction set extension (ignoring " 248 "target-abi)\n"; 249 } else if (ABIName.endswith("d") && 250 !getSTI().getFeatureBits()[RISCV::FeatureStdExtD]) { 251 errs() << "Hard-float 'd' ABI can't be used for a target that " 252 "doesn't support the D instruction set extension (ignoring " 253 "target-abi)\n"; 254 } 255 256 const MCObjectFileInfo *MOFI = Parser.getContext().getObjectFileInfo(); 257 ParserOptions.IsPicEnabled = MOFI->isPositionIndependent(); 258 } 259 }; 260 261 /// RISCVOperand - Instances of this class represent a parsed machine 262 /// instruction 263 struct RISCVOperand : public MCParsedAsmOperand { 264 265 enum class KindTy { 266 Token, 267 Register, 268 Immediate, 269 SystemRegister, 270 VType, 271 } Kind; 272 273 bool IsRV64; 274 275 struct RegOp { 276 MCRegister RegNum; 277 }; 278 279 struct ImmOp { 280 const MCExpr *Val; 281 }; 282 283 struct SysRegOp { 284 const char *Data; 285 unsigned Length; 286 unsigned Encoding; 287 // FIXME: Add the Encoding parsed fields as needed for checks, 288 // e.g.: read/write or user/supervisor/machine privileges. 289 }; 290 291 struct VTypeOp { 292 unsigned Val; 293 }; 294 295 SMLoc StartLoc, EndLoc; 296 union { 297 StringRef Tok; 298 RegOp Reg; 299 ImmOp Imm; 300 struct SysRegOp SysReg; 301 struct VTypeOp VType; 302 }; 303 304 RISCVOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 305 306 public: 307 RISCVOperand(const RISCVOperand &o) : MCParsedAsmOperand() { 308 Kind = o.Kind; 309 IsRV64 = o.IsRV64; 310 StartLoc = o.StartLoc; 311 EndLoc = o.EndLoc; 312 switch (Kind) { 313 case KindTy::Register: 314 Reg = o.Reg; 315 break; 316 case KindTy::Immediate: 317 Imm = o.Imm; 318 break; 319 case KindTy::Token: 320 Tok = o.Tok; 321 break; 322 case KindTy::SystemRegister: 323 SysReg = o.SysReg; 324 break; 325 case KindTy::VType: 326 VType = o.VType; 327 break; 328 } 329 } 330 331 bool isToken() const override { return Kind == KindTy::Token; } 332 bool isReg() const override { return Kind == KindTy::Register; } 333 bool isV0Reg() const { 334 return Kind == KindTy::Register && Reg.RegNum == RISCV::V0; 335 } 336 bool isImm() const override { return Kind == KindTy::Immediate; } 337 bool isMem() const override { return false; } 338 bool isSystemRegister() const { return Kind == KindTy::SystemRegister; } 339 bool isVType() const { return Kind == KindTy::VType; } 340 341 bool isGPR() const { 342 return Kind == KindTy::Register && 343 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(Reg.RegNum); 344 } 345 346 static bool evaluateConstantImm(const MCExpr *Expr, int64_t &Imm, 347 RISCVMCExpr::VariantKind &VK) { 348 if (auto *RE = dyn_cast<RISCVMCExpr>(Expr)) { 349 VK = RE->getKind(); 350 return RE->evaluateAsConstant(Imm); 351 } 352 353 if (auto CE = dyn_cast<MCConstantExpr>(Expr)) { 354 VK = RISCVMCExpr::VK_RISCV_None; 355 Imm = CE->getValue(); 356 return true; 357 } 358 359 return false; 360 } 361 362 // True if operand is a symbol with no modifiers, or a constant with no 363 // modifiers and isShiftedInt<N-1, 1>(Op). 364 template <int N> bool isBareSimmNLsb0() const { 365 int64_t Imm; 366 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 367 if (!isImm()) 368 return false; 369 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 370 bool IsValid; 371 if (!IsConstantImm) 372 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK); 373 else 374 IsValid = isShiftedInt<N - 1, 1>(Imm); 375 return IsValid && VK == RISCVMCExpr::VK_RISCV_None; 376 } 377 378 // Predicate methods for AsmOperands defined in RISCVInstrInfo.td 379 380 bool isBareSymbol() const { 381 int64_t Imm; 382 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 383 // Must be of 'immediate' type but not a constant. 384 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 385 return false; 386 return RISCVAsmParser::classifySymbolRef(getImm(), VK) && 387 VK == RISCVMCExpr::VK_RISCV_None; 388 } 389 390 bool isCallSymbol() const { 391 int64_t Imm; 392 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 393 // Must be of 'immediate' type but not a constant. 394 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 395 return false; 396 return RISCVAsmParser::classifySymbolRef(getImm(), VK) && 397 (VK == RISCVMCExpr::VK_RISCV_CALL || 398 VK == RISCVMCExpr::VK_RISCV_CALL_PLT); 399 } 400 401 bool isPseudoJumpSymbol() const { 402 int64_t Imm; 403 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 404 // Must be of 'immediate' type but not a constant. 405 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 406 return false; 407 return RISCVAsmParser::classifySymbolRef(getImm(), VK) && 408 VK == RISCVMCExpr::VK_RISCV_CALL; 409 } 410 411 bool isTPRelAddSymbol() const { 412 int64_t Imm; 413 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 414 // Must be of 'immediate' type but not a constant. 415 if (!isImm() || evaluateConstantImm(getImm(), Imm, VK)) 416 return false; 417 return RISCVAsmParser::classifySymbolRef(getImm(), VK) && 418 VK == RISCVMCExpr::VK_RISCV_TPREL_ADD; 419 } 420 421 bool isCSRSystemRegister() const { return isSystemRegister(); } 422 423 bool isVTypeI() const { return isVType(); } 424 425 /// Return true if the operand is a valid for the fence instruction e.g. 426 /// ('iorw'). 427 bool isFenceArg() const { 428 if (!isImm()) 429 return false; 430 const MCExpr *Val = getImm(); 431 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val); 432 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None) 433 return false; 434 435 StringRef Str = SVal->getSymbol().getName(); 436 // Letters must be unique, taken from 'iorw', and in ascending order. This 437 // holds as long as each individual character is one of 'iorw' and is 438 // greater than the previous character. 439 char Prev = '\0'; 440 for (char c : Str) { 441 if (c != 'i' && c != 'o' && c != 'r' && c != 'w') 442 return false; 443 if (c <= Prev) 444 return false; 445 Prev = c; 446 } 447 return true; 448 } 449 450 /// Return true if the operand is a valid floating point rounding mode. 451 bool isFRMArg() const { 452 if (!isImm()) 453 return false; 454 const MCExpr *Val = getImm(); 455 auto *SVal = dyn_cast<MCSymbolRefExpr>(Val); 456 if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None) 457 return false; 458 459 StringRef Str = SVal->getSymbol().getName(); 460 461 return RISCVFPRndMode::stringToRoundingMode(Str) != RISCVFPRndMode::Invalid; 462 } 463 464 bool isImmXLenLI() const { 465 int64_t Imm; 466 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 467 if (!isImm()) 468 return false; 469 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 470 if (VK == RISCVMCExpr::VK_RISCV_LO || VK == RISCVMCExpr::VK_RISCV_PCREL_LO) 471 return true; 472 // Given only Imm, ensuring that the actually specified constant is either 473 // a signed or unsigned 64-bit number is unfortunately impossible. 474 return IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None && 475 (isRV64() || (isInt<32>(Imm) || isUInt<32>(Imm))); 476 } 477 478 bool isUImmLog2XLen() const { 479 int64_t Imm; 480 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 481 if (!isImm()) 482 return false; 483 if (!evaluateConstantImm(getImm(), Imm, VK) || 484 VK != RISCVMCExpr::VK_RISCV_None) 485 return false; 486 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm); 487 } 488 489 bool isUImmLog2XLenNonZero() const { 490 int64_t Imm; 491 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 492 if (!isImm()) 493 return false; 494 if (!evaluateConstantImm(getImm(), Imm, VK) || 495 VK != RISCVMCExpr::VK_RISCV_None) 496 return false; 497 if (Imm == 0) 498 return false; 499 return (isRV64() && isUInt<6>(Imm)) || isUInt<5>(Imm); 500 } 501 502 bool isUImmLog2XLenHalf() const { 503 int64_t Imm; 504 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 505 if (!isImm()) 506 return false; 507 if (!evaluateConstantImm(getImm(), Imm, VK) || 508 VK != RISCVMCExpr::VK_RISCV_None) 509 return false; 510 return (isRV64() && isUInt<5>(Imm)) || isUInt<4>(Imm); 511 } 512 513 bool isUImm2() const { 514 int64_t Imm; 515 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 516 if (!isImm()) 517 return false; 518 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 519 return IsConstantImm && isUInt<2>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; 520 } 521 522 bool isUImm3() const { 523 int64_t Imm; 524 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 525 if (!isImm()) 526 return false; 527 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 528 return IsConstantImm && isUInt<3>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; 529 } 530 531 bool isUImm5() const { 532 int64_t Imm; 533 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 534 if (!isImm()) 535 return false; 536 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 537 return IsConstantImm && isUInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; 538 } 539 540 bool isUImm7() const { 541 int64_t Imm; 542 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 543 if (!isImm()) 544 return false; 545 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 546 return IsConstantImm && isUInt<7>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; 547 } 548 549 bool isSImm5() const { 550 if (!isImm()) 551 return false; 552 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 553 int64_t Imm; 554 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 555 return IsConstantImm && isInt<5>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; 556 } 557 558 bool isSImm6() const { 559 if (!isImm()) 560 return false; 561 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 562 int64_t Imm; 563 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 564 return IsConstantImm && isInt<6>(Imm) && VK == RISCVMCExpr::VK_RISCV_None; 565 } 566 567 bool isSImm6NonZero() const { 568 if (!isImm()) 569 return false; 570 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 571 int64_t Imm; 572 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 573 return IsConstantImm && isInt<6>(Imm) && (Imm != 0) && 574 VK == RISCVMCExpr::VK_RISCV_None; 575 } 576 577 bool isCLUIImm() const { 578 if (!isImm()) 579 return false; 580 int64_t Imm; 581 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 582 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 583 return IsConstantImm && (Imm != 0) && 584 (isUInt<5>(Imm) || (Imm >= 0xfffe0 && Imm <= 0xfffff)) && 585 VK == RISCVMCExpr::VK_RISCV_None; 586 } 587 588 bool isUImm7Lsb00() const { 589 if (!isImm()) 590 return false; 591 int64_t Imm; 592 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 593 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 594 return IsConstantImm && isShiftedUInt<5, 2>(Imm) && 595 VK == RISCVMCExpr::VK_RISCV_None; 596 } 597 598 bool isUImm8Lsb00() const { 599 if (!isImm()) 600 return false; 601 int64_t Imm; 602 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 603 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 604 return IsConstantImm && isShiftedUInt<6, 2>(Imm) && 605 VK == RISCVMCExpr::VK_RISCV_None; 606 } 607 608 bool isUImm8Lsb000() const { 609 if (!isImm()) 610 return false; 611 int64_t Imm; 612 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 613 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 614 return IsConstantImm && isShiftedUInt<5, 3>(Imm) && 615 VK == RISCVMCExpr::VK_RISCV_None; 616 } 617 618 bool isSImm9Lsb0() const { return isBareSimmNLsb0<9>(); } 619 620 bool isUImm9Lsb000() const { 621 if (!isImm()) 622 return false; 623 int64_t Imm; 624 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 625 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 626 return IsConstantImm && isShiftedUInt<6, 3>(Imm) && 627 VK == RISCVMCExpr::VK_RISCV_None; 628 } 629 630 bool isUImm10Lsb00NonZero() const { 631 if (!isImm()) 632 return false; 633 int64_t Imm; 634 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 635 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 636 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (Imm != 0) && 637 VK == RISCVMCExpr::VK_RISCV_None; 638 } 639 640 bool isSImm12() const { 641 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 642 int64_t Imm; 643 bool IsValid; 644 if (!isImm()) 645 return false; 646 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 647 if (!IsConstantImm) 648 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK); 649 else 650 IsValid = isInt<12>(Imm); 651 return IsValid && ((IsConstantImm && VK == RISCVMCExpr::VK_RISCV_None) || 652 VK == RISCVMCExpr::VK_RISCV_LO || 653 VK == RISCVMCExpr::VK_RISCV_PCREL_LO || 654 VK == RISCVMCExpr::VK_RISCV_TPREL_LO); 655 } 656 657 bool isSImm12Lsb0() const { return isBareSimmNLsb0<12>(); } 658 659 bool isSImm13Lsb0() const { return isBareSimmNLsb0<13>(); } 660 661 bool isSImm10Lsb0000NonZero() const { 662 if (!isImm()) 663 return false; 664 int64_t Imm; 665 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 666 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 667 return IsConstantImm && (Imm != 0) && isShiftedInt<6, 4>(Imm) && 668 VK == RISCVMCExpr::VK_RISCV_None; 669 } 670 671 bool isUImm20LUI() const { 672 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 673 int64_t Imm; 674 bool IsValid; 675 if (!isImm()) 676 return false; 677 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 678 if (!IsConstantImm) { 679 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK); 680 return IsValid && (VK == RISCVMCExpr::VK_RISCV_HI || 681 VK == RISCVMCExpr::VK_RISCV_TPREL_HI); 682 } else { 683 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None || 684 VK == RISCVMCExpr::VK_RISCV_HI || 685 VK == RISCVMCExpr::VK_RISCV_TPREL_HI); 686 } 687 } 688 689 bool isUImm20AUIPC() const { 690 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 691 int64_t Imm; 692 bool IsValid; 693 if (!isImm()) 694 return false; 695 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 696 if (!IsConstantImm) { 697 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK); 698 return IsValid && (VK == RISCVMCExpr::VK_RISCV_PCREL_HI || 699 VK == RISCVMCExpr::VK_RISCV_GOT_HI || 700 VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI || 701 VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI); 702 } else { 703 return isUInt<20>(Imm) && (VK == RISCVMCExpr::VK_RISCV_None || 704 VK == RISCVMCExpr::VK_RISCV_PCREL_HI || 705 VK == RISCVMCExpr::VK_RISCV_GOT_HI || 706 VK == RISCVMCExpr::VK_RISCV_TLS_GOT_HI || 707 VK == RISCVMCExpr::VK_RISCV_TLS_GD_HI); 708 } 709 } 710 711 bool isSImm21Lsb0JAL() const { return isBareSimmNLsb0<21>(); } 712 713 bool isImmZero() const { 714 if (!isImm()) 715 return false; 716 int64_t Imm; 717 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 718 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 719 return IsConstantImm && (Imm == 0) && VK == RISCVMCExpr::VK_RISCV_None; 720 } 721 722 bool isSImm5Plus1() const { 723 if (!isImm()) 724 return false; 725 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 726 int64_t Imm; 727 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK); 728 return IsConstantImm && isInt<5>(Imm - 1) && 729 VK == RISCVMCExpr::VK_RISCV_None; 730 } 731 732 /// getStartLoc - Gets location of the first token of this operand 733 SMLoc getStartLoc() const override { return StartLoc; } 734 /// getEndLoc - Gets location of the last token of this operand 735 SMLoc getEndLoc() const override { return EndLoc; } 736 /// True if this operand is for an RV64 instruction 737 bool isRV64() const { return IsRV64; } 738 739 unsigned getReg() const override { 740 assert(Kind == KindTy::Register && "Invalid type access!"); 741 return Reg.RegNum.id(); 742 } 743 744 StringRef getSysReg() const { 745 assert(Kind == KindTy::SystemRegister && "Invalid type access!"); 746 return StringRef(SysReg.Data, SysReg.Length); 747 } 748 749 const MCExpr *getImm() const { 750 assert(Kind == KindTy::Immediate && "Invalid type access!"); 751 return Imm.Val; 752 } 753 754 StringRef getToken() const { 755 assert(Kind == KindTy::Token && "Invalid type access!"); 756 return Tok; 757 } 758 759 unsigned getVType() const { 760 assert(Kind == KindTy::VType && "Invalid type access!"); 761 return VType.Val; 762 } 763 764 void print(raw_ostream &OS) const override { 765 auto RegName = [](unsigned Reg) { 766 if (Reg) 767 return RISCVInstPrinter::getRegisterName(Reg); 768 else 769 return "noreg"; 770 }; 771 772 switch (Kind) { 773 case KindTy::Immediate: 774 OS << *getImm(); 775 break; 776 case KindTy::Register: 777 OS << "<register " << RegName(getReg()) << ">"; 778 break; 779 case KindTy::Token: 780 OS << "'" << getToken() << "'"; 781 break; 782 case KindTy::SystemRegister: 783 OS << "<sysreg: " << getSysReg() << '>'; 784 break; 785 case KindTy::VType: 786 OS << "<vtype: "; 787 RISCVVType::printVType(getVType(), OS); 788 OS << '>'; 789 break; 790 } 791 } 792 793 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S, 794 bool IsRV64) { 795 auto Op = std::make_unique<RISCVOperand>(KindTy::Token); 796 Op->Tok = Str; 797 Op->StartLoc = S; 798 Op->EndLoc = S; 799 Op->IsRV64 = IsRV64; 800 return Op; 801 } 802 803 static std::unique_ptr<RISCVOperand> createReg(unsigned RegNo, SMLoc S, 804 SMLoc E, bool IsRV64) { 805 auto Op = std::make_unique<RISCVOperand>(KindTy::Register); 806 Op->Reg.RegNum = RegNo; 807 Op->StartLoc = S; 808 Op->EndLoc = E; 809 Op->IsRV64 = IsRV64; 810 return Op; 811 } 812 813 static std::unique_ptr<RISCVOperand> createImm(const MCExpr *Val, SMLoc S, 814 SMLoc E, bool IsRV64) { 815 auto Op = std::make_unique<RISCVOperand>(KindTy::Immediate); 816 Op->Imm.Val = Val; 817 Op->StartLoc = S; 818 Op->EndLoc = E; 819 Op->IsRV64 = IsRV64; 820 return Op; 821 } 822 823 static std::unique_ptr<RISCVOperand> 824 createSysReg(StringRef Str, SMLoc S, unsigned Encoding, bool IsRV64) { 825 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister); 826 Op->SysReg.Data = Str.data(); 827 Op->SysReg.Length = Str.size(); 828 Op->SysReg.Encoding = Encoding; 829 Op->StartLoc = S; 830 Op->IsRV64 = IsRV64; 831 return Op; 832 } 833 834 static std::unique_ptr<RISCVOperand> createVType(unsigned VTypeI, SMLoc S, 835 bool IsRV64) { 836 auto Op = std::make_unique<RISCVOperand>(KindTy::VType); 837 Op->VType.Val = VTypeI; 838 Op->StartLoc = S; 839 Op->IsRV64 = IsRV64; 840 return Op; 841 } 842 843 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 844 assert(Expr && "Expr shouldn't be null!"); 845 int64_t Imm = 0; 846 RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None; 847 bool IsConstant = evaluateConstantImm(Expr, Imm, VK); 848 849 if (IsConstant) 850 Inst.addOperand(MCOperand::createImm(Imm)); 851 else 852 Inst.addOperand(MCOperand::createExpr(Expr)); 853 } 854 855 // Used by the TableGen Code 856 void addRegOperands(MCInst &Inst, unsigned N) const { 857 assert(N == 1 && "Invalid number of operands!"); 858 Inst.addOperand(MCOperand::createReg(getReg())); 859 } 860 861 void addImmOperands(MCInst &Inst, unsigned N) const { 862 assert(N == 1 && "Invalid number of operands!"); 863 addExpr(Inst, getImm()); 864 } 865 866 void addFenceArgOperands(MCInst &Inst, unsigned N) const { 867 assert(N == 1 && "Invalid number of operands!"); 868 // isFenceArg has validated the operand, meaning this cast is safe 869 auto SE = cast<MCSymbolRefExpr>(getImm()); 870 871 unsigned Imm = 0; 872 for (char c : SE->getSymbol().getName()) { 873 switch (c) { 874 default: 875 llvm_unreachable("FenceArg must contain only [iorw]"); 876 case 'i': 877 Imm |= RISCVFenceField::I; 878 break; 879 case 'o': 880 Imm |= RISCVFenceField::O; 881 break; 882 case 'r': 883 Imm |= RISCVFenceField::R; 884 break; 885 case 'w': 886 Imm |= RISCVFenceField::W; 887 break; 888 } 889 } 890 Inst.addOperand(MCOperand::createImm(Imm)); 891 } 892 893 void addCSRSystemRegisterOperands(MCInst &Inst, unsigned N) const { 894 assert(N == 1 && "Invalid number of operands!"); 895 Inst.addOperand(MCOperand::createImm(SysReg.Encoding)); 896 } 897 898 void addVTypeIOperands(MCInst &Inst, unsigned N) const { 899 assert(N == 1 && "Invalid number of operands!"); 900 Inst.addOperand(MCOperand::createImm(getVType())); 901 } 902 903 // Returns the rounding mode represented by this RISCVOperand. Should only 904 // be called after checking isFRMArg. 905 RISCVFPRndMode::RoundingMode getRoundingMode() const { 906 // isFRMArg has validated the operand, meaning this cast is safe. 907 auto SE = cast<MCSymbolRefExpr>(getImm()); 908 RISCVFPRndMode::RoundingMode FRM = 909 RISCVFPRndMode::stringToRoundingMode(SE->getSymbol().getName()); 910 assert(FRM != RISCVFPRndMode::Invalid && "Invalid rounding mode"); 911 return FRM; 912 } 913 914 void addFRMArgOperands(MCInst &Inst, unsigned N) const { 915 assert(N == 1 && "Invalid number of operands!"); 916 Inst.addOperand(MCOperand::createImm(getRoundingMode())); 917 } 918 }; 919 } // end anonymous namespace. 920 921 #define GET_REGISTER_MATCHER 922 #define GET_SUBTARGET_FEATURE_NAME 923 #define GET_MATCHER_IMPLEMENTATION 924 #define GET_MNEMONIC_SPELL_CHECKER 925 #include "RISCVGenAsmMatcher.inc" 926 927 static MCRegister convertFPR64ToFPR16(MCRegister Reg) { 928 assert(Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && "Invalid register"); 929 return Reg - RISCV::F0_D + RISCV::F0_H; 930 } 931 932 static MCRegister convertFPR64ToFPR32(MCRegister Reg) { 933 assert(Reg >= RISCV::F0_D && Reg <= RISCV::F31_D && "Invalid register"); 934 return Reg - RISCV::F0_D + RISCV::F0_F; 935 } 936 937 static MCRegister convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg, 938 unsigned Kind) { 939 unsigned RegClassID; 940 if (Kind == MCK_VRM2) 941 RegClassID = RISCV::VRM2RegClassID; 942 else if (Kind == MCK_VRM4) 943 RegClassID = RISCV::VRM4RegClassID; 944 else if (Kind == MCK_VRM8) 945 RegClassID = RISCV::VRM8RegClassID; 946 else 947 return 0; 948 return RI.getMatchingSuperReg(Reg, RISCV::sub_vrm1_0, 949 &RISCVMCRegisterClasses[RegClassID]); 950 } 951 952 unsigned RISCVAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, 953 unsigned Kind) { 954 RISCVOperand &Op = static_cast<RISCVOperand &>(AsmOp); 955 if (!Op.isReg()) 956 return Match_InvalidOperand; 957 958 MCRegister Reg = Op.getReg(); 959 bool IsRegFPR64 = 960 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(Reg); 961 bool IsRegFPR64C = 962 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(Reg); 963 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(Reg); 964 965 // As the parser couldn't differentiate an FPR32 from an FPR64, coerce the 966 // register from FPR64 to FPR32 or FPR64C to FPR32C if necessary. 967 if ((IsRegFPR64 && Kind == MCK_FPR32) || 968 (IsRegFPR64C && Kind == MCK_FPR32C)) { 969 Op.Reg.RegNum = convertFPR64ToFPR32(Reg); 970 return Match_Success; 971 } 972 // As the parser couldn't differentiate an FPR16 from an FPR64, coerce the 973 // register from FPR64 to FPR16 if necessary. 974 if (IsRegFPR64 && Kind == MCK_FPR16) { 975 Op.Reg.RegNum = convertFPR64ToFPR16(Reg); 976 return Match_Success; 977 } 978 // As the parser couldn't differentiate an VRM2/VRM4/VRM8 from an VR, coerce 979 // the register from VR to VRM2/VRM4/VRM8 if necessary. 980 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) { 981 Op.Reg.RegNum = convertVRToVRMx(*getContext().getRegisterInfo(), Reg, Kind); 982 if (Op.Reg.RegNum == 0) 983 return Match_InvalidOperand; 984 return Match_Success; 985 } 986 return Match_InvalidOperand; 987 } 988 989 bool RISCVAsmParser::generateImmOutOfRangeError( 990 OperandVector &Operands, uint64_t ErrorInfo, int64_t Lower, int64_t Upper, 991 Twine Msg = "immediate must be an integer in the range") { 992 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 993 return Error(ErrorLoc, Msg + " [" + Twine(Lower) + ", " + Twine(Upper) + "]"); 994 } 995 996 bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 997 OperandVector &Operands, 998 MCStreamer &Out, 999 uint64_t &ErrorInfo, 1000 bool MatchingInlineAsm) { 1001 MCInst Inst; 1002 FeatureBitset MissingFeatures; 1003 1004 auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures, 1005 MatchingInlineAsm); 1006 switch (Result) { 1007 default: 1008 break; 1009 case Match_Success: 1010 if (validateInstruction(Inst, Operands)) 1011 return true; 1012 return processInstruction(Inst, IDLoc, Operands, Out); 1013 case Match_MissingFeature: { 1014 assert(MissingFeatures.any() && "Unknown missing features!"); 1015 bool FirstFeature = true; 1016 std::string Msg = "instruction requires the following:"; 1017 for (unsigned i = 0, e = MissingFeatures.size(); i != e; ++i) { 1018 if (MissingFeatures[i]) { 1019 Msg += FirstFeature ? " " : ", "; 1020 Msg += getSubtargetFeatureName(i); 1021 FirstFeature = false; 1022 } 1023 } 1024 return Error(IDLoc, Msg); 1025 } 1026 case Match_MnemonicFail: { 1027 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits()); 1028 std::string Suggestion = RISCVMnemonicSpellCheck( 1029 ((RISCVOperand &)*Operands[0]).getToken(), FBS, 0); 1030 return Error(IDLoc, "unrecognized instruction mnemonic" + Suggestion); 1031 } 1032 case Match_InvalidOperand: { 1033 SMLoc ErrorLoc = IDLoc; 1034 if (ErrorInfo != ~0ULL) { 1035 if (ErrorInfo >= Operands.size()) 1036 return Error(ErrorLoc, "too few operands for instruction"); 1037 1038 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1039 if (ErrorLoc == SMLoc()) 1040 ErrorLoc = IDLoc; 1041 } 1042 return Error(ErrorLoc, "invalid operand for instruction"); 1043 } 1044 } 1045 1046 // Handle the case when the error message is of specific type 1047 // other than the generic Match_InvalidOperand, and the 1048 // corresponding operand is missing. 1049 if (Result > FIRST_TARGET_MATCH_RESULT_TY) { 1050 SMLoc ErrorLoc = IDLoc; 1051 if (ErrorInfo != ~0ULL && ErrorInfo >= Operands.size()) 1052 return Error(ErrorLoc, "too few operands for instruction"); 1053 } 1054 1055 switch (Result) { 1056 default: 1057 break; 1058 case Match_InvalidImmXLenLI: 1059 if (isRV64()) { 1060 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1061 return Error(ErrorLoc, "operand must be a constant 64-bit integer"); 1062 } 1063 return generateImmOutOfRangeError(Operands, ErrorInfo, 1064 std::numeric_limits<int32_t>::min(), 1065 std::numeric_limits<uint32_t>::max()); 1066 case Match_InvalidImmZero: { 1067 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1068 return Error(ErrorLoc, "immediate must be zero"); 1069 } 1070 case Match_InvalidUImmLog2XLen: 1071 if (isRV64()) 1072 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1); 1073 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 1074 case Match_InvalidUImmLog2XLenNonZero: 1075 if (isRV64()) 1076 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1); 1077 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1); 1078 case Match_InvalidUImmLog2XLenHalf: 1079 if (isRV64()) 1080 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 1081 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1); 1082 case Match_InvalidUImm2: 1083 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1); 1084 case Match_InvalidUImm3: 1085 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1); 1086 case Match_InvalidUImm5: 1087 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1); 1088 case Match_InvalidUImm7: 1089 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1); 1090 case Match_InvalidSImm5: 1091 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4), 1092 (1 << 4) - 1); 1093 case Match_InvalidSImm6: 1094 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5), 1095 (1 << 5) - 1); 1096 case Match_InvalidSImm6NonZero: 1097 return generateImmOutOfRangeError( 1098 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1, 1099 "immediate must be non-zero in the range"); 1100 case Match_InvalidCLUIImm: 1101 return generateImmOutOfRangeError( 1102 Operands, ErrorInfo, 1, (1 << 5) - 1, 1103 "immediate must be in [0xfffe0, 0xfffff] or"); 1104 case Match_InvalidUImm7Lsb00: 1105 return generateImmOutOfRangeError( 1106 Operands, ErrorInfo, 0, (1 << 7) - 4, 1107 "immediate must be a multiple of 4 bytes in the range"); 1108 case Match_InvalidUImm8Lsb00: 1109 return generateImmOutOfRangeError( 1110 Operands, ErrorInfo, 0, (1 << 8) - 4, 1111 "immediate must be a multiple of 4 bytes in the range"); 1112 case Match_InvalidUImm8Lsb000: 1113 return generateImmOutOfRangeError( 1114 Operands, ErrorInfo, 0, (1 << 8) - 8, 1115 "immediate must be a multiple of 8 bytes in the range"); 1116 case Match_InvalidSImm9Lsb0: 1117 return generateImmOutOfRangeError( 1118 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2, 1119 "immediate must be a multiple of 2 bytes in the range"); 1120 case Match_InvalidUImm9Lsb000: 1121 return generateImmOutOfRangeError( 1122 Operands, ErrorInfo, 0, (1 << 9) - 8, 1123 "immediate must be a multiple of 8 bytes in the range"); 1124 case Match_InvalidUImm10Lsb00NonZero: 1125 return generateImmOutOfRangeError( 1126 Operands, ErrorInfo, 4, (1 << 10) - 4, 1127 "immediate must be a multiple of 4 bytes in the range"); 1128 case Match_InvalidSImm10Lsb0000NonZero: 1129 return generateImmOutOfRangeError( 1130 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16, 1131 "immediate must be a multiple of 16 bytes and non-zero in the range"); 1132 case Match_InvalidSImm12: 1133 return generateImmOutOfRangeError( 1134 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1, 1135 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an " 1136 "integer in the range"); 1137 case Match_InvalidSImm12Lsb0: 1138 return generateImmOutOfRangeError( 1139 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2, 1140 "immediate must be a multiple of 2 bytes in the range"); 1141 case Match_InvalidSImm13Lsb0: 1142 return generateImmOutOfRangeError( 1143 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2, 1144 "immediate must be a multiple of 2 bytes in the range"); 1145 case Match_InvalidUImm20LUI: 1146 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1, 1147 "operand must be a symbol with " 1148 "%hi/%tprel_hi modifier or an integer in " 1149 "the range"); 1150 case Match_InvalidUImm20AUIPC: 1151 return generateImmOutOfRangeError( 1152 Operands, ErrorInfo, 0, (1 << 20) - 1, 1153 "operand must be a symbol with a " 1154 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or " 1155 "an integer in the range"); 1156 case Match_InvalidSImm21Lsb0JAL: 1157 return generateImmOutOfRangeError( 1158 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2, 1159 "immediate must be a multiple of 2 bytes in the range"); 1160 case Match_InvalidCSRSystemRegister: { 1161 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1, 1162 "operand must be a valid system register " 1163 "name or an integer in the range"); 1164 } 1165 case Match_InvalidFenceArg: { 1166 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1167 return Error( 1168 ErrorLoc, 1169 "operand must be formed of letters selected in-order from 'iorw'"); 1170 } 1171 case Match_InvalidFRMArg: { 1172 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1173 return Error( 1174 ErrorLoc, 1175 "operand must be a valid floating point rounding mode mnemonic"); 1176 } 1177 case Match_InvalidBareSymbol: { 1178 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1179 return Error(ErrorLoc, "operand must be a bare symbol name"); 1180 } 1181 case Match_InvalidPseudoJumpSymbol: { 1182 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1183 return Error(ErrorLoc, "operand must be a valid jump target"); 1184 } 1185 case Match_InvalidCallSymbol: { 1186 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1187 return Error(ErrorLoc, "operand must be a bare symbol name"); 1188 } 1189 case Match_InvalidTPRelAddSymbol: { 1190 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1191 return Error(ErrorLoc, "operand must be a symbol with %tprel_add modifier"); 1192 } 1193 case Match_InvalidVTypeI: { 1194 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1195 return Error( 1196 ErrorLoc, 1197 "operand must be " 1198 "e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]"); 1199 } 1200 case Match_InvalidVMaskRegister: { 1201 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc(); 1202 return Error(ErrorLoc, "operand must be v0.t"); 1203 } 1204 case Match_InvalidSImm5Plus1: { 1205 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1, 1206 (1 << 4), 1207 "immediate must be in the range"); 1208 } 1209 } 1210 1211 llvm_unreachable("Unknown match type detected!"); 1212 } 1213 1214 // Attempts to match Name as a register (either using the default name or 1215 // alternative ABI names), setting RegNo to the matching register. Upon 1216 // failure, returns true and sets RegNo to 0. If IsRV32E then registers 1217 // x16-x31 will be rejected. 1218 static bool matchRegisterNameHelper(bool IsRV32E, MCRegister &RegNo, 1219 StringRef Name) { 1220 RegNo = MatchRegisterName(Name); 1221 // The 16-/32- and 64-bit FPRs have the same asm name. Check that the initial 1222 // match always matches the 64-bit variant, and not the 16/32-bit one. 1223 assert(!(RegNo >= RISCV::F0_H && RegNo <= RISCV::F31_H)); 1224 assert(!(RegNo >= RISCV::F0_F && RegNo <= RISCV::F31_F)); 1225 // The default FPR register class is based on the tablegen enum ordering. 1226 static_assert(RISCV::F0_D < RISCV::F0_H, "FPR matching must be updated"); 1227 static_assert(RISCV::F0_D < RISCV::F0_F, "FPR matching must be updated"); 1228 if (RegNo == RISCV::NoRegister) 1229 RegNo = MatchRegisterAltName(Name); 1230 if (IsRV32E && RegNo >= RISCV::X16 && RegNo <= RISCV::X31) 1231 RegNo = RISCV::NoRegister; 1232 return RegNo == RISCV::NoRegister; 1233 } 1234 1235 bool RISCVAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 1236 SMLoc &EndLoc) { 1237 if (tryParseRegister(RegNo, StartLoc, EndLoc) != MatchOperand_Success) 1238 return Error(StartLoc, "invalid register name"); 1239 return false; 1240 } 1241 1242 OperandMatchResultTy RISCVAsmParser::tryParseRegister(unsigned &RegNo, 1243 SMLoc &StartLoc, 1244 SMLoc &EndLoc) { 1245 const AsmToken &Tok = getParser().getTok(); 1246 StartLoc = Tok.getLoc(); 1247 EndLoc = Tok.getEndLoc(); 1248 RegNo = 0; 1249 StringRef Name = getLexer().getTok().getIdentifier(); 1250 1251 if (matchRegisterNameHelper(isRV32E(), (MCRegister &)RegNo, Name)) 1252 return MatchOperand_NoMatch; 1253 1254 getParser().Lex(); // Eat identifier token. 1255 return MatchOperand_Success; 1256 } 1257 1258 OperandMatchResultTy RISCVAsmParser::parseRegister(OperandVector &Operands, 1259 bool AllowParens) { 1260 SMLoc FirstS = getLoc(); 1261 bool HadParens = false; 1262 AsmToken LParen; 1263 1264 // If this is an LParen and a parenthesised register name is allowed, parse it 1265 // atomically. 1266 if (AllowParens && getLexer().is(AsmToken::LParen)) { 1267 AsmToken Buf[2]; 1268 size_t ReadCount = getLexer().peekTokens(Buf); 1269 if (ReadCount == 2 && Buf[1].getKind() == AsmToken::RParen) { 1270 HadParens = true; 1271 LParen = getParser().getTok(); 1272 getParser().Lex(); // Eat '(' 1273 } 1274 } 1275 1276 switch (getLexer().getKind()) { 1277 default: 1278 if (HadParens) 1279 getLexer().UnLex(LParen); 1280 return MatchOperand_NoMatch; 1281 case AsmToken::Identifier: 1282 StringRef Name = getLexer().getTok().getIdentifier(); 1283 MCRegister RegNo; 1284 matchRegisterNameHelper(isRV32E(), RegNo, Name); 1285 1286 if (RegNo == RISCV::NoRegister) { 1287 if (HadParens) 1288 getLexer().UnLex(LParen); 1289 return MatchOperand_NoMatch; 1290 } 1291 if (HadParens) 1292 Operands.push_back(RISCVOperand::createToken("(", FirstS, isRV64())); 1293 SMLoc S = getLoc(); 1294 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1295 getLexer().Lex(); 1296 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64())); 1297 } 1298 1299 if (HadParens) { 1300 getParser().Lex(); // Eat ')' 1301 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 1302 } 1303 1304 return MatchOperand_Success; 1305 } 1306 1307 OperandMatchResultTy 1308 RISCVAsmParser::parseCSRSystemRegister(OperandVector &Operands) { 1309 SMLoc S = getLoc(); 1310 const MCExpr *Res; 1311 1312 switch (getLexer().getKind()) { 1313 default: 1314 return MatchOperand_NoMatch; 1315 case AsmToken::LParen: 1316 case AsmToken::Minus: 1317 case AsmToken::Plus: 1318 case AsmToken::Exclaim: 1319 case AsmToken::Tilde: 1320 case AsmToken::Integer: 1321 case AsmToken::String: { 1322 if (getParser().parseExpression(Res)) 1323 return MatchOperand_ParseFail; 1324 1325 auto *CE = dyn_cast<MCConstantExpr>(Res); 1326 if (CE) { 1327 int64_t Imm = CE->getValue(); 1328 if (isUInt<12>(Imm)) { 1329 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm); 1330 // Accept an immediate representing a named or un-named Sys Reg 1331 // if the range is valid, regardless of the required features. 1332 Operands.push_back(RISCVOperand::createSysReg( 1333 SysReg ? SysReg->Name : "", S, Imm, isRV64())); 1334 return MatchOperand_Success; 1335 } 1336 } 1337 1338 Twine Msg = "immediate must be an integer in the range"; 1339 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1340 return MatchOperand_ParseFail; 1341 } 1342 case AsmToken::Identifier: { 1343 StringRef Identifier; 1344 if (getParser().parseIdentifier(Identifier)) 1345 return MatchOperand_ParseFail; 1346 1347 auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier); 1348 if (!SysReg) 1349 SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier); 1350 if (!SysReg) 1351 if ((SysReg = RISCVSysReg::lookupSysRegByDeprecatedName(Identifier))) 1352 Warning(S, "'" + Identifier + "' is a deprecated alias for '" + 1353 SysReg->Name + "'"); 1354 1355 // Accept a named Sys Reg if the required features are present. 1356 if (SysReg) { 1357 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits())) { 1358 Error(S, "system register use requires an option to be enabled"); 1359 return MatchOperand_ParseFail; 1360 } 1361 Operands.push_back(RISCVOperand::createSysReg( 1362 Identifier, S, SysReg->Encoding, isRV64())); 1363 return MatchOperand_Success; 1364 } 1365 1366 Twine Msg = "operand must be a valid system register name " 1367 "or an integer in the range"; 1368 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1369 return MatchOperand_ParseFail; 1370 } 1371 case AsmToken::Percent: { 1372 // Discard operand with modifier. 1373 Twine Msg = "immediate must be an integer in the range"; 1374 Error(S, Msg + " [" + Twine(0) + ", " + Twine((1 << 12) - 1) + "]"); 1375 return MatchOperand_ParseFail; 1376 } 1377 } 1378 1379 return MatchOperand_NoMatch; 1380 } 1381 1382 OperandMatchResultTy RISCVAsmParser::parseImmediate(OperandVector &Operands) { 1383 SMLoc S = getLoc(); 1384 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1385 const MCExpr *Res; 1386 1387 switch (getLexer().getKind()) { 1388 default: 1389 return MatchOperand_NoMatch; 1390 case AsmToken::LParen: 1391 case AsmToken::Dot: 1392 case AsmToken::Minus: 1393 case AsmToken::Plus: 1394 case AsmToken::Exclaim: 1395 case AsmToken::Tilde: 1396 case AsmToken::Integer: 1397 case AsmToken::String: 1398 case AsmToken::Identifier: 1399 if (getParser().parseExpression(Res)) 1400 return MatchOperand_ParseFail; 1401 break; 1402 case AsmToken::Percent: 1403 return parseOperandWithModifier(Operands); 1404 } 1405 1406 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1407 return MatchOperand_Success; 1408 } 1409 1410 OperandMatchResultTy 1411 RISCVAsmParser::parseOperandWithModifier(OperandVector &Operands) { 1412 SMLoc S = getLoc(); 1413 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1414 1415 if (getLexer().getKind() != AsmToken::Percent) { 1416 Error(getLoc(), "expected '%' for operand modifier"); 1417 return MatchOperand_ParseFail; 1418 } 1419 1420 getParser().Lex(); // Eat '%' 1421 1422 if (getLexer().getKind() != AsmToken::Identifier) { 1423 Error(getLoc(), "expected valid identifier for operand modifier"); 1424 return MatchOperand_ParseFail; 1425 } 1426 StringRef Identifier = getParser().getTok().getIdentifier(); 1427 RISCVMCExpr::VariantKind VK = RISCVMCExpr::getVariantKindForName(Identifier); 1428 if (VK == RISCVMCExpr::VK_RISCV_Invalid) { 1429 Error(getLoc(), "unrecognized operand modifier"); 1430 return MatchOperand_ParseFail; 1431 } 1432 1433 getParser().Lex(); // Eat the identifier 1434 if (getLexer().getKind() != AsmToken::LParen) { 1435 Error(getLoc(), "expected '('"); 1436 return MatchOperand_ParseFail; 1437 } 1438 getParser().Lex(); // Eat '(' 1439 1440 const MCExpr *SubExpr; 1441 if (getParser().parseParenExpression(SubExpr, E)) { 1442 return MatchOperand_ParseFail; 1443 } 1444 1445 const MCExpr *ModExpr = RISCVMCExpr::create(SubExpr, VK, getContext()); 1446 Operands.push_back(RISCVOperand::createImm(ModExpr, S, E, isRV64())); 1447 return MatchOperand_Success; 1448 } 1449 1450 OperandMatchResultTy RISCVAsmParser::parseBareSymbol(OperandVector &Operands) { 1451 SMLoc S = getLoc(); 1452 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1453 const MCExpr *Res; 1454 1455 if (getLexer().getKind() != AsmToken::Identifier) 1456 return MatchOperand_NoMatch; 1457 1458 StringRef Identifier; 1459 AsmToken Tok = getLexer().getTok(); 1460 1461 if (getParser().parseIdentifier(Identifier)) 1462 return MatchOperand_ParseFail; 1463 1464 if (Identifier.consume_back("@plt")) { 1465 Error(getLoc(), "'@plt' operand not valid for instruction"); 1466 return MatchOperand_ParseFail; 1467 } 1468 1469 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1470 1471 if (Sym->isVariable()) { 1472 const MCExpr *V = Sym->getVariableValue(/*SetUsed=*/false); 1473 if (!isa<MCSymbolRefExpr>(V)) { 1474 getLexer().UnLex(Tok); // Put back if it's not a bare symbol. 1475 return MatchOperand_NoMatch; 1476 } 1477 Res = V; 1478 } else 1479 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1480 1481 MCBinaryExpr::Opcode Opcode; 1482 switch (getLexer().getKind()) { 1483 default: 1484 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1485 return MatchOperand_Success; 1486 case AsmToken::Plus: 1487 Opcode = MCBinaryExpr::Add; 1488 break; 1489 case AsmToken::Minus: 1490 Opcode = MCBinaryExpr::Sub; 1491 break; 1492 } 1493 1494 const MCExpr *Expr; 1495 if (getParser().parseExpression(Expr)) 1496 return MatchOperand_ParseFail; 1497 Res = MCBinaryExpr::create(Opcode, Res, Expr, getContext()); 1498 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1499 return MatchOperand_Success; 1500 } 1501 1502 OperandMatchResultTy RISCVAsmParser::parseCallSymbol(OperandVector &Operands) { 1503 SMLoc S = getLoc(); 1504 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1505 const MCExpr *Res; 1506 1507 if (getLexer().getKind() != AsmToken::Identifier) 1508 return MatchOperand_NoMatch; 1509 1510 // Avoid parsing the register in `call rd, foo` as a call symbol. 1511 if (getLexer().peekTok().getKind() != AsmToken::EndOfStatement) 1512 return MatchOperand_NoMatch; 1513 1514 StringRef Identifier; 1515 if (getParser().parseIdentifier(Identifier)) 1516 return MatchOperand_ParseFail; 1517 1518 RISCVMCExpr::VariantKind Kind = RISCVMCExpr::VK_RISCV_CALL; 1519 if (Identifier.consume_back("@plt")) 1520 Kind = RISCVMCExpr::VK_RISCV_CALL_PLT; 1521 1522 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier); 1523 Res = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1524 Res = RISCVMCExpr::create(Res, Kind, getContext()); 1525 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1526 return MatchOperand_Success; 1527 } 1528 1529 OperandMatchResultTy 1530 RISCVAsmParser::parsePseudoJumpSymbol(OperandVector &Operands) { 1531 SMLoc S = getLoc(); 1532 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1533 const MCExpr *Res; 1534 1535 if (getParser().parseExpression(Res)) 1536 return MatchOperand_ParseFail; 1537 1538 if (Res->getKind() != MCExpr::ExprKind::SymbolRef || 1539 cast<MCSymbolRefExpr>(Res)->getKind() == 1540 MCSymbolRefExpr::VariantKind::VK_PLT) { 1541 Error(S, "operand must be a valid jump target"); 1542 return MatchOperand_ParseFail; 1543 } 1544 1545 Res = RISCVMCExpr::create(Res, RISCVMCExpr::VK_RISCV_CALL, getContext()); 1546 Operands.push_back(RISCVOperand::createImm(Res, S, E, isRV64())); 1547 return MatchOperand_Success; 1548 } 1549 1550 OperandMatchResultTy RISCVAsmParser::parseJALOffset(OperandVector &Operands) { 1551 // Parsing jal operands is fiddly due to the `jal foo` and `jal ra, foo` 1552 // both being acceptable forms. When parsing `jal ra, foo` this function 1553 // will be called for the `ra` register operand in an attempt to match the 1554 // single-operand alias. parseJALOffset must fail for this case. It would 1555 // seem logical to try parse the operand using parseImmediate and return 1556 // NoMatch if the next token is a comma (meaning we must be parsing a jal in 1557 // the second form rather than the first). We can't do this as there's no 1558 // way of rewinding the lexer state. Instead, return NoMatch if this operand 1559 // is an identifier and is followed by a comma. 1560 if (getLexer().is(AsmToken::Identifier) && 1561 getLexer().peekTok().is(AsmToken::Comma)) 1562 return MatchOperand_NoMatch; 1563 1564 return parseImmediate(Operands); 1565 } 1566 1567 OperandMatchResultTy RISCVAsmParser::parseVTypeI(OperandVector &Operands) { 1568 SMLoc S = getLoc(); 1569 if (getLexer().isNot(AsmToken::Identifier)) 1570 return MatchOperand_NoMatch; 1571 1572 SmallVector<AsmToken, 7> VTypeIElements; 1573 // Put all the tokens for vtypei operand into VTypeIElements vector. 1574 while (getLexer().isNot(AsmToken::EndOfStatement)) { 1575 VTypeIElements.push_back(getLexer().getTok()); 1576 getLexer().Lex(); 1577 if (getLexer().is(AsmToken::EndOfStatement)) 1578 break; 1579 if (getLexer().isNot(AsmToken::Comma)) 1580 goto MatchFail; 1581 AsmToken Comma = getLexer().getTok(); 1582 VTypeIElements.push_back(Comma); 1583 getLexer().Lex(); 1584 } 1585 1586 if (VTypeIElements.size() == 7) { 1587 // The VTypeIElements layout is: 1588 // SEW comma LMUL comma TA comma MA 1589 // 0 1 2 3 4 5 6 1590 StringRef Name = VTypeIElements[0].getIdentifier(); 1591 if (!Name.consume_front("e")) 1592 goto MatchFail; 1593 unsigned Sew; 1594 if (Name.getAsInteger(10, Sew)) 1595 goto MatchFail; 1596 if (!RISCVVType::isValidSEW(Sew)) 1597 goto MatchFail; 1598 1599 Name = VTypeIElements[2].getIdentifier(); 1600 if (!Name.consume_front("m")) 1601 goto MatchFail; 1602 // "m" or "mf" 1603 bool Fractional = Name.consume_front("f"); 1604 unsigned Lmul; 1605 if (Name.getAsInteger(10, Lmul)) 1606 goto MatchFail; 1607 if (!RISCVVType::isValidLMUL(Lmul, Fractional)) 1608 goto MatchFail; 1609 1610 // ta or tu 1611 Name = VTypeIElements[4].getIdentifier(); 1612 bool TailAgnostic; 1613 if (Name == "ta") 1614 TailAgnostic = true; 1615 else if (Name == "tu") 1616 TailAgnostic = false; 1617 else 1618 goto MatchFail; 1619 1620 // ma or mu 1621 Name = VTypeIElements[6].getIdentifier(); 1622 bool MaskAgnostic; 1623 if (Name == "ma") 1624 MaskAgnostic = true; 1625 else if (Name == "mu") 1626 MaskAgnostic = false; 1627 else 1628 goto MatchFail; 1629 1630 unsigned LmulLog2 = Log2_32(Lmul); 1631 RISCVII::VLMUL VLMUL = 1632 static_cast<RISCVII::VLMUL>(Fractional ? 8 - LmulLog2 : LmulLog2); 1633 1634 unsigned VTypeI = 1635 RISCVVType::encodeVTYPE(VLMUL, Sew, TailAgnostic, MaskAgnostic); 1636 Operands.push_back(RISCVOperand::createVType(VTypeI, S, isRV64())); 1637 return MatchOperand_Success; 1638 } 1639 1640 // If NoMatch, unlex all the tokens that comprise a vtypei operand 1641 MatchFail: 1642 while (!VTypeIElements.empty()) 1643 getLexer().UnLex(VTypeIElements.pop_back_val()); 1644 return MatchOperand_NoMatch; 1645 } 1646 1647 OperandMatchResultTy RISCVAsmParser::parseMaskReg(OperandVector &Operands) { 1648 switch (getLexer().getKind()) { 1649 default: 1650 return MatchOperand_NoMatch; 1651 case AsmToken::Identifier: 1652 StringRef Name = getLexer().getTok().getIdentifier(); 1653 if (!Name.consume_back(".t")) { 1654 Error(getLoc(), "expected '.t' suffix"); 1655 return MatchOperand_ParseFail; 1656 } 1657 MCRegister RegNo; 1658 matchRegisterNameHelper(isRV32E(), RegNo, Name); 1659 1660 if (RegNo == RISCV::NoRegister) 1661 return MatchOperand_NoMatch; 1662 if (RegNo != RISCV::V0) 1663 return MatchOperand_NoMatch; 1664 SMLoc S = getLoc(); 1665 SMLoc E = SMLoc::getFromPointer(S.getPointer() - 1); 1666 getLexer().Lex(); 1667 Operands.push_back(RISCVOperand::createReg(RegNo, S, E, isRV64())); 1668 } 1669 1670 return MatchOperand_Success; 1671 } 1672 1673 OperandMatchResultTy 1674 RISCVAsmParser::parseMemOpBaseReg(OperandVector &Operands) { 1675 if (getLexer().isNot(AsmToken::LParen)) { 1676 Error(getLoc(), "expected '('"); 1677 return MatchOperand_ParseFail; 1678 } 1679 1680 getParser().Lex(); // Eat '(' 1681 Operands.push_back(RISCVOperand::createToken("(", getLoc(), isRV64())); 1682 1683 if (parseRegister(Operands) != MatchOperand_Success) { 1684 Error(getLoc(), "expected register"); 1685 return MatchOperand_ParseFail; 1686 } 1687 1688 if (getLexer().isNot(AsmToken::RParen)) { 1689 Error(getLoc(), "expected ')'"); 1690 return MatchOperand_ParseFail; 1691 } 1692 1693 getParser().Lex(); // Eat ')' 1694 Operands.push_back(RISCVOperand::createToken(")", getLoc(), isRV64())); 1695 1696 return MatchOperand_Success; 1697 } 1698 1699 OperandMatchResultTy RISCVAsmParser::parseAtomicMemOp(OperandVector &Operands) { 1700 // Atomic operations such as lr.w, sc.w, and amo*.w accept a "memory operand" 1701 // as one of their register operands, such as `(a0)`. This just denotes that 1702 // the register (in this case `a0`) contains a memory address. 1703 // 1704 // Normally, we would be able to parse these by putting the parens into the 1705 // instruction string. However, GNU as also accepts a zero-offset memory 1706 // operand (such as `0(a0)`), and ignores the 0. Normally this would be parsed 1707 // with parseImmediate followed by parseMemOpBaseReg, but these instructions 1708 // do not accept an immediate operand, and we do not want to add a "dummy" 1709 // operand that is silently dropped. 1710 // 1711 // Instead, we use this custom parser. This will: allow (and discard) an 1712 // offset if it is zero; require (and discard) parentheses; and add only the 1713 // parsed register operand to `Operands`. 1714 // 1715 // These operands are printed with RISCVInstPrinter::printAtomicMemOp, which 1716 // will only print the register surrounded by parentheses (which GNU as also 1717 // uses as its canonical representation for these operands). 1718 std::unique_ptr<RISCVOperand> OptionalImmOp; 1719 1720 if (getLexer().isNot(AsmToken::LParen)) { 1721 // Parse an Integer token. We do not accept arbritrary constant expressions 1722 // in the offset field (because they may include parens, which complicates 1723 // parsing a lot). 1724 int64_t ImmVal; 1725 SMLoc ImmStart = getLoc(); 1726 if (getParser().parseIntToken(ImmVal, 1727 "expected '(' or optional integer offset")) 1728 return MatchOperand_ParseFail; 1729 1730 // Create a RISCVOperand for checking later (so the error messages are 1731 // nicer), but we don't add it to Operands. 1732 SMLoc ImmEnd = getLoc(); 1733 OptionalImmOp = 1734 RISCVOperand::createImm(MCConstantExpr::create(ImmVal, getContext()), 1735 ImmStart, ImmEnd, isRV64()); 1736 } 1737 1738 if (getLexer().isNot(AsmToken::LParen)) { 1739 Error(getLoc(), OptionalImmOp ? "expected '(' after optional integer offset" 1740 : "expected '(' or optional integer offset"); 1741 return MatchOperand_ParseFail; 1742 } 1743 getParser().Lex(); // Eat '(' 1744 1745 if (parseRegister(Operands) != MatchOperand_Success) { 1746 Error(getLoc(), "expected register"); 1747 return MatchOperand_ParseFail; 1748 } 1749 1750 if (getLexer().isNot(AsmToken::RParen)) { 1751 Error(getLoc(), "expected ')'"); 1752 return MatchOperand_ParseFail; 1753 } 1754 getParser().Lex(); // Eat ')' 1755 1756 // Deferred Handling of non-zero offsets. This makes the error messages nicer. 1757 if (OptionalImmOp && !OptionalImmOp->isImmZero()) { 1758 Error(OptionalImmOp->getStartLoc(), "optional integer offset must be 0", 1759 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc())); 1760 return MatchOperand_ParseFail; 1761 } 1762 1763 return MatchOperand_Success; 1764 } 1765 1766 /// Looks at a token type and creates the relevant operand from this 1767 /// information, adding to Operands. If operand was parsed, returns false, else 1768 /// true. 1769 bool RISCVAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) { 1770 // Check if the current operand has a custom associated parser, if so, try to 1771 // custom parse the operand, or fallback to the general approach. 1772 OperandMatchResultTy Result = 1773 MatchOperandParserImpl(Operands, Mnemonic, /*ParseForAllFeatures=*/true); 1774 if (Result == MatchOperand_Success) 1775 return false; 1776 if (Result == MatchOperand_ParseFail) 1777 return true; 1778 1779 // Attempt to parse token as a register. 1780 if (parseRegister(Operands, true) == MatchOperand_Success) 1781 return false; 1782 1783 // Attempt to parse token as an immediate 1784 if (parseImmediate(Operands) == MatchOperand_Success) { 1785 // Parse memory base register if present 1786 if (getLexer().is(AsmToken::LParen)) 1787 return parseMemOpBaseReg(Operands) != MatchOperand_Success; 1788 return false; 1789 } 1790 1791 // Finally we have exhausted all options and must declare defeat. 1792 Error(getLoc(), "unknown operand"); 1793 return true; 1794 } 1795 1796 bool RISCVAsmParser::ParseInstruction(ParseInstructionInfo &Info, 1797 StringRef Name, SMLoc NameLoc, 1798 OperandVector &Operands) { 1799 // Ensure that if the instruction occurs when relaxation is enabled, 1800 // relocations are forced for the file. Ideally this would be done when there 1801 // is enough information to reliably determine if the instruction itself may 1802 // cause relaxations. Unfortunately instruction processing stage occurs in the 1803 // same pass as relocation emission, so it's too late to set a 'sticky bit' 1804 // for the entire file. 1805 if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) { 1806 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr(); 1807 if (Assembler != nullptr) { 1808 RISCVAsmBackend &MAB = 1809 static_cast<RISCVAsmBackend &>(Assembler->getBackend()); 1810 MAB.setForceRelocs(); 1811 } 1812 } 1813 1814 // First operand is token for instruction 1815 Operands.push_back(RISCVOperand::createToken(Name, NameLoc, isRV64())); 1816 1817 // If there are no more operands, then finish 1818 if (getLexer().is(AsmToken::EndOfStatement)) 1819 return false; 1820 1821 // Parse first operand 1822 if (parseOperand(Operands, Name)) 1823 return true; 1824 1825 // Parse until end of statement, consuming commas between operands 1826 unsigned OperandIdx = 1; 1827 while (getLexer().is(AsmToken::Comma)) { 1828 // Consume comma token 1829 getLexer().Lex(); 1830 1831 // Parse next operand 1832 if (parseOperand(Operands, Name)) 1833 return true; 1834 1835 ++OperandIdx; 1836 } 1837 1838 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1839 SMLoc Loc = getLexer().getLoc(); 1840 getParser().eatToEndOfStatement(); 1841 return Error(Loc, "unexpected token"); 1842 } 1843 1844 getParser().Lex(); // Consume the EndOfStatement. 1845 return false; 1846 } 1847 1848 bool RISCVAsmParser::classifySymbolRef(const MCExpr *Expr, 1849 RISCVMCExpr::VariantKind &Kind) { 1850 Kind = RISCVMCExpr::VK_RISCV_None; 1851 1852 if (const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) { 1853 Kind = RE->getKind(); 1854 Expr = RE->getSubExpr(); 1855 } 1856 1857 MCValue Res; 1858 MCFixup Fixup; 1859 if (Expr->evaluateAsRelocatable(Res, nullptr, &Fixup)) 1860 return Res.getRefKind() == RISCVMCExpr::VK_RISCV_None; 1861 return false; 1862 } 1863 1864 bool RISCVAsmParser::ParseDirective(AsmToken DirectiveID) { 1865 // This returns false if this function recognizes the directive 1866 // regardless of whether it is successfully handles or reports an 1867 // error. Otherwise it returns true to give the generic parser a 1868 // chance at recognizing it. 1869 StringRef IDVal = DirectiveID.getString(); 1870 1871 if (IDVal == ".option") 1872 return parseDirectiveOption(); 1873 if (IDVal == ".attribute") 1874 return parseDirectiveAttribute(); 1875 if (IDVal == ".insn") 1876 return parseDirectiveInsn(DirectiveID.getLoc()); 1877 1878 return true; 1879 } 1880 1881 bool RISCVAsmParser::parseDirectiveOption() { 1882 MCAsmParser &Parser = getParser(); 1883 // Get the option token. 1884 AsmToken Tok = Parser.getTok(); 1885 // At the moment only identifiers are supported. 1886 if (Tok.isNot(AsmToken::Identifier)) 1887 return Error(Parser.getTok().getLoc(), 1888 "unexpected token, expected identifier"); 1889 1890 StringRef Option = Tok.getIdentifier(); 1891 1892 if (Option == "push") { 1893 getTargetStreamer().emitDirectiveOptionPush(); 1894 1895 Parser.Lex(); 1896 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1897 return Error(Parser.getTok().getLoc(), 1898 "unexpected token, expected end of statement"); 1899 1900 pushFeatureBits(); 1901 return false; 1902 } 1903 1904 if (Option == "pop") { 1905 SMLoc StartLoc = Parser.getTok().getLoc(); 1906 getTargetStreamer().emitDirectiveOptionPop(); 1907 1908 Parser.Lex(); 1909 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1910 return Error(Parser.getTok().getLoc(), 1911 "unexpected token, expected end of statement"); 1912 1913 if (popFeatureBits()) 1914 return Error(StartLoc, ".option pop with no .option push"); 1915 1916 return false; 1917 } 1918 1919 if (Option == "rvc") { 1920 getTargetStreamer().emitDirectiveOptionRVC(); 1921 1922 Parser.Lex(); 1923 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1924 return Error(Parser.getTok().getLoc(), 1925 "unexpected token, expected end of statement"); 1926 1927 setFeatureBits(RISCV::FeatureStdExtC, "c"); 1928 return false; 1929 } 1930 1931 if (Option == "norvc") { 1932 getTargetStreamer().emitDirectiveOptionNoRVC(); 1933 1934 Parser.Lex(); 1935 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1936 return Error(Parser.getTok().getLoc(), 1937 "unexpected token, expected end of statement"); 1938 1939 clearFeatureBits(RISCV::FeatureStdExtC, "c"); 1940 return false; 1941 } 1942 1943 if (Option == "pic") { 1944 getTargetStreamer().emitDirectiveOptionPIC(); 1945 1946 Parser.Lex(); 1947 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1948 return Error(Parser.getTok().getLoc(), 1949 "unexpected token, expected end of statement"); 1950 1951 ParserOptions.IsPicEnabled = true; 1952 return false; 1953 } 1954 1955 if (Option == "nopic") { 1956 getTargetStreamer().emitDirectiveOptionNoPIC(); 1957 1958 Parser.Lex(); 1959 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1960 return Error(Parser.getTok().getLoc(), 1961 "unexpected token, expected end of statement"); 1962 1963 ParserOptions.IsPicEnabled = false; 1964 return false; 1965 } 1966 1967 if (Option == "relax") { 1968 getTargetStreamer().emitDirectiveOptionRelax(); 1969 1970 Parser.Lex(); 1971 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1972 return Error(Parser.getTok().getLoc(), 1973 "unexpected token, expected end of statement"); 1974 1975 setFeatureBits(RISCV::FeatureRelax, "relax"); 1976 return false; 1977 } 1978 1979 if (Option == "norelax") { 1980 getTargetStreamer().emitDirectiveOptionNoRelax(); 1981 1982 Parser.Lex(); 1983 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) 1984 return Error(Parser.getTok().getLoc(), 1985 "unexpected token, expected end of statement"); 1986 1987 clearFeatureBits(RISCV::FeatureRelax, "relax"); 1988 return false; 1989 } 1990 1991 // Unknown option. 1992 Warning(Parser.getTok().getLoc(), 1993 "unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'relax' or " 1994 "'norelax'"); 1995 Parser.eatToEndOfStatement(); 1996 return false; 1997 } 1998 1999 /// parseDirectiveAttribute 2000 /// ::= .attribute expression ',' ( expression | "string" ) 2001 /// ::= .attribute identifier ',' ( expression | "string" ) 2002 bool RISCVAsmParser::parseDirectiveAttribute() { 2003 MCAsmParser &Parser = getParser(); 2004 int64_t Tag; 2005 SMLoc TagLoc; 2006 TagLoc = Parser.getTok().getLoc(); 2007 if (Parser.getTok().is(AsmToken::Identifier)) { 2008 StringRef Name = Parser.getTok().getIdentifier(); 2009 Optional<unsigned> Ret = 2010 ELFAttrs::attrTypeFromString(Name, RISCVAttrs::getRISCVAttributeTags()); 2011 if (!Ret.hasValue()) { 2012 Error(TagLoc, "attribute name not recognised: " + Name); 2013 return false; 2014 } 2015 Tag = Ret.getValue(); 2016 Parser.Lex(); 2017 } else { 2018 const MCExpr *AttrExpr; 2019 2020 TagLoc = Parser.getTok().getLoc(); 2021 if (Parser.parseExpression(AttrExpr)) 2022 return true; 2023 2024 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(AttrExpr); 2025 if (check(!CE, TagLoc, "expected numeric constant")) 2026 return true; 2027 2028 Tag = CE->getValue(); 2029 } 2030 2031 if (Parser.parseToken(AsmToken::Comma, "comma expected")) 2032 return true; 2033 2034 StringRef StringValue; 2035 int64_t IntegerValue = 0; 2036 bool IsIntegerValue = true; 2037 2038 // RISC-V attributes have a string value if the tag number is odd 2039 // and an integer value if the tag number is even. 2040 if (Tag % 2) 2041 IsIntegerValue = false; 2042 2043 SMLoc ValueExprLoc = Parser.getTok().getLoc(); 2044 if (IsIntegerValue) { 2045 const MCExpr *ValueExpr; 2046 if (Parser.parseExpression(ValueExpr)) 2047 return true; 2048 2049 const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(ValueExpr); 2050 if (!CE) 2051 return Error(ValueExprLoc, "expected numeric constant"); 2052 IntegerValue = CE->getValue(); 2053 } else { 2054 if (Parser.getTok().isNot(AsmToken::String)) 2055 return Error(Parser.getTok().getLoc(), "expected string constant"); 2056 2057 StringValue = Parser.getTok().getStringContents(); 2058 Parser.Lex(); 2059 } 2060 2061 if (Parser.parseToken(AsmToken::EndOfStatement, 2062 "unexpected token in '.attribute' directive")) 2063 return true; 2064 2065 if (Tag == RISCVAttrs::ARCH) { 2066 StringRef Arch = StringValue; 2067 for (auto Feature : RISCVFeatureKV) 2068 if (llvm::RISCVISAInfo::isSupportedExtensionFeature(Feature.Key)) 2069 clearFeatureBits(Feature.Value, Feature.Key); 2070 2071 auto ParseResult = llvm::RISCVISAInfo::parseArchString( 2072 StringValue, /*EnableExperimentalExtension=*/true, 2073 /*ExperimentalExtensionVersionCheck=*/false); 2074 if (!ParseResult) { 2075 std::string Buffer; 2076 raw_string_ostream OutputErrMsg(Buffer); 2077 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) { 2078 OutputErrMsg << "invalid arch name '" << Arch << "', " 2079 << ErrMsg.getMessage(); 2080 }); 2081 2082 return Error(ValueExprLoc, OutputErrMsg.str()); 2083 } 2084 auto &ISAInfo = *ParseResult; 2085 2086 for (auto Feature : RISCVFeatureKV) 2087 if (ISAInfo->hasExtension(Feature.Key)) 2088 setFeatureBits(Feature.Value, Feature.Key); 2089 2090 if (ISAInfo->getXLen() == 32) 2091 clearFeatureBits(RISCV::Feature64Bit, "64bit"); 2092 else if (ISAInfo->getXLen() == 64) 2093 setFeatureBits(RISCV::Feature64Bit, "64bit"); 2094 else 2095 return Error(ValueExprLoc, "bad arch string " + Arch); 2096 } 2097 2098 if (IsIntegerValue) 2099 getTargetStreamer().emitAttribute(Tag, IntegerValue); 2100 else { 2101 if (Tag != RISCVAttrs::ARCH) { 2102 getTargetStreamer().emitTextAttribute(Tag, StringValue); 2103 } else { 2104 std::vector<std::string> FeatureVector; 2105 RISCVFeatures::toFeatureVector(FeatureVector, getSTI().getFeatureBits()); 2106 2107 // Parse that by RISCVISAInfo-> 2108 unsigned XLen = getFeatureBits(RISCV::Feature64Bit) ? 64 : 32; 2109 auto ParseResult = llvm::RISCVISAInfo::parseFeatures(XLen, FeatureVector); 2110 if (!ParseResult) { 2111 std::string Buffer; 2112 raw_string_ostream OutputErrMsg(Buffer); 2113 handleAllErrors(ParseResult.takeError(), 2114 [&](llvm::StringError &ErrMsg) { 2115 OutputErrMsg << ErrMsg.getMessage(); 2116 }); 2117 2118 return Error(ValueExprLoc, OutputErrMsg.str()); 2119 } 2120 auto &ISAInfo = *ParseResult; 2121 2122 // Then emit the arch string. 2123 getTargetStreamer().emitTextAttribute(Tag, ISAInfo->toString()); 2124 } 2125 } 2126 2127 return false; 2128 } 2129 2130 /// parseDirectiveInsn 2131 /// ::= .insn [ format encoding, (operands (, operands)*) ] 2132 bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) { 2133 MCAsmParser &Parser = getParser(); 2134 2135 // Expect instruction format as identifier. 2136 StringRef Format; 2137 SMLoc ErrorLoc = Parser.getTok().getLoc(); 2138 if (Parser.parseIdentifier(Format)) 2139 return Error(ErrorLoc, "expected instruction format"); 2140 2141 if (Format != "r" && Format != "r4" && Format != "i" && Format != "b" && 2142 Format != "sb" && Format != "u" && Format != "j" && Format != "uj" && 2143 Format != "s") 2144 return Error(ErrorLoc, "invalid instruction format"); 2145 2146 std::string FormatName = (".insn_" + Format).str(); 2147 2148 ParseInstructionInfo Info; 2149 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> Operands; 2150 2151 if (ParseInstruction(Info, FormatName, L, Operands)) 2152 return true; 2153 2154 unsigned Opcode; 2155 uint64_t ErrorInfo; 2156 return MatchAndEmitInstruction(L, Opcode, Operands, Parser.getStreamer(), 2157 ErrorInfo, 2158 /*MatchingInlineAsm=*/false); 2159 } 2160 2161 void RISCVAsmParser::emitToStreamer(MCStreamer &S, const MCInst &Inst) { 2162 MCInst CInst; 2163 bool Res = compressInst(CInst, Inst, getSTI(), S.getContext()); 2164 if (Res) 2165 ++RISCVNumInstrsCompressed; 2166 S.emitInstruction((Res ? CInst : Inst), getSTI()); 2167 } 2168 2169 void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t Value, 2170 MCStreamer &Out) { 2171 RISCVMatInt::InstSeq Seq = 2172 RISCVMatInt::generateInstSeq(Value, getSTI().getFeatureBits()); 2173 2174 MCRegister SrcReg = RISCV::X0; 2175 for (RISCVMatInt::Inst &Inst : Seq) { 2176 if (Inst.Opc == RISCV::LUI) { 2177 emitToStreamer( 2178 Out, MCInstBuilder(RISCV::LUI).addReg(DestReg).addImm(Inst.Imm)); 2179 } else if (Inst.Opc == RISCV::ADDUW) { 2180 emitToStreamer(Out, MCInstBuilder(RISCV::ADDUW) 2181 .addReg(DestReg) 2182 .addReg(SrcReg) 2183 .addReg(RISCV::X0)); 2184 } else if (Inst.Opc == RISCV::SH1ADD || Inst.Opc == RISCV::SH2ADD || 2185 Inst.Opc == RISCV::SH3ADD) { 2186 emitToStreamer( 2187 Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addReg( 2188 SrcReg)); 2189 } else { 2190 emitToStreamer( 2191 Out, MCInstBuilder(Inst.Opc).addReg(DestReg).addReg(SrcReg).addImm( 2192 Inst.Imm)); 2193 } 2194 2195 // Only the first instruction has X0 as its source. 2196 SrcReg = DestReg; 2197 } 2198 } 2199 2200 void RISCVAsmParser::emitAuipcInstPair(MCOperand DestReg, MCOperand TmpReg, 2201 const MCExpr *Symbol, 2202 RISCVMCExpr::VariantKind VKHi, 2203 unsigned SecondOpcode, SMLoc IDLoc, 2204 MCStreamer &Out) { 2205 // A pair of instructions for PC-relative addressing; expands to 2206 // TmpLabel: AUIPC TmpReg, VKHi(symbol) 2207 // OP DestReg, TmpReg, %pcrel_lo(TmpLabel) 2208 MCContext &Ctx = getContext(); 2209 2210 MCSymbol *TmpLabel = Ctx.createNamedTempSymbol("pcrel_hi"); 2211 Out.emitLabel(TmpLabel); 2212 2213 const RISCVMCExpr *SymbolHi = RISCVMCExpr::create(Symbol, VKHi, Ctx); 2214 emitToStreamer( 2215 Out, MCInstBuilder(RISCV::AUIPC).addOperand(TmpReg).addExpr(SymbolHi)); 2216 2217 const MCExpr *RefToLinkTmpLabel = 2218 RISCVMCExpr::create(MCSymbolRefExpr::create(TmpLabel, Ctx), 2219 RISCVMCExpr::VK_RISCV_PCREL_LO, Ctx); 2220 2221 emitToStreamer(Out, MCInstBuilder(SecondOpcode) 2222 .addOperand(DestReg) 2223 .addOperand(TmpReg) 2224 .addExpr(RefToLinkTmpLabel)); 2225 } 2226 2227 void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, 2228 MCStreamer &Out) { 2229 // The load local address pseudo-instruction "lla" is used in PC-relative 2230 // addressing of local symbols: 2231 // lla rdest, symbol 2232 // expands to 2233 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) 2234 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 2235 MCOperand DestReg = Inst.getOperand(0); 2236 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2237 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI, 2238 RISCV::ADDI, IDLoc, Out); 2239 } 2240 2241 void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc, 2242 MCStreamer &Out) { 2243 // The load address pseudo-instruction "la" is used in PC-relative and 2244 // GOT-indirect addressing of global symbols: 2245 // la rdest, symbol 2246 // expands to either (for non-PIC) 2247 // TmpLabel: AUIPC rdest, %pcrel_hi(symbol) 2248 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 2249 // or (for PIC) 2250 // TmpLabel: AUIPC rdest, %got_pcrel_hi(symbol) 2251 // Lx rdest, %pcrel_lo(TmpLabel)(rdest) 2252 MCOperand DestReg = Inst.getOperand(0); 2253 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2254 unsigned SecondOpcode; 2255 RISCVMCExpr::VariantKind VKHi; 2256 if (ParserOptions.IsPicEnabled) { 2257 SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; 2258 VKHi = RISCVMCExpr::VK_RISCV_GOT_HI; 2259 } else { 2260 SecondOpcode = RISCV::ADDI; 2261 VKHi = RISCVMCExpr::VK_RISCV_PCREL_HI; 2262 } 2263 emitAuipcInstPair(DestReg, DestReg, Symbol, VKHi, SecondOpcode, IDLoc, Out); 2264 } 2265 2266 void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, 2267 MCStreamer &Out) { 2268 // The load TLS IE address pseudo-instruction "la.tls.ie" is used in 2269 // initial-exec TLS model addressing of global symbols: 2270 // la.tls.ie rdest, symbol 2271 // expands to 2272 // TmpLabel: AUIPC rdest, %tls_ie_pcrel_hi(symbol) 2273 // Lx rdest, %pcrel_lo(TmpLabel)(rdest) 2274 MCOperand DestReg = Inst.getOperand(0); 2275 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2276 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW; 2277 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GOT_HI, 2278 SecondOpcode, IDLoc, Out); 2279 } 2280 2281 void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, 2282 MCStreamer &Out) { 2283 // The load TLS GD address pseudo-instruction "la.tls.gd" is used in 2284 // global-dynamic TLS model addressing of global symbols: 2285 // la.tls.gd rdest, symbol 2286 // expands to 2287 // TmpLabel: AUIPC rdest, %tls_gd_pcrel_hi(symbol) 2288 // ADDI rdest, rdest, %pcrel_lo(TmpLabel) 2289 MCOperand DestReg = Inst.getOperand(0); 2290 const MCExpr *Symbol = Inst.getOperand(1).getExpr(); 2291 emitAuipcInstPair(DestReg, DestReg, Symbol, RISCVMCExpr::VK_RISCV_TLS_GD_HI, 2292 RISCV::ADDI, IDLoc, Out); 2293 } 2294 2295 void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, 2296 SMLoc IDLoc, MCStreamer &Out, 2297 bool HasTmpReg) { 2298 // The load/store pseudo-instruction does a pc-relative load with 2299 // a symbol. 2300 // 2301 // The expansion looks like this 2302 // 2303 // TmpLabel: AUIPC tmp, %pcrel_hi(symbol) 2304 // [S|L]X rd, %pcrel_lo(TmpLabel)(tmp) 2305 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0; 2306 MCOperand DestReg = Inst.getOperand(DestRegOpIdx); 2307 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1; 2308 MCOperand TmpReg = Inst.getOperand(0); 2309 const MCExpr *Symbol = Inst.getOperand(SymbolOpIdx).getExpr(); 2310 emitAuipcInstPair(DestReg, TmpReg, Symbol, RISCVMCExpr::VK_RISCV_PCREL_HI, 2311 Opcode, IDLoc, Out); 2312 } 2313 2314 void RISCVAsmParser::emitPseudoExtend(MCInst &Inst, bool SignExtend, 2315 int64_t Width, SMLoc IDLoc, 2316 MCStreamer &Out) { 2317 // The sign/zero extend pseudo-instruction does two shifts, with the shift 2318 // amounts dependent on the XLEN. 2319 // 2320 // The expansion looks like this 2321 // 2322 // SLLI rd, rs, XLEN - Width 2323 // SR[A|R]I rd, rd, XLEN - Width 2324 MCOperand DestReg = Inst.getOperand(0); 2325 MCOperand SourceReg = Inst.getOperand(1); 2326 2327 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI; 2328 int64_t ShAmt = (isRV64() ? 64 : 32) - Width; 2329 2330 assert(ShAmt > 0 && "Shift amount must be non-zero."); 2331 2332 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI) 2333 .addOperand(DestReg) 2334 .addOperand(SourceReg) 2335 .addImm(ShAmt)); 2336 2337 emitToStreamer(Out, MCInstBuilder(SecondOpcode) 2338 .addOperand(DestReg) 2339 .addOperand(DestReg) 2340 .addImm(ShAmt)); 2341 } 2342 2343 void RISCVAsmParser::emitVMSGE(MCInst &Inst, unsigned Opcode, SMLoc IDLoc, 2344 MCStreamer &Out) { 2345 if (Inst.getNumOperands() == 3) { 2346 // unmasked va >= x 2347 // 2348 // pseudoinstruction: vmsge{u}.vx vd, va, x 2349 // expansion: vmslt{u}.vx vd, va, x; vmnand.mm vd, vd, vd 2350 emitToStreamer(Out, MCInstBuilder(Opcode) 2351 .addOperand(Inst.getOperand(0)) 2352 .addOperand(Inst.getOperand(1)) 2353 .addOperand(Inst.getOperand(2)) 2354 .addReg(RISCV::NoRegister)); 2355 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM) 2356 .addOperand(Inst.getOperand(0)) 2357 .addOperand(Inst.getOperand(0)) 2358 .addOperand(Inst.getOperand(0))); 2359 } else if (Inst.getNumOperands() == 4) { 2360 // masked va >= x, vd != v0 2361 // 2362 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t 2363 // expansion: vmslt{u}.vx vd, va, x, v0.t; vmxor.mm vd, vd, v0 2364 assert(Inst.getOperand(0).getReg() != RISCV::V0 && 2365 "The destination register should not be V0."); 2366 emitToStreamer(Out, MCInstBuilder(Opcode) 2367 .addOperand(Inst.getOperand(0)) 2368 .addOperand(Inst.getOperand(1)) 2369 .addOperand(Inst.getOperand(2)) 2370 .addOperand(Inst.getOperand(3))); 2371 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM) 2372 .addOperand(Inst.getOperand(0)) 2373 .addOperand(Inst.getOperand(0)) 2374 .addReg(RISCV::V0)); 2375 } else if (Inst.getNumOperands() == 5 && 2376 Inst.getOperand(0).getReg() == RISCV::V0) { 2377 // masked va >= x, vd == v0 2378 // 2379 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt 2380 // expansion: vmslt{u}.vx vt, va, x; vmandn.mm vd, vd, vt 2381 assert(Inst.getOperand(0).getReg() == RISCV::V0 && 2382 "The destination register should be V0."); 2383 assert(Inst.getOperand(1).getReg() != RISCV::V0 && 2384 "The temporary vector register should not be V0."); 2385 emitToStreamer(Out, MCInstBuilder(Opcode) 2386 .addOperand(Inst.getOperand(1)) 2387 .addOperand(Inst.getOperand(2)) 2388 .addOperand(Inst.getOperand(3)) 2389 .addOperand(Inst.getOperand(4))); 2390 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM) 2391 .addOperand(Inst.getOperand(0)) 2392 .addOperand(Inst.getOperand(0)) 2393 .addOperand(Inst.getOperand(1))); 2394 } else if (Inst.getNumOperands() == 5) { 2395 // masked va >= x, any vd 2396 // 2397 // pseudoinstruction: vmsge{u}.vx vd, va, x, v0.t, vt 2398 // expansion: vmslt{u}.vx vt, va, x; vmandn.mm vt, v0, vt; vmandn.mm vd, 2399 // vd, v0; vmor.mm vd, vt, vd 2400 assert(Inst.getOperand(1).getReg() != RISCV::V0 && 2401 "The temporary vector register should not be V0."); 2402 emitToStreamer(Out, MCInstBuilder(Opcode) 2403 .addOperand(Inst.getOperand(1)) 2404 .addOperand(Inst.getOperand(2)) 2405 .addOperand(Inst.getOperand(3)) 2406 .addReg(RISCV::NoRegister)); 2407 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM) 2408 .addOperand(Inst.getOperand(1)) 2409 .addReg(RISCV::V0) 2410 .addOperand(Inst.getOperand(1))); 2411 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM) 2412 .addOperand(Inst.getOperand(0)) 2413 .addOperand(Inst.getOperand(0)) 2414 .addReg(RISCV::V0)); 2415 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM) 2416 .addOperand(Inst.getOperand(0)) 2417 .addOperand(Inst.getOperand(1)) 2418 .addOperand(Inst.getOperand(0))); 2419 } 2420 } 2421 2422 bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst, 2423 OperandVector &Operands) { 2424 assert(Inst.getOpcode() == RISCV::PseudoAddTPRel && "Invalid instruction"); 2425 assert(Inst.getOperand(2).isReg() && "Unexpected second operand kind"); 2426 if (Inst.getOperand(2).getReg() != RISCV::X4) { 2427 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc(); 2428 return Error(ErrorLoc, "the second input operand must be tp/x4 when using " 2429 "%tprel_add modifier"); 2430 } 2431 2432 return false; 2433 } 2434 2435 std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp() const { 2436 return RISCVOperand::createReg(RISCV::NoRegister, llvm::SMLoc(), 2437 llvm::SMLoc(), isRV64()); 2438 } 2439 2440 bool RISCVAsmParser::validateInstruction(MCInst &Inst, 2441 OperandVector &Operands) { 2442 if (Inst.getOpcode() == RISCV::PseudoVMSGEU_VX_M_T || 2443 Inst.getOpcode() == RISCV::PseudoVMSGE_VX_M_T) { 2444 unsigned DestReg = Inst.getOperand(0).getReg(); 2445 unsigned TempReg = Inst.getOperand(1).getReg(); 2446 if (DestReg == TempReg) { 2447 SMLoc Loc = Operands.back()->getStartLoc(); 2448 return Error(Loc, "The temporary vector register cannot be the same as " 2449 "the destination register."); 2450 } 2451 } 2452 2453 const MCInstrDesc &MCID = MII.get(Inst.getOpcode()); 2454 RISCVII::VConstraintType Constraints = 2455 RISCVII::getConstraint(MCID.TSFlags); 2456 if (Constraints == RISCVII::NoConstraint) 2457 return false; 2458 2459 unsigned DestReg = Inst.getOperand(0).getReg(); 2460 // Operands[1] will be the first operand, DestReg. 2461 SMLoc Loc = Operands[1]->getStartLoc(); 2462 if (Constraints & RISCVII::VS2Constraint) { 2463 unsigned CheckReg = Inst.getOperand(1).getReg(); 2464 if (DestReg == CheckReg) 2465 return Error(Loc, "The destination vector register group cannot overlap" 2466 " the source vector register group."); 2467 } 2468 if ((Constraints & RISCVII::VS1Constraint) && (Inst.getOperand(2).isReg())) { 2469 unsigned CheckReg = Inst.getOperand(2).getReg(); 2470 if (DestReg == CheckReg) 2471 return Error(Loc, "The destination vector register group cannot overlap" 2472 " the source vector register group."); 2473 } 2474 if ((Constraints & RISCVII::VMConstraint) && (DestReg == RISCV::V0)) { 2475 // vadc, vsbc are special cases. These instructions have no mask register. 2476 // The destination register could not be V0. 2477 unsigned Opcode = Inst.getOpcode(); 2478 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM || 2479 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM || 2480 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM || 2481 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM || 2482 Opcode == RISCV::VMERGE_VXM) 2483 return Error(Loc, "The destination vector register group cannot be V0."); 2484 2485 // Regardless masked or unmasked version, the number of operands is the 2486 // same. For example, "viota.m v0, v2" is "viota.m v0, v2, NoRegister" 2487 // actually. We need to check the last operand to ensure whether it is 2488 // masked or not. 2489 unsigned CheckReg = Inst.getOperand(Inst.getNumOperands() - 1).getReg(); 2490 assert((CheckReg == RISCV::V0 || CheckReg == RISCV::NoRegister) && 2491 "Unexpected register for mask operand"); 2492 2493 if (DestReg == CheckReg) 2494 return Error(Loc, "The destination vector register group cannot overlap" 2495 " the mask register."); 2496 } 2497 return false; 2498 } 2499 2500 bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 2501 OperandVector &Operands, 2502 MCStreamer &Out) { 2503 Inst.setLoc(IDLoc); 2504 2505 switch (Inst.getOpcode()) { 2506 default: 2507 break; 2508 case RISCV::PseudoLI: { 2509 MCRegister Reg = Inst.getOperand(0).getReg(); 2510 const MCOperand &Op1 = Inst.getOperand(1); 2511 if (Op1.isExpr()) { 2512 // We must have li reg, %lo(sym) or li reg, %pcrel_lo(sym) or similar. 2513 // Just convert to an addi. This allows compatibility with gas. 2514 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI) 2515 .addReg(Reg) 2516 .addReg(RISCV::X0) 2517 .addExpr(Op1.getExpr())); 2518 return false; 2519 } 2520 int64_t Imm = Inst.getOperand(1).getImm(); 2521 // On RV32 the immediate here can either be a signed or an unsigned 2522 // 32-bit number. Sign extension has to be performed to ensure that Imm 2523 // represents the expected signed 64-bit number. 2524 if (!isRV64()) 2525 Imm = SignExtend64<32>(Imm); 2526 emitLoadImm(Reg, Imm, Out); 2527 return false; 2528 } 2529 case RISCV::PseudoLLA: 2530 emitLoadLocalAddress(Inst, IDLoc, Out); 2531 return false; 2532 case RISCV::PseudoLA: 2533 emitLoadAddress(Inst, IDLoc, Out); 2534 return false; 2535 case RISCV::PseudoLA_TLS_IE: 2536 emitLoadTLSIEAddress(Inst, IDLoc, Out); 2537 return false; 2538 case RISCV::PseudoLA_TLS_GD: 2539 emitLoadTLSGDAddress(Inst, IDLoc, Out); 2540 return false; 2541 case RISCV::PseudoLB: 2542 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out, /*HasTmpReg=*/false); 2543 return false; 2544 case RISCV::PseudoLBU: 2545 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out, /*HasTmpReg=*/false); 2546 return false; 2547 case RISCV::PseudoLH: 2548 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out, /*HasTmpReg=*/false); 2549 return false; 2550 case RISCV::PseudoLHU: 2551 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out, /*HasTmpReg=*/false); 2552 return false; 2553 case RISCV::PseudoLW: 2554 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out, /*HasTmpReg=*/false); 2555 return false; 2556 case RISCV::PseudoLWU: 2557 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out, /*HasTmpReg=*/false); 2558 return false; 2559 case RISCV::PseudoLD: 2560 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out, /*HasTmpReg=*/false); 2561 return false; 2562 case RISCV::PseudoFLH: 2563 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out, /*HasTmpReg=*/true); 2564 return false; 2565 case RISCV::PseudoFLW: 2566 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out, /*HasTmpReg=*/true); 2567 return false; 2568 case RISCV::PseudoFLD: 2569 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out, /*HasTmpReg=*/true); 2570 return false; 2571 case RISCV::PseudoSB: 2572 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out, /*HasTmpReg=*/true); 2573 return false; 2574 case RISCV::PseudoSH: 2575 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out, /*HasTmpReg=*/true); 2576 return false; 2577 case RISCV::PseudoSW: 2578 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out, /*HasTmpReg=*/true); 2579 return false; 2580 case RISCV::PseudoSD: 2581 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out, /*HasTmpReg=*/true); 2582 return false; 2583 case RISCV::PseudoFSH: 2584 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out, /*HasTmpReg=*/true); 2585 return false; 2586 case RISCV::PseudoFSW: 2587 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out, /*HasTmpReg=*/true); 2588 return false; 2589 case RISCV::PseudoFSD: 2590 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, /*HasTmpReg=*/true); 2591 return false; 2592 case RISCV::PseudoAddTPRel: 2593 if (checkPseudoAddTPRel(Inst, Operands)) 2594 return true; 2595 break; 2596 case RISCV::PseudoSEXT_B: 2597 emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/8, IDLoc, Out); 2598 return false; 2599 case RISCV::PseudoSEXT_H: 2600 emitPseudoExtend(Inst, /*SignExtend=*/true, /*Width=*/16, IDLoc, Out); 2601 return false; 2602 case RISCV::PseudoZEXT_H: 2603 emitPseudoExtend(Inst, /*SignExtend=*/false, /*Width=*/16, IDLoc, Out); 2604 return false; 2605 case RISCV::PseudoZEXT_W: 2606 emitPseudoExtend(Inst, /*SignExtend=*/false, /*Width=*/32, IDLoc, Out); 2607 return false; 2608 case RISCV::PseudoVMSGEU_VX: 2609 case RISCV::PseudoVMSGEU_VX_M: 2610 case RISCV::PseudoVMSGEU_VX_M_T: 2611 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out); 2612 return false; 2613 case RISCV::PseudoVMSGE_VX: 2614 case RISCV::PseudoVMSGE_VX_M: 2615 case RISCV::PseudoVMSGE_VX_M_T: 2616 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out); 2617 return false; 2618 case RISCV::PseudoVMSGE_VI: 2619 case RISCV::PseudoVMSLT_VI: { 2620 // These instructions are signed and so is immediate so we can subtract one 2621 // and change the opcode. 2622 int64_t Imm = Inst.getOperand(2).getImm(); 2623 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI 2624 : RISCV::VMSLE_VI; 2625 emitToStreamer(Out, MCInstBuilder(Opc) 2626 .addOperand(Inst.getOperand(0)) 2627 .addOperand(Inst.getOperand(1)) 2628 .addImm(Imm - 1) 2629 .addOperand(Inst.getOperand(3))); 2630 return false; 2631 } 2632 case RISCV::PseudoVMSGEU_VI: 2633 case RISCV::PseudoVMSLTU_VI: { 2634 int64_t Imm = Inst.getOperand(2).getImm(); 2635 // Unsigned comparisons are tricky because the immediate is signed. If the 2636 // immediate is 0 we can't just subtract one. vmsltu.vi v0, v1, 0 is always 2637 // false, but vmsle.vi v0, v1, -1 is always true. Instead we use 2638 // vmsne v0, v1, v1 which is always false. 2639 if (Imm == 0) { 2640 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGEU_VI 2641 ? RISCV::VMSEQ_VV 2642 : RISCV::VMSNE_VV; 2643 emitToStreamer(Out, MCInstBuilder(Opc) 2644 .addOperand(Inst.getOperand(0)) 2645 .addOperand(Inst.getOperand(1)) 2646 .addOperand(Inst.getOperand(1)) 2647 .addOperand(Inst.getOperand(3))); 2648 } else { 2649 // Other immediate values can subtract one like signed. 2650 unsigned Opc = Inst.getOpcode() == RISCV::PseudoVMSGEU_VI 2651 ? RISCV::VMSGTU_VI 2652 : RISCV::VMSLEU_VI; 2653 emitToStreamer(Out, MCInstBuilder(Opc) 2654 .addOperand(Inst.getOperand(0)) 2655 .addOperand(Inst.getOperand(1)) 2656 .addImm(Imm - 1) 2657 .addOperand(Inst.getOperand(3))); 2658 } 2659 2660 return false; 2661 } 2662 } 2663 2664 emitToStreamer(Out, Inst); 2665 return false; 2666 } 2667 2668 extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser() { 2669 RegisterMCAsmParser<RISCVAsmParser> X(getTheRISCV32Target()); 2670 RegisterMCAsmParser<RISCVAsmParser> Y(getTheRISCV64Target()); 2671 } 2672