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