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