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