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