52#define DEBUG_TYPE "riscv-asm-parser"
55 "Number of RISC-V Compressed instructions emitted");
63struct ParserOptionsSet {
70 enum class VTypeState {
81 ParserOptionsSet ParserOptions;
83 SMLoc getLoc()
const {
return getParser().
getTok().
getLoc(); }
84 bool isRV64()
const {
return getSTI().hasFeature(RISCV::Feature64Bit); }
85 bool isRVE()
const {
return getSTI().hasFeature(RISCV::FeatureStdExtE); }
86 bool enableExperimentalExtension()
const {
87 return getSTI().hasFeature(RISCV::Experimental);
90 RISCVTargetStreamer &getTargetStreamer() {
91 assert(getParser().getStreamer().getTargetStreamer() &&
92 "do not have a target streamer");
93 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
94 return static_cast<RISCVTargetStreamer &
>(TS);
97 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
98 unsigned Kind)
override;
100 bool generateImmOutOfRangeError(SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
103 struct NearMissMessage {
108 std::string getCustomOperandDiag(
unsigned MatchError);
110 void FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
111 SmallVectorImpl<NearMissMessage> &NearMissesOut,
113 void ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses, SMLoc IDLoc,
116 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
119 bool MatchingInlineAsm)
override;
122 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
123 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
124 SMLoc &EndLoc)
override;
126 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
129 ParseStatus parseDirective(AsmToken DirectiveID)
override;
131 bool parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
unsigned &Sew,
132 unsigned &Lmul,
bool &Fractional,
bool &TailAgnostic,
133 bool &MaskAgnostic,
bool &AltFmt);
134 bool generateVTypeError(SMLoc ErrorLoc);
136 bool generateXSfmmVTypeError(SMLoc ErrorLoc);
139 void emitToStreamer(MCStreamer &S,
const MCInst &Inst);
143 void emitLoadImm(MCRegister DestReg, int64_t
Value, MCStreamer &Out);
147 void emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
149 unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out);
152 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
155 void emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
158 void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
162 void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
166 void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
169 void emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
170 MCStreamer &Out,
bool HasTmpReg);
175 void emitQCELILoadStoreSymbol(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
176 MCStreamer &Out,
bool HasTmpReg);
179 void emitPseudoExtend(MCInst &Inst,
bool SignExtend, int64_t Width,
180 SMLoc IDLoc, MCStreamer &Out);
183 void emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc, MCStreamer &Out);
189 bool checkPseudoAddTPRel(MCInst &Inst,
OperandVector &Operands);
195 bool checkPseudoTLSDESCCall(MCInst &Inst,
OperandVector &Operands);
198 bool validateInstruction(MCInst &Inst,
OperandVector &Operands);
204 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
OperandVector &Operands,
208#define GET_ASSEMBLER_HEADER
209#include "RISCVGenAsmMatcher.inc"
238 return parseRegList(Operands,
true);
244 bool ExpectNegative =
false);
246 return parseZcmpStackAdj(Operands,
true);
249 bool parseOperand(
OperandVector &Operands, StringRef Mnemonic);
250 bool parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
251 bool parseDataExpr(
const MCExpr *&Res)
override;
253 bool parseDirectiveOption();
254 bool parseDirectiveAttribute();
255 bool parseDirectiveInsn(SMLoc L);
256 bool parseDirectiveVariantCC();
261 bool resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
262 bool FromOptionDirective);
264 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
266 MCSubtargetInfo &STI = copySTI();
272 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
276 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
278 MCSubtargetInfo &STI = copySTI();
279 setAvailableFeatures(
284 void pushFeatureBits() {
285 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
286 "These two stacks must be kept synchronized");
287 FeatureBitStack.push_back(getSTI().getFeatureBits());
288 ParserOptionsStack.push_back(ParserOptions);
291 bool popFeatureBits() {
292 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
293 "These two stacks must be kept synchronized");
294 if (FeatureBitStack.empty())
297 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
298 copySTI().setFeatureBits(FeatureBits);
299 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
301 ParserOptions = ParserOptionsStack.pop_back_val();
306 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
307 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
308 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
309 std::unique_ptr<RISCVOperand> defaultSMTVType();
312 enum RISCVMatchResultTy :
unsigned {
313 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
314#define GET_OPERAND_DIAGNOSTIC_TYPES
315#include "RISCVGenAsmMatcher.inc"
316#undef GET_OPERAND_DIAGNOSTIC_TYPES
320 static bool isSymbolDiff(
const MCExpr *Expr);
322 RISCVAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
323 const MCInstrInfo &MII)
324 : MCTargetAsmParser(STI, MII) {
331 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
333 auto ABIName = StringRef(getTargetOptions().ABIName);
334 if (ABIName.ends_with(
"f") && !getSTI().
hasFeature(RISCV::FeatureStdExtF)) {
335 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
336 "doesn't support the F instruction set extension (ignoring "
338 }
else if (ABIName.ends_with(
"d") &&
339 !getSTI().
hasFeature(RISCV::FeatureStdExtD)) {
340 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
341 "doesn't support the D instruction set extension (ignoring "
353 getTargetStreamer().emitTargetAttributes(STI,
false);
424 MCRegister OffsetReg;
427 SMLoc StartLoc, EndLoc;
443 RISCVOperand(KindTy K) : Kind(
K) {}
446 RISCVOperand(
const RISCVOperand &o) : MCParsedAsmOperand() {
448 StartLoc =
o.StartLoc;
451 case KindTy::Register:
454 case KindTy::Expression:
457 case KindTy::FPImmediate:
463 case KindTy::SystemRegister:
469 case KindTy::SMTVType:
470 SMTVType =
o.SMTVType;
478 case KindTy::RegList:
481 case KindTy::StackAdj:
482 StackAdj =
o.StackAdj;
490 bool isToken()
const override {
return Kind == KindTy::Token; }
491 bool isReg()
const override {
return Kind == KindTy::Register; }
492 bool isExpr()
const {
return Kind == KindTy::Expression; }
493 bool isV0Reg()
const {
494 return Kind == KindTy::Register &&
Reg.Reg == RISCV::V0;
496 bool isAnyReg()
const {
497 return Kind == KindTy::Register &&
498 (getRISCVMCRegisterClass(RISCV::GPRRegClassID).contains(
Reg.Reg) ||
499 getRISCVMCRegisterClass(RISCV::FPR64RegClassID).contains(
Reg.Reg) ||
500 getRISCVMCRegisterClass(RISCV::VRRegClassID).contains(
Reg.Reg));
502 bool isAnyRegC()
const {
503 return Kind == KindTy::Register &&
504 (getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(
Reg.Reg) ||
505 getRISCVMCRegisterClass(RISCV::FPR64CRegClassID).contains(
Reg.Reg));
507 bool isImm()
const override {
return isExpr(); }
508 bool isMem()
const override {
return false; }
509 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
510 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
511 bool isRegList()
const {
return Kind == KindTy::RegList; }
512 bool isRegListS0()
const {
513 return Kind == KindTy::RegList && RegList.Encoding !=
RISCVZC::RA;
515 bool isStackAdj()
const {
return Kind == KindTy::StackAdj; }
518 return Kind == KindTy::Register &&
519 getRISCVMCRegisterClass(RISCV::GPRRegClassID).contains(
Reg.Reg);
522 bool isYGPR()
const {
523 return Kind == KindTy::Register &&
524 getRISCVMCRegisterClass(RISCV::YGPRRegClassID).contains(
Reg.Reg);
527 bool isGPRPair()
const {
528 return Kind == KindTy::Register &&
529 getRISCVMCRegisterClass(RISCV::GPRPairRegClassID).contains(
Reg.Reg);
532 bool isGPRPairC()
const {
533 return Kind == KindTy::Register &&
534 getRISCVMCRegisterClass(RISCV::GPRPairCRegClassID).contains(
Reg.Reg);
537 bool isGPRPairNoX0()
const {
538 return Kind == KindTy::Register &&
539 getRISCVMCRegisterClass(RISCV::GPRPairNoX0RegClassID)
543 bool isGPRF16()
const {
544 return Kind == KindTy::Register &&
545 getRISCVMCRegisterClass(RISCV::GPRF16RegClassID).contains(
Reg.Reg);
548 bool isGPRF32()
const {
549 return Kind == KindTy::Register &&
550 getRISCVMCRegisterClass(RISCV::GPRF32RegClassID).contains(
Reg.Reg);
553 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
554 bool isGPRAsFPR16()
const {
return isGPRF16() &&
Reg.IsGPRAsFPR; }
555 bool isGPRAsFPR32()
const {
return isGPRF32() &&
Reg.IsGPRAsFPR; }
556 bool isGPRPairAsFPR64()
const {
return isGPRPair() &&
Reg.IsGPRAsFPR; }
558 static bool evaluateConstantExpr(
const MCExpr *Expr, int64_t &Imm) {
560 Imm =
CE->getValue();
569 template <
int N>
bool isBareSimmNLsb0()
const {
574 if (evaluateConstantExpr(
getExpr(), Imm))
575 return isShiftedInt<
N - 1, 1>(fixImmediateForRV32(Imm, isRV64Expr()));
578 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
584 template <
int N>
bool isBareSimmN()
const {
589 if (evaluateConstantExpr(
getExpr(), Imm))
590 return isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
593 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
599 bool isBareSymbol()
const {
602 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
606 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
610 bool isCallSymbol()
const {
613 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
617 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
621 bool isPseudoJumpSymbol()
const {
624 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
628 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
632 bool isTPRelAddSymbol()
const {
635 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
639 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
640 VK == ELF::R_RISCV_TPREL_ADD;
643 bool isTLSDESCCallSymbol()
const {
646 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
650 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
651 VK == ELF::R_RISCV_TLSDESC_CALL;
654 bool isQCAccessSymbol()
const {
657 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
661 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
665 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
669 bool isVTypeI10()
const {
670 if (Kind == KindTy::VType)
674 bool isVTypeI11()
const {
675 if (Kind == KindTy::VType)
680 bool isXSfmmVType()
const {
684 bool isTileLambda()
const {
685 return isUImmPred([](int64_t Imm) {
return Imm &&
isUInt<3>(Imm); });
690 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
693 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
694 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
699 bool isSMTVType()
const {
700 return Kind == KindTy::SMTVType &&
704 bool isSMTI8()
const {
709 bool isLoadFPImm()
const {
712 if (Kind != KindTy::FPImmediate)
715 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
718 return Idx >= 0 && Idx != 1;
721 bool isImmXLenLI()
const {
727 if (evaluateConstantExpr(
getExpr(), Imm))
730 return RISCVAsmParser::isSymbolDiff(
getExpr());
733 bool isImmXLenLI_Restricted()
const {
737 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
739 return IsConstantImm &&
743 template <
unsigned N>
bool isUImm()
const {
747 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
751 template <
unsigned N,
unsigned S>
bool isUImmShifted()
const {
755 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
759 template <
class Pred>
bool isUImmPred(Pred p)
const {
763 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
764 return IsConstantImm &&
p(Imm);
767 bool isUImmLog2XLen()
const {
768 if (isExpr() && isRV64Expr())
773 bool isUImmLog2XLenNonZero()
const {
774 if (isExpr() && isRV64Expr())
775 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<6>(Imm); });
776 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<5>(Imm); });
779 bool isUImmLog2XLenHalf()
const {
780 if (isExpr() && isRV64Expr())
785 bool isUImm1()
const {
return isUImm<1>(); }
786 bool isUImm2()
const {
return isUImm<2>(); }
787 bool isUImm3()
const {
return isUImm<3>(); }
788 bool isUImm4()
const {
return isUImm<4>(); }
789 bool isUImm5()
const {
return isUImm<5>(); }
790 bool isUImm6()
const {
return isUImm<6>(); }
791 bool isUImm7()
const {
return isUImm<7>(); }
792 bool isUImm8()
const {
return isUImm<8>(); }
793 bool isUImm9()
const {
return isUImm<9>(); }
794 bool isUImm10()
const {
return isUImm<10>(); }
795 bool isUImm11()
const {
return isUImm<11>(); }
796 bool isUImm16()
const {
return isUImm<16>(); }
797 bool isUImm20()
const {
return isUImm<20>(); }
798 bool isUImm32()
const {
return isUImm<32>(); }
799 bool isUImm48()
const {
return isUImm<48>(); }
800 bool isUImm64()
const {
return isUImm<64>(); }
802 bool isUImm5NonZero()
const {
803 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<5>(Imm); });
806 bool isUImm5GT3()
const {
807 return isUImmPred([](int64_t Imm) {
return isUInt<5>(Imm) &&
Imm > 3; });
810 bool isUImm4Plus1()
const {
812 [](int64_t Imm) {
return Imm > 0 &&
isUInt<4>(Imm - 1); });
815 bool isUImm5Plus1()
const {
817 [](int64_t Imm) {
return Imm > 0 &&
isUInt<5>(Imm - 1); });
820 bool isUImm6Plus1()
const {
822 [](int64_t Imm) {
return Imm > 0 &&
isUInt<6>(Imm - 1); });
825 bool isUImm5GE6Plus1()
const {
827 [](int64_t Imm) {
return Imm >= 6 &&
isUInt<5>(Imm - 1); });
830 bool isUImm5Slist()
const {
831 return isUImmPred([](int64_t Imm) {
832 return (Imm == 0) || (
Imm == 1) || (Imm == 2) || (
Imm == 4) ||
833 (Imm == 8) || (
Imm == 16) || (Imm == 15) || (
Imm == 31);
837 bool isUImm7EqXLen()
const {
839 [
this](int64_t Imm) {
return isRV64Expr() ?
Imm == 64 :
Imm == 32; });
842 bool isUImm8GE32()
const {
843 return isUImmPred([](int64_t Imm) {
return isUInt<8>(Imm) &&
Imm >= 32; });
846 bool isRnumArg()
const {
848 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(10); });
851 bool isRnumArg_0_7()
const {
853 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(7); });
856 bool isRnumArg_1_10()
const {
858 [](int64_t Imm) {
return Imm >= INT64_C(1) &&
Imm <= INT64_C(10); });
861 bool isRnumArg_2_14()
const {
863 [](int64_t Imm) {
return Imm >= INT64_C(2) &&
Imm <= INT64_C(14); });
866 template <
unsigned N>
bool isSImm()
const {
870 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
871 return IsConstantImm &&
isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
874 bool isYBNDSWImm()
const {
879 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
883 template <
class Pred>
bool isSImmPred(Pred p)
const {
887 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
888 return IsConstantImm &&
p(fixImmediateForRV32(Imm, isRV64Expr()));
891 bool isSImm5()
const {
return isSImm<5>(); }
892 bool isSImm6()
const {
return isSImm<6>(); }
893 bool isSImm10()
const {
return isSImm<10>(); }
894 bool isSImm11()
const {
return isSImm<11>(); }
895 bool isSImm12()
const {
return isSImm<12>(); }
896 bool isSImm16()
const {
return isSImm<16>(); }
897 bool isSImm26()
const {
return isSImm<26>(); }
899 bool isSImm5NonZero()
const {
900 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<5>(Imm); });
903 bool isSImm6NonZero()
const {
904 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<6>(Imm); });
907 bool isCLUIImm()
const {
908 return isUImmPred([](int64_t Imm) {
909 return (
isUInt<5>(Imm) && Imm != 0) || (
Imm >= 0xfffe0 &&
Imm <= 0xfffff);
913 bool isUImm2Lsb0()
const {
return isUImmShifted<1, 1>(); }
915 bool isUImm5Lsb0()
const {
return isUImmShifted<4, 1>(); }
917 bool isUImm6Lsb0()
const {
return isUImmShifted<5, 1>(); }
919 bool isUImm7Lsb00()
const {
return isUImmShifted<5, 2>(); }
921 bool isUImm7Lsb000()
const {
return isUImmShifted<4, 3>(); }
923 bool isUImm8Lsb00()
const {
return isUImmShifted<6, 2>(); }
925 bool isUImm8Lsb000()
const {
return isUImmShifted<5, 3>(); }
927 bool isUImm9Lsb000()
const {
return isUImmShifted<6, 3>(); }
929 bool isUImm14Lsb00()
const {
return isUImmShifted<12, 2>(); }
931 bool isUImm10Lsb00NonZero()
const {
938 static int64_t fixImmediateForRV32(int64_t Imm,
bool IsRV64Imm) {
944 bool isSImm12LO()
const {
949 if (evaluateConstantExpr(
getExpr(), Imm))
950 return isInt<12>(fixImmediateForRV32(Imm, isRV64Expr()));
953 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
956 VK == ELF::R_RISCV_TLSDESC_ADD_LO12);
959 bool isSImm12Lsb00000()
const {
963 bool isSImm10Lsb0000NonZero()
const {
968 bool isSImm16NonZero()
const {
969 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<16>(Imm); });
972 bool isUImm16NonZero()
const {
973 return isUImmPred([](int64_t Imm) {
return isUInt<16>(Imm) &&
Imm != 0; });
976 bool isSImm20LI()
const {
981 if (evaluateConstantExpr(
getExpr(), Imm))
982 return isInt<20>(fixImmediateForRV32(Imm, isRV64Expr()));
985 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
989 bool isSImm8PLI_B()
const {
return isSImm<8>() || isUImm<8>(); }
990 bool isSImm10PLUI()
const {
return isSImm<10>() || isUImm<10>(); }
992 bool isSImm10PLI_H()
const {
993 return isSImm<10>() || isUImmPred([](int64_t Imm) {
997 bool isSImm10PLI_W()
const {
998 return isSImm<10>() || isUImmPred([](int64_t Imm) {
1003 bool isUImm20LUI()
const {
1008 if (evaluateConstantExpr(
getExpr(), Imm))
1012 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
1013 (VK == ELF::R_RISCV_HI20 || VK == ELF::R_RISCV_TPREL_HI20);
1016 bool isUImm20AUIPC()
const {
1021 if (evaluateConstantExpr(
getExpr(), Imm))
1025 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
1027 VK == ELF::R_RISCV_TLS_GOT_HI20 || VK == ELF::R_RISCV_TLS_GD_HI20 ||
1028 VK == ELF::R_RISCV_TLSDESC_HI20);
1031 bool isImmZero()
const {
1032 return isUImmPred([](int64_t Imm) {
return 0 ==
Imm; });
1035 bool isImmThree()
const {
1036 return isUImmPred([](int64_t Imm) {
return 3 ==
Imm; });
1039 bool isImmFour()
const {
1040 return isUImmPred([](int64_t Imm) {
return 4 ==
Imm; });
1043 bool isImm5Zibi()
const {
1045 [](int64_t Imm) {
return (Imm != 0 &&
isUInt<5>(Imm)) ||
Imm == -1; });
1048 bool isSImm5Plus1()
const {
1053 bool isSImm18()
const {
1054 return isSImmPred([](int64_t Imm) {
return isInt<18>(Imm); });
1057 bool isSImm18Lsb0()
const {
1061 bool isSImm19Lsb00()
const {
1065 bool isSImm20Lsb000()
const {
1069 bool isSImm32Lsb0()
const {
1074 SMLoc getStartLoc()
const override {
return StartLoc; }
1076 SMLoc getEndLoc()
const override {
return EndLoc; }
1079 bool isRV64Expr()
const {
1080 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1084 MCRegister
getReg()
const override {
1085 assert(Kind == KindTy::Register &&
"Invalid type access!");
1089 StringRef getSysReg()
const {
1090 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
1091 return StringRef(SysReg.Data, SysReg.Length);
1094 const MCExpr *
getExpr()
const {
1095 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1099 uint64_t getFPConst()
const {
1100 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1105 assert(Kind == KindTy::Token &&
"Invalid type access!");
1109 unsigned getVType()
const {
1110 assert(Kind == KindTy::VType &&
"Invalid type access!");
1115 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1119 unsigned getFence()
const {
1120 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1125 assert(Kind == KindTy::SMTVType &&
"Invalid type access!");
1126 return SMTVType.SMTVType;
1129 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1138 case KindTy::Expression:
1141 OS <<
' ' << (Expr.IsRV64 ?
"rv64" :
"rv32") <<
'>';
1143 case KindTy::FPImmediate:
1144 OS <<
"<fpimm: " << FPImm.Val <<
">";
1146 case KindTy::Register:
1148 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1153 case KindTy::SystemRegister:
1154 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1163 OS << roundingModeToString(getFRM());
1166 case KindTy::SMTVType:
1167 OS <<
"<smtvtype: ";
1168 OS << SMTVTypeModeToString(getSMTVType());
1176 case KindTy::RegList:
1181 case KindTy::StackAdj:
1182 OS <<
"<stackadj: ";
1186 case KindTy::RegReg:
1187 OS <<
"<RegReg: BaseReg " <<
RegName(
RegReg.BaseReg) <<
" OffsetReg "
1193 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1194 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1201 static std::unique_ptr<RISCVOperand>
1202 createReg(MCRegister
Reg, SMLoc S, SMLoc
E,
bool IsGPRAsFPR =
false) {
1203 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1205 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1211 static std::unique_ptr<RISCVOperand> createExpr(
const MCExpr *Val, SMLoc S,
1212 SMLoc
E,
bool IsRV64) {
1213 auto Op = std::make_unique<RISCVOperand>(KindTy::Expression);
1214 Op->Expr.Expr = Val;
1215 Op->Expr.IsRV64 = IsRV64;
1221 static std::unique_ptr<RISCVOperand> createFPImm(uint64_t Val, SMLoc S) {
1222 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1223 Op->FPImm.Val = Val;
1229 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1230 unsigned Encoding) {
1231 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1232 Op->SysReg.Data = Str.data();
1233 Op->SysReg.Length = Str.size();
1240 static std::unique_ptr<RISCVOperand>
1242 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1249 static std::unique_ptr<RISCVOperand>
1251 auto Op = std::make_unique<RISCVOperand>(KindTy::SMTVType);
1252 Op->SMTVType.SMTVType = VType;
1258 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val, SMLoc S) {
1259 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1260 Op->Fence.Val = Val;
1266 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI, SMLoc S) {
1267 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1268 Op->VType.Val = VTypeI;
1274 static std::unique_ptr<RISCVOperand> createRegList(
unsigned RlistEncode,
1276 auto Op = std::make_unique<RISCVOperand>(KindTy::RegList);
1282 static std::unique_ptr<RISCVOperand>
1283 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {
1284 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1286 Op->RegReg.OffsetReg = OffsetReg;
1292 static std::unique_ptr<RISCVOperand> createStackAdj(
unsigned StackAdj, SMLoc S) {
1293 auto Op = std::make_unique<RISCVOperand>(KindTy::StackAdj);
1294 Op->StackAdj.Val = StackAdj;
1299 static void addExpr(MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1300 assert(Expr &&
"Expr shouldn't be null!");
1302 bool IsConstant = evaluateConstantExpr(Expr, Imm);
1312 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1313 assert(
N == 1 &&
"Invalid number of operands!");
1317 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1318 assert(
N == 1 &&
"Invalid number of operands!");
1319 addExpr(Inst,
getExpr(), isRV64Expr());
1322 template <
unsigned Bits>
1323 void addSExtImmOperands(MCInst &Inst,
unsigned N)
const {
1324 assert(
N == 1 &&
"Invalid number of operands!");
1331 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
1332 assert(
N == 1 &&
"Invalid number of operands!");
1334 addExpr(Inst,
getExpr(), isRV64Expr());
1339 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1343 void addFenceArgOperands(MCInst &Inst,
unsigned N)
const {
1344 assert(
N == 1 &&
"Invalid number of operands!");
1348 void addCSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
1349 assert(
N == 1 &&
"Invalid number of operands!");
1356 void addVTypeIOperands(MCInst &Inst,
unsigned N)
const {
1357 assert(
N == 1 &&
"Invalid number of operands!");
1359 if (Kind == KindTy::Expression) {
1360 [[maybe_unused]]
bool IsConstantImm =
1361 evaluateConstantExpr(
getExpr(), Imm);
1362 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1369 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1370 assert(
N == 1 &&
"Invalid number of operands!");
1374 void addRegRegOperands(MCInst &Inst,
unsigned N)
const {
1375 assert(
N == 2 &&
"Invalid number of operands!");
1380 void addStackAdjOperands(MCInst &Inst,
unsigned N)
const {
1381 assert(
N == 1 &&
"Invalid number of operands!");
1385 void addFRMArgOperands(MCInst &Inst,
unsigned N)
const {
1386 assert(
N == 1 &&
"Invalid number of operands!");
1390 void addSMTVTypeOperand(MCInst &Inst,
unsigned N)
const {
1391 assert(
N == 1 &&
"Invalid number of operands!");
1397#define GET_REGISTER_MATCHER
1398#define GET_SUBTARGET_FEATURE_NAME
1399#define GET_MATCHER_IMPLEMENTATION
1400#define GET_MNEMONIC_SPELL_CHECKER
1401#include "RISCVGenAsmMatcher.inc"
1404 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1405 return Reg - RISCV::F0_D + RISCV::F0_H;
1409 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1410 return Reg - RISCV::F0_D + RISCV::F0_F;
1414 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1415 return Reg - RISCV::F0_D + RISCV::F0_Q;
1419 assert(
Reg >= RISCV::X0 &&
Reg <= RISCV::X31 &&
"Invalid register");
1420 return Reg - RISCV::X0 + RISCV::X0_Y;
1425 unsigned RegClassID;
1426 if (Kind == MCK_VRM2)
1427 RegClassID = RISCV::VRM2RegClassID;
1428 else if (Kind == MCK_VRM4)
1429 RegClassID = RISCV::VRM4RegClassID;
1430 else if (Kind == MCK_VRM8)
1431 RegClassID = RISCV::VRM8RegClassID;
1435 &getRISCVMCRegisterClass(RegClassID));
1439 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1440 return Reg - RISCV::F0_D + RISCV::F0_Q2;
1445 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1447 return Match_InvalidOperand;
1449 MCRegister
Reg =
Op.getReg();
1451 getRISCVMCRegisterClass(RISCV::FPR64RegClassID).contains(
Reg);
1453 getRISCVMCRegisterClass(RISCV::FPR64CRegClassID).contains(
Reg);
1454 bool IsRegVR = getRISCVMCRegisterClass(RISCV::VRRegClassID).contains(
Reg);
1456 if (
Op.isGPR() && Kind == MCK_YGPR) {
1459 return Match_Success;
1461 if (IsRegFPR64 && Kind == MCK_FPR256) {
1463 return Match_Success;
1465 if (IsRegFPR64 && Kind == MCK_FPR128) {
1467 return Match_Success;
1471 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1472 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1474 return Match_Success;
1478 if (IsRegFPR64 && Kind == MCK_FPR16) {
1480 return Match_Success;
1482 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1483 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_H;
1484 return Match_Success;
1486 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1487 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_W;
1488 return Match_Success;
1495 if (getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg) &&
1496 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1498 return Match_Success;
1502 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1505 return Match_InvalidOperand;
1506 return Match_Success;
1508 return Match_InvalidOperand;
1511bool RISCVAsmParser::generateImmOutOfRangeError(
1512 SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
1513 const Twine &
Msg =
"immediate must be an integer in the range") {
1520std::string RISCVAsmParser::getCustomOperandDiag(
unsigned MatchError) {
1522 StringRef
Msg =
"immediate must be an integer in the range") {
1523 return (
Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]").str();
1526 switch (MatchError) {
1530 if (
const char *Diag = getMatchKindDiag((RISCVMatchResultTy)MatchError))
1532 return std::string();
1533 case Match_InvalidImmXLenLI:
1535 return "operand must be a constant 64-bit integer";
1536 return Range(std::numeric_limits<int32_t>::min(),
1537 std::numeric_limits<uint32_t>::max());
1538 case Match_InvalidImmXLenLI_Restricted:
1540 return "operand either must be a constant 64-bit integer "
1541 "or a bare symbol name";
1542 return Range(std::numeric_limits<int32_t>::min(),
1543 std::numeric_limits<uint32_t>::max(),
1544 "operand either must be a bare symbol name or an immediate "
1545 "integer in the range");
1546 case Match_InvalidUImmLog2XLen:
1548 return Range(0, (1 << 6) - 1);
1549 return Range(0, (1 << 5) - 1);
1550 case Match_InvalidUImmLog2XLenNonZero:
1552 return Range(1, (1 << 6) - 1);
1553 return Range(1, (1 << 5) - 1);
1554 case Match_InvalidUImm1:
1555 return Range(0, (1 << 1) - 1);
1556 case Match_InvalidUImm2:
1557 return Range(0, (1 << 2) - 1);
1558 case Match_InvalidUImm2Lsb0:
1559 return Range(0, 2,
"immediate must be one of");
1560 case Match_InvalidUImm3:
1561 return Range(0, (1 << 3) - 1);
1562 case Match_InvalidUImm4:
1563 return Range(0, (1 << 4) - 1);
1564 case Match_InvalidUImm4Plus1:
1565 return Range(1, (1 << 4));
1566 case Match_InvalidUImm5:
1567 return Range(0, (1 << 5) - 1);
1568 case Match_InvalidUImm5NonZero:
1569 return Range(1, (1 << 5) - 1);
1570 case Match_InvalidUImm5GT3:
1571 return Range(4, (1 << 5) - 1);
1572 case Match_InvalidUImm5Plus1:
1573 return Range(1, (1 << 5));
1574 case Match_InvalidUImm5GE6Plus1:
1575 return Range(6, (1 << 5));
1576 case Match_InvalidUImm5Slist:
1577 return "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31";
1578 case Match_InvalidUImm6:
1579 return Range(0, (1 << 6) - 1);
1580 case Match_InvalidUImm6Plus1:
1581 return Range(1, (1 << 6));
1582 case Match_InvalidUImm7:
1583 return Range(0, (1 << 7) - 1);
1584 case Match_InvalidUImm8:
1585 return Range(0, (1 << 8) - 1);
1586 case Match_InvalidUImm8GE32:
1587 return Range(32, (1 << 8) - 1);
1588 case Match_InvalidSImm5:
1589 return Range(-(1 << 4), (1 << 4) - 1);
1590 case Match_InvalidSImm5NonZero:
1591 return Range(-(1 << 4), (1 << 4) - 1,
1592 "immediate must be non-zero in the range");
1593 case Match_InvalidSImm6:
1594 return Range(-(1 << 5), (1 << 5) - 1);
1595 case Match_InvalidSImm6NonZero:
1596 return Range(-(1 << 5), (1 << 5) - 1,
1597 "immediate must be non-zero in the range");
1598 case Match_InvalidCLUIImm:
1599 return Range(1, (1 << 5) - 1,
"immediate must be in [0xfffe0, 0xfffff] or");
1600 case Match_InvalidUImm5Lsb0:
1601 return Range(0, (1 << 5) - 2,
1602 "immediate must be a multiple of 2 bytes in the range");
1603 case Match_InvalidUImm6Lsb0:
1604 return Range(0, (1 << 6) - 2,
1605 "immediate must be a multiple of 2 bytes in the range");
1606 case Match_InvalidUImm7Lsb00:
1607 return Range(0, (1 << 7) - 4,
1608 "immediate must be a multiple of 4 bytes in the range");
1609 case Match_InvalidUImm8Lsb00:
1610 return Range(0, (1 << 8) - 4,
1611 "immediate must be a multiple of 4 bytes in the range");
1612 case Match_InvalidUImm8Lsb000:
1613 return Range(0, (1 << 8) - 8,
1614 "immediate must be a multiple of 8 bytes in the range");
1615 case Match_InvalidUImm9:
1616 return Range(0, (1 << 9) - 1,
"immediate offset must be in the range");
1617 case Match_InvalidBareSImm9Lsb0:
1618 return Range(-(1 << 8), (1 << 8) - 2,
1619 "immediate must be a multiple of 2 bytes in the range");
1620 case Match_InvalidUImm9Lsb000:
1621 return Range(0, (1 << 9) - 8,
1622 "immediate must be a multiple of 8 bytes in the range");
1623 case Match_InvalidSImm8PLI_B:
1624 return Range(-(1 << 7), (1 << 8) - 1);
1625 case Match_InvalidSImm10:
1626 case Match_InvalidSImm10PLI_H:
1627 case Match_InvalidSImm10PLI_W:
1628 return Range(-(1 << 9), (1 << 9) - 1);
1629 case Match_InvalidSImm10PLUI:
1630 return Range(-(1 << 9), (1 << 10) - 1);
1631 case Match_InvalidUImm10Lsb00NonZero:
1632 return Range(4, (1 << 10) - 4,
1633 "immediate must be a multiple of 4 bytes in the range");
1634 case Match_InvalidSImm10Lsb0000NonZero:
1636 -(1 << 9), (1 << 9) - 16,
1637 "immediate must be a multiple of 16 bytes and non-zero in the range");
1638 case Match_InvalidSImm11:
1639 return Range(-(1 << 10), (1 << 10) - 1);
1640 case Match_InvalidBareSImm11Lsb0:
1641 return Range(-(1 << 10), (1 << 10) - 2,
1642 "immediate must be a multiple of 2 bytes in the range");
1643 case Match_InvalidUImm10:
1644 return Range(0, (1 << 10) - 1);
1645 case Match_InvalidUImm11:
1646 return Range(0, (1 << 11) - 1);
1647 case Match_InvalidUImm14Lsb00:
1648 return Range(0, (1 << 14) - 4,
1649 "immediate must be a multiple of 4 bytes in the range");
1650 case Match_InvalidUImm16NonZero:
1651 return Range(1, (1 << 16) - 1);
1652 case Match_InvalidSImm12:
1653 return Range(-(1 << 11), (1 << 11) - 1);
1654 case Match_InvalidSImm12LO:
1655 return Range(-(1 << 11), (1 << 11) - 1,
1656 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo "
1657 "specifier or an integer in the range");
1658 case Match_InvalidBareSImm12Lsb0:
1659 return Range(-(1 << 11), (1 << 11) - 2,
1660 "immediate must be a multiple of 2 bytes in the range");
1661 case Match_InvalidSImm12Lsb00000:
1662 return Range(-(1 << 11), (1 << 11) - 32,
1663 "immediate must be a multiple of 32 bytes in the range");
1664 case Match_InvalidBareSImm13Lsb0:
1665 return Range(-(1 << 12), (1 << 12) - 2,
1666 "immediate must be a multiple of 2 bytes in the range");
1667 case Match_InvalidSImm16:
1668 return Range(-(1 << 15), (1 << 15) - 1);
1669 case Match_InvalidSImm16NonZero:
1670 return Range(-(1 << 15), (1 << 15) - 1,
1671 "immediate must be non-zero in the range");
1672 case Match_InvalidSImm20LI:
1673 return Range(-(1 << 19), (1 << 19) - 1,
1674 "operand must be a symbol with a %qc.abs20 specifier or an "
1675 "integer in the range");
1676 case Match_InvalidUImm20LUI:
1677 return Range(0, (1 << 20) - 1,
1678 "operand must be a symbol with %hi/%tprel_hi specifier or an "
1679 "integer in the range");
1680 case Match_InvalidUImm20:
1681 return Range(0, (1 << 20) - 1);
1682 case Match_InvalidUImm20AUIPC:
1685 "operand must be a symbol with a "
1686 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
1687 "or an integer in the range");
1688 case Match_InvalidBareSImm21Lsb0:
1689 return Range(-(1 << 20), (1 << 20) - 2,
1690 "immediate must be a multiple of 2 bytes in the range");
1691 case Match_InvalidCSRSystemRegister:
1692 return Range(0, (1 << 12) - 1,
1693 "operand must be a valid system register name or an integer "
1695 case Match_InvalidImm5Zibi:
1696 return Range(-1, (1 << 5) - 1,
"immediate must be non-zero in the range");
1697 case Match_InvalidVTypeI:
1698 return "operand must be "
1699 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]";
1700 case Match_InvalidSImm5Plus1:
1701 return Range(-(1 << 4) + 1, (1 << 4),
"immediate must be in the range");
1702 case Match_InvalidSImm18:
1703 return Range(-(1 << 17), (1 << 17) - 1);
1704 case Match_InvalidSImm18Lsb0:
1705 return Range(-(1 << 17), (1 << 17) - 2,
1706 "immediate must be a multiple of 2 bytes in the range");
1707 case Match_InvalidSImm19Lsb00:
1708 return Range(-(1 << 18), (1 << 18) - 4,
1709 "immediate must be a multiple of 4 bytes in the range");
1710 case Match_InvalidSImm20Lsb000:
1711 return Range(-(1 << 19), (1 << 19) - 8,
1712 "immediate must be a multiple of 8 bytes in the range");
1713 case Match_InvalidSImm26:
1714 return Range(-(1 << 25), (1 << 25) - 1);
1716 case Match_InvalidBareSymbolQC_E_LI:
1719 case Match_InvalidBareSImm32:
1720 return Range(std::numeric_limits<int32_t>::min(),
1721 std::numeric_limits<uint32_t>::max());
1722 case Match_InvalidBareSImm32Lsb0:
1723 return Range(std::numeric_limits<int32_t>::min(),
1724 std::numeric_limits<int32_t>::max() - 1,
1725 "operand must be a multiple of 2 bytes in the range");
1726 case Match_InvalidRnumArg:
1727 return Range(0, 10);
1728 case Match_InvalidStackAdj:
1729 return "stack adjustment is invalid for this instruction and register "
1731 case Match_InvalidYBNDSWImm:
1732 return "immediate must be an integer in the range "
1733 "[1, 255], a multiple of 8 in the range [256, 504], "
1734 "or a multiple of 16 in the range [512, 4096]";
1735 case Match_InvalidUImm7EqXLen:
1736 return (
"immediate must be an integer equal to XLEN (" +
1737 Twine(isRV64() ?
"64" :
"32") +
")")
1745void RISCVAsmParser::FilterNearMisses(
1746 SmallVectorImpl<NearMissInfo> &NearMissesIn,
1747 SmallVectorImpl<NearMissMessage> &NearMissesOut, SMLoc IDLoc,
1751 std::multimap<unsigned, unsigned> OperandMissesSeen;
1752 SmallSet<FeatureBitset, 4> FeatureMissesSeen;
1753 bool ReportedTooFewOperands =
false;
1754 bool ReportedTooManyOperands =
false;
1756 for (NearMissInfo &
I : NearMissesIn) {
1757 switch (
I.getKind()) {
1760 ((RISCVOperand &)*Operands[
I.getOperandIndex()]).getStartLoc();
1765 if (
I.getOperandClass() == InvalidMatchClass) {
1766 if (!ReportedTooManyOperands) {
1768 OperandLoc,
"unexpected extra operand for instruction"});
1769 ReportedTooManyOperands =
true;
1774 std::string OperandDiag = getCustomOperandDiag(
I.getOperandError());
1778 unsigned DupCheckMatchClass =
1779 OperandDiag.empty() ? ~0
U :
I.getOperandClass();
1780 auto PrevReports = OperandMissesSeen.equal_range(
I.getOperandIndex());
1782 PrevReports.first, PrevReports.second,
1783 [DupCheckMatchClass](
const std::pair<unsigned, unsigned> Pair) {
1784 if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
1785 return Pair.second == DupCheckMatchClass;
1786 return isSubclass((MatchClassKind)DupCheckMatchClass,
1787 (MatchClassKind)Pair.second);
1790 OperandMissesSeen.insert(
1791 std::make_pair(
I.getOperandIndex(), DupCheckMatchClass));
1793 NearMissMessage Message;
1794 Message.Loc = OperandLoc;
1795 if (!OperandDiag.empty()) {
1796 Message.Message = OperandDiag;
1798 Message.Message =
"invalid operand for instruction";
1800 dbgs() <<
"Missing diagnostic string for operand class "
1801 << getMatchClassName((MatchClassKind)
I.getOperandClass())
1802 <<
I.getOperandClass() <<
", error " <<
I.getOperandError()
1803 <<
", opcode " << MII.
getName(
I.getOpcode()) <<
"\n");
1809 const FeatureBitset &MissingFeatures =
I.getFeatures();
1811 if (!FeatureMissesSeen.
insert(MissingFeatures).second)
1814 NearMissMessage Message;
1815 Message.Loc = IDLoc;
1816 bool FirstFeature =
true;
1817 Message.Message =
"instruction requires the following:";
1818 for (
unsigned Feature : MissingFeatures) {
1819 Message.Message += FirstFeature ?
" " :
", ";
1821 FirstFeature =
false;
1831 if (!ReportedTooFewOperands) {
1832 SMLoc EndLoc = ((RISCVOperand &)*Operands.
back()).getEndLoc();
1834 NearMissMessage{EndLoc,
"too few operands for instruction"});
1835 ReportedTooFewOperands =
true;
1847void RISCVAsmParser::ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses,
1850 FilterNearMisses(NearMisses, Messages, IDLoc, Operands);
1855 Error(IDLoc,
"invalid instruction");
1858 Error(Messages[0].Loc, Messages[0].Message);
1863 "invalid instruction, any one of the following would fix this:");
1864 for (
auto &M : Messages)
1869bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1872 uint64_t &ErrorInfo,
1873 bool MatchingInlineAsm) {
1878 MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm);
1883 if (validateInstruction(Inst, Operands))
1885 return processInstruction(Inst, IDLoc, Operands, Out);
1886 case Match_MnemonicFail: {
1887 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1888 std::string Suggestion = RISCVMnemonicSpellCheck(
1889 ((RISCVOperand &)*Operands[0]).
getToken(), FBS, 0);
1890 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1892 case Match_NearMisses:
1893 ReportNearMisses(NearMisses, IDLoc, Operands);
1904MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name)
const {
1913 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1914 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1915 static_assert(RISCV::F0_D < RISCV::F0_Q,
"FPR matching must be updated");
1918 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1923bool RISCVAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1925 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1926 return Error(StartLoc,
"invalid register name");
1930ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1932 const AsmToken &Tok = getParser().getTok();
1935 StringRef
Name = getLexer().getTok().getIdentifier();
1945ParseStatus RISCVAsmParser::parseRegister(
OperandVector &Operands,
1947 SMLoc FirstS = getLoc();
1948 bool HadParens =
false;
1955 size_t ReadCount = getLexer().peekTokens(Buf);
1958 LParen = getParser().getTok();
1963 switch (getLexer().getKind()) {
1966 getLexer().UnLex(LParen);
1969 StringRef
Name = getLexer().getTok().getIdentifier();
1974 getLexer().UnLex(LParen);
1978 Operands.
push_back(RISCVOperand::createToken(
"(", FirstS));
1980 SMLoc
E = getTok().getEndLoc();
1987 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
1993ParseStatus RISCVAsmParser::parseInsnDirectiveOpcode(
OperandVector &Operands) {
1998 switch (getLexer().getKind()) {
2008 if (getParser().parseExpression(Res,
E))
2013 int64_t
Imm =
CE->getValue();
2015 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2024 if (getParser().parseIdentifier(Identifier))
2027 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
2030 "Unexpected opcode");
2033 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2043 return generateImmOutOfRangeError(
2045 "opcode must be a valid opcode name or an immediate in the range");
2048ParseStatus RISCVAsmParser::parseInsnCDirectiveOpcode(
OperandVector &Operands) {
2053 switch (getLexer().getKind()) {
2063 if (getParser().parseExpression(Res,
E))
2068 int64_t
Imm =
CE->getValue();
2069 if (Imm >= 0 && Imm <= 2) {
2070 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2079 if (getParser().parseIdentifier(Identifier))
2083 if (Identifier ==
"C0")
2085 else if (Identifier ==
"C1")
2087 else if (Identifier ==
"C2")
2094 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2103 return generateImmOutOfRangeError(
2105 "opcode must be a valid opcode name or an immediate in the range");
2108ParseStatus RISCVAsmParser::parseCSRSystemRegister(
OperandVector &Operands) {
2112 auto SysRegFromConstantInt = [
this](
const MCExpr *
E, SMLoc S) {
2114 int64_t
Imm =
CE->getValue();
2116 auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
2120 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2123 return RISCVOperand::createSysReg(
2124 RISCVSysReg::getSysRegStr(
Reg.Name), S, Imm);
2128 return RISCVOperand::createSysReg(
"", S, Imm);
2131 return std::unique_ptr<RISCVOperand>();
2134 switch (getLexer().getKind()) {
2144 if (getParser().parseExpression(Res))
2147 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
2152 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2156 if (getParser().parseIdentifier(Identifier))
2159 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
2162 if (SysReg->IsDeprecatedName) {
2164 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
2166 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2168 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
2169 RISCVSysReg::getSysRegStr(
Reg.Name) +
"'");
2174 const auto &FeatureBits = getSTI().getFeatureBits();
2175 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
2176 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
2177 const auto *Feature =
2179 return SysReg->FeaturesRequired[Feature.Value];
2181 std::string ErrorMsg =
2182 std::string(
"system register '") +
2183 std::string(RISCVSysReg::getSysRegStr(SysReg->Name)) +
"' ";
2184 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
2185 ErrorMsg +=
"is RV32 only";
2187 ErrorMsg +=
" and ";
2191 "requires '" + std::string(Feature->key()) +
"' to be enabled";
2194 return Error(S, ErrorMsg);
2197 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
2212 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2213 "operand must be a valid system register "
2214 "name or an integer in the range");
2218 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2225ParseStatus RISCVAsmParser::parseFPImm(
OperandVector &Operands) {
2230 StringRef
Identifier = getTok().getIdentifier();
2231 if (
Identifier.compare_insensitive(
"inf") == 0) {
2234 getTok().getEndLoc(), isRV64()));
2235 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2238 getTok().getEndLoc(), isRV64()));
2239 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2242 getTok().getEndLoc(), isRV64()));
2244 return TokError(
"invalid floating point literal");
2255 const AsmToken &Tok = getTok();
2257 return TokError(
"invalid floating point immediate");
2260 APFloat RealVal(APFloat::IEEEdouble());
2262 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2264 return TokError(
"invalid floating point representation");
2267 RealVal.changeSign();
2269 Operands.
push_back(RISCVOperand::createFPImm(
2270 RealVal.bitcastToAPInt().getZExtValue(), S));
2277ParseStatus RISCVAsmParser::parseExpression(
OperandVector &Operands) {
2282 switch (getLexer().getKind()) {
2294 if (getParser().parseExpression(Res,
E))
2298 return parseOperandWithSpecifier(Operands);
2301 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2305ParseStatus RISCVAsmParser::parseOperandWithSpecifier(
OperandVector &Operands) {
2311 const MCExpr *Expr =
nullptr;
2312 bool Failed = parseExprWithSpecifier(Expr,
E);
2314 Operands.
push_back(RISCVOperand::createExpr(Expr, S,
E, isRV64()));
2318bool RISCVAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
2319 SMLoc Loc = getLoc();
2321 return TokError(
"expected '%' relocation specifier");
2322 StringRef
Identifier = getParser().getTok().getIdentifier();
2325 return TokError(
"invalid relocation specifier");
2331 const MCExpr *SubExpr;
2332 if (getParser().parseParenExpression(SubExpr,
E))
2339bool RISCVAsmParser::parseDataExpr(
const MCExpr *&Res) {
2342 return parseExprWithSpecifier(Res,
E);
2343 return getParser().parseExpression(Res);
2346ParseStatus RISCVAsmParser::parseBareSymbol(
OperandVector &Operands) {
2353 StringRef
Identifier = getTok().getIdentifier();
2363 if (getParser().parseExpression(Res,
E))
2366 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2370ParseStatus RISCVAsmParser::parseCallSymbol(
OperandVector &Operands) {
2376 std::string
Identifier(getTok().getIdentifier());
2382 SMLoc Loc = getLoc();
2383 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2384 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2398 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2402ParseStatus RISCVAsmParser::parsePseudoJumpSymbol(
OperandVector &Operands) {
2407 if (getParser().parseExpression(Res,
E))
2410 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef)
2411 return Error(S,
"operand must be a valid jump target");
2414 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2418ParseStatus RISCVAsmParser::parseJALOffset(
OperandVector &Operands) {
2432 return parseExpression(Operands);
2435bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2436 unsigned &Sew,
unsigned &Lmul,
2437 bool &Fractional,
bool &TailAgnostic,
2438 bool &MaskAgnostic,
bool &AltFmt) {
2443 if (State < VTypeState::SeenSew &&
Identifier.consume_front(
"e")) {
2445 if (Identifier ==
"16alt") {
2448 }
else if (Identifier ==
"8alt") {
2458 State = VTypeState::SeenSew;
2462 if (State < VTypeState::SeenLmul &&
Identifier.consume_front(
"m")) {
2465 if (Identifier ==
"a" || Identifier ==
"u") {
2467 State = VTypeState::SeenMaskPolicy;
2478 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2479 unsigned MinLMUL = ELEN / 8;
2482 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2483 Twine(MinLMUL) +
" is reserved");
2486 State = VTypeState::SeenLmul;
2490 if (State < VTypeState::SeenTailPolicy &&
Identifier.starts_with(
"t")) {
2491 if (Identifier ==
"ta")
2492 TailAgnostic =
true;
2493 else if (Identifier ==
"tu")
2494 TailAgnostic =
false;
2498 State = VTypeState::SeenTailPolicy;
2502 if (State < VTypeState::SeenMaskPolicy &&
Identifier.starts_with(
"m")) {
2503 if (Identifier ==
"ma")
2504 MaskAgnostic =
true;
2505 else if (Identifier ==
"mu")
2506 MaskAgnostic =
false;
2510 State = VTypeState::SeenMaskPolicy;
2517ParseStatus RISCVAsmParser::parseVTypeI(
OperandVector &Operands) {
2523 bool Fractional =
false;
2524 bool TailAgnostic =
false;
2525 bool MaskAgnostic =
false;
2528 VTypeState State = VTypeState::SeenNothingYet;
2530 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2531 MaskAgnostic, AltFmt)) {
2533 if (State == VTypeState::SeenNothingYet)
2542 State == VTypeState::SeenNothingYet)
2543 return generateVTypeError(S);
2547 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2548 unsigned MaxSEW = ELEN / Lmul;
2550 if (MaxSEW >= 8 && Sew > MaxSEW)
2551 Warning(S,
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2552 " and LMUL == mf" + Twine(Lmul) +
2553 " may not be compatible with all RVV implementations");
2558 Operands.
push_back(RISCVOperand::createVType(VTypeI, S));
2562bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2563 return Error(ErrorLoc,
2565 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2568ParseStatus RISCVAsmParser::parseXSfmmVType(
OperandVector &Operands) {
2585 if (Identifier !=
"16alt")
2614 Operands.
push_back(RISCVOperand::createVType(
2620 return generateXSfmmVTypeError(S);
2623bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
2624 return Error(ErrorLoc,
"operand must be e[8|16|16alt|32|64],w[1|2|4]");
2627ParseStatus RISCVAsmParser::parseMaskReg(
OperandVector &Operands) {
2631 StringRef
Name = getLexer().getTok().getIdentifier();
2632 if (!
Name.consume_back(
".t")) {
2636 return Error(getLoc(),
"expected '.t' suffix");
2643 if (
Reg != RISCV::V0)
2646 SMLoc
E = getTok().getEndLoc();
2652ParseStatus RISCVAsmParser::parseVScaleReg(
OperandVector &Operands) {
2656 StringRef
Name = getLexer().getTok().getIdentifier();
2657 if (!
Name.consume_back(
".scale"))
2658 return Error(getLoc(),
"expected '.scale' suffix");
2663 if (
Reg != RISCV::V0)
2666 SMLoc
E = getTok().getEndLoc();
2672ParseStatus RISCVAsmParser::parseTileLambda(
OperandVector &Operands) {
2677 StringRef
Name = getLexer().getTok().getIdentifier();
2678 if (!
Name.consume_front(
"L") && !
Name.consume_front(
"l"))
2683 return Error(S,
"operand must be L1, L2, L4, L8, L16, L32, or L64");
2685 unsigned EncodedLambda =
Log2_32(Lambda) + 1;
2687 SMLoc
E = getTok().getEndLoc();
2689 Operands.
push_back(RISCVOperand::createExpr(
2694ParseStatus RISCVAsmParser::parseGPRAsFPR64(
OperandVector &Operands) {
2695 if (!isRV64() || getSTI().
hasFeature(RISCV::FeatureStdExtF))
2698 return parseGPRAsFPR(Operands);
2701ParseStatus RISCVAsmParser::parseGPRAsFPR(
OperandVector &Operands) {
2705 StringRef
Name = getLexer().getTok().getIdentifier();
2711 SMLoc
E = getTok().getEndLoc();
2713 Operands.
push_back(RISCVOperand::createReg(
2718ParseStatus RISCVAsmParser::parseGPRPairAsFPR64(
OperandVector &Operands) {
2719 if (isRV64() || getSTI().
hasFeature(RISCV::FeatureStdExtF))
2725 StringRef
Name = getLexer().getTok().getIdentifier();
2731 if (!getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg))
2734 if ((
Reg - RISCV::X0) & 1) {
2737 if (getSTI().
hasFeature(RISCV::FeatureStdExtZfinx))
2738 return TokError(
"double precision floating point operands must use even "
2739 "numbered X register");
2744 SMLoc
E = getTok().getEndLoc();
2747 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2749 Reg, RISCV::sub_gpr_even,
2750 &getRISCVMCRegisterClass(RISCV::GPRPairRegClassID));
2751 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2755template <
bool IsRV64>
2756ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands) {
2757 return parseGPRPair(Operands, IsRV64);
2760ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands,
2767 if (!IsRV64Inst && isRV64())
2773 StringRef
Name = getLexer().getTok().getIdentifier();
2779 if (!getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg))
2782 if ((
Reg - RISCV::X0) & 1)
2783 return TokError(
"register must be even");
2786 SMLoc
E = getTok().getEndLoc();
2789 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2791 Reg, RISCV::sub_gpr_even,
2792 &getRISCVMCRegisterClass(RISCV::GPRPairRegClassID));
2793 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E));
2797ParseStatus RISCVAsmParser::parseSMTVType(
OperandVector &Operands) {
2800 "operand must be a valid SpacemiT's Integer Matrix VType mnemonic");
2802 StringRef Str = getLexer().getTok().getIdentifier();
2805 if (!isValidSMTVTypeMode(VType))
2806 return TokError(
"SpacemiT's Integer Matrix only supports [i4|i8] mode");
2808 Operands.
push_back(RISCVOperand::createSMTVType(VType, getLoc()));
2813ParseStatus RISCVAsmParser::parseFRMArg(
OperandVector &Operands) {
2816 "operand must be a valid floating point rounding mode mnemonic");
2818 StringRef Str = getLexer().getTok().getIdentifier();
2823 "operand must be a valid floating point rounding mode mnemonic");
2825 Operands.
push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2830std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultSMTVType() {
2831 return RISCVOperand::createSMTVType(XSMTVTypeMode::SMTVTypeMode::SMT_I8,
2835ParseStatus RISCVAsmParser::parseFenceArg(
OperandVector &Operands) {
2836 const AsmToken &Tok = getLexer().getTok();
2842 Operands.
push_back(RISCVOperand::createFenceArg(0, getLoc()));
2856 for (
char c : Str) {
2885 Operands.
push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2891 return TokError(
"operand must be formed of letters selected in-order from "
2895ParseStatus RISCVAsmParser::parseMemOpBaseReg(
OperandVector &Operands) {
2898 Operands.
push_back(RISCVOperand::createToken(
"(", getLoc()));
2900 if (!parseRegister(Operands).isSuccess())
2901 return Error(getLoc(),
"expected register");
2905 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
2910ParseStatus RISCVAsmParser::parseZeroOffsetMemOp(
OperandVector &Operands) {
2929 std::unique_ptr<RISCVOperand> OptionalImmOp;
2936 SMLoc ImmStart = getLoc();
2937 if (getParser().parseIntToken(ImmVal,
2938 "expected '(' or optional integer offset"))
2943 SMLoc ImmEnd = getLoc();
2946 ImmStart, ImmEnd, isRV64());
2950 OptionalImmOp ?
"expected '(' after optional integer offset"
2951 :
"expected '(' or optional integer offset"))
2954 if (!parseRegister(Operands).isSuccess())
2955 return Error(getLoc(),
"expected register");
2961 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2963 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2964 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2969ParseStatus RISCVAsmParser::parseRegReg(
OperandVector &Operands) {
2975 StringRef OffsetRegName = getLexer().getTok().getIdentifier();
2978 !getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(OffsetReg))
2979 return Error(getLoc(),
"expected GPR register");
2986 return Error(getLoc(),
"expected GPR register");
2988 StringRef BaseRegName = getLexer().getTok().getIdentifier();
2991 !getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(BaseReg))
2992 return Error(getLoc(),
"expected GPR register");
2998 Operands.
push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));
3010ParseStatus RISCVAsmParser::parseRegList(
OperandVector &Operands,
3011 bool MustIncludeS0) {
3023 return Error(getLoc(),
"invalid register");
3025 StringRef
RegName = getTok().getIdentifier();
3028 return Error(getLoc(),
"invalid register");
3031 UsesXRegs =
RegName[0] ==
'x';
3032 if (
Reg != RISCV::X1)
3033 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
3034 }
else if (RegEnd == RISCV::X1) {
3035 if (
Reg != RISCV::X8 || (UsesXRegs != (
RegName[0] ==
'x')))
3036 return Error(getLoc(), Twine(
"register must be '") +
3037 (UsesXRegs ?
"x8" :
"s0") +
"'");
3038 }
else if (RegEnd == RISCV::X9 && UsesXRegs) {
3039 if (
Reg != RISCV::X18 || (
RegName[0] !=
'x'))
3040 return Error(getLoc(),
"register must be 'x18'");
3042 return Error(getLoc(),
"too many register ranges");
3049 SMLoc MinusLoc = getLoc();
3051 if (RegEnd == RISCV::X1)
3052 return Error(MinusLoc, Twine(
"register '") + (UsesXRegs ?
"x1" :
"ra") +
3053 "' cannot start a multiple register range");
3056 return Error(getLoc(),
"invalid register");
3058 StringRef
RegName = getTok().getIdentifier();
3061 return Error(getLoc(),
"invalid register");
3063 if (RegEnd == RISCV::X8) {
3064 if ((
Reg != RISCV::X9 &&
3066 (UsesXRegs != (
RegName[0] ==
'x'))) {
3068 return Error(getLoc(),
"register must be 'x9'");
3069 return Error(getLoc(),
"register must be in the range 's1' to 's11'");
3071 }
else if (RegEnd == RISCV::X18) {
3073 return Error(getLoc(),
3074 "register must be in the range 'x19' to 'x27'");
3087 if (RegEnd == RISCV::X26)
3088 return Error(S,
"invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "
3089 "x18-x26}' is not supported");
3095 return Error(S,
"register list must include 's0' or 'x8'");
3097 Operands.
push_back(RISCVOperand::createRegList(Encode, S));
3102ParseStatus RISCVAsmParser::parseZcmpStackAdj(
OperandVector &Operands,
3103 bool ExpectNegative) {
3112 auto *RegListOp =
static_cast<RISCVOperand *
>(Operands.
back().
get());
3113 if (!RegListOp->isRegList())
3116 unsigned RlistEncode = RegListOp->RegList.Encoding;
3120 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||
3121 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {
3122 int64_t
Lower = StackAdjBase;
3123 int64_t
Upper = StackAdjBase + 48;
3124 if (ExpectNegative) {
3129 return generateImmOutOfRangeError(S,
Lower,
Upper,
3130 "stack adjustment for register list must "
3131 "be a multiple of 16 bytes in the range");
3135 Operands.
push_back(RISCVOperand::createStackAdj(StackAdj, S));
3143bool RISCVAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
3147 MatchOperandParserImpl(Operands, Mnemonic,
true);
3154 if (parseRegister(Operands,
true).isSuccess())
3158 if (parseExpression(Operands).isSuccess()) {
3161 return !parseMemOpBaseReg(Operands).isSuccess();
3166 Error(getLoc(),
"unknown operand");
3170bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &Info,
3171 StringRef Name, SMLoc NameLoc,
3177 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
3181 Operands.
push_back(RISCVOperand::createToken(Name, NameLoc));
3190 if (parseOperand(Operands, Name))
3196 if (parseOperand(Operands, Name))
3200 if (getParser().parseEOL(
"unexpected token")) {
3201 getParser().eatToEndOfStatement();
3207bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
3211 Kind = RE->getSpecifier();
3212 Expr = RE->getSubExpr();
3221bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
3230ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
3231 StringRef IDVal = DirectiveID.
getString();
3233 if (IDVal ==
".option")
3234 return parseDirectiveOption();
3235 if (IDVal ==
".attribute")
3236 return parseDirectiveAttribute();
3237 if (IDVal ==
".insn")
3238 return parseDirectiveInsn(DirectiveID.
getLoc());
3239 if (IDVal ==
".variant_cc")
3240 return parseDirectiveVariantCC();
3245bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
3246 bool FromOptionDirective) {
3247 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
3250 clearFeatureBits(Feature.Value, Feature.key());
3257 raw_string_ostream OutputErrMsg(Buffer);
3258 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3259 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
3260 << ErrMsg.getMessage();
3263 return Error(Loc, OutputErrMsg.str());
3265 auto &ISAInfo = *ParseResult;
3268 if (ISAInfo->hasExtension(Feature.key()))
3269 setFeatureBits(Feature.Value, Feature.key());
3271 if (FromOptionDirective) {
3272 if (ISAInfo->getXLen() == 32 && isRV64())
3273 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3274 else if (ISAInfo->getXLen() == 64 && !isRV64())
3275 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3278 if (ISAInfo->getXLen() == 32)
3279 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
3280 else if (ISAInfo->getXLen() == 64)
3281 setFeatureBits(RISCV::Feature64Bit,
"64bit");
3283 return Error(Loc,
"bad arch string " + Arch);
3285 Result = ISAInfo->toString();
3289bool RISCVAsmParser::parseDirectiveOption() {
3290 MCAsmParser &Parser = getParser();
3292 AsmToken Tok = Parser.
getTok();
3300 if (Option ==
"push") {
3304 getTargetStreamer().emitDirectiveOptionPush();
3309 if (Option ==
"pop") {
3314 getTargetStreamer().emitDirectiveOptionPop();
3315 if (popFeatureBits())
3316 return Error(StartLoc,
".option pop with no .option push");
3321 if (Option ==
"arch") {
3329 Type = RISCVOptionArchArgType::Plus;
3331 Type = RISCVOptionArchArgType::Minus;
3332 else if (!
Args.empty())
3334 "unexpected token, expected + or -");
3336 Type = RISCVOptionArchArgType::Full;
3340 "unexpected token, expected identifier");
3346 if (
Type == RISCVOptionArchArgType::Full) {
3348 if (resetToArch(Arch, Loc, Result,
true))
3357 Loc,
"extension version number parsing not currently implemented");
3360 if (!enableExperimentalExtension() &&
3362 return Error(Loc,
"unexpected experimental extensions");
3363 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
3365 if (Ext == std::end(
AllFeatures) || StringRef(Ext->key()) != Feature)
3366 return Error(Loc,
"unknown extension feature");
3370 if (
Type == RISCVOptionArchArgType::Plus) {
3373 setFeatureBits(Ext->Value, Ext->key());
3376 copySTI().setFeatureBits(OldFeatureBits);
3377 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3380 raw_string_ostream OutputErrMsg(Buffer);
3381 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3382 OutputErrMsg << ErrMsg.getMessage();
3385 return Error(Loc, OutputErrMsg.str());
3388 assert(
Type == RISCVOptionArchArgType::Minus);
3394 Feature.Implies.test(Ext->Value))
3395 return Error(Loc, Twine(
"can't disable ") + Ext->key() +
3396 " extension; " + Feature.key() +
3397 " extension requires " + Ext->key() +
3401 clearFeatureBits(Ext->Value, Ext->key());
3408 getTargetStreamer().emitDirectiveOptionArch(Args);
3411 getTargetStreamer().setArchString((*ParseResult)->toString());
3415 if (Option ==
"exact") {
3419 getTargetStreamer().emitDirectiveOptionExact();
3420 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3421 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3425 if (Option ==
"noexact") {
3429 getTargetStreamer().emitDirectiveOptionNoExact();
3430 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3431 setFeatureBits(RISCV::FeatureRelax,
"relax");
3435 if (Option ==
"rvc") {
3439 getTargetStreamer().emitDirectiveOptionRVC();
3440 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3442 getTargetStreamer().setArchString((*ParseResult)->toString());
3446 if (Option ==
"norvc") {
3450 getTargetStreamer().emitDirectiveOptionNoRVC();
3451 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3452 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3454 getTargetStreamer().setArchString((*ParseResult)->toString());
3458 if (Option ==
"pic") {
3462 getTargetStreamer().emitDirectiveOptionPIC();
3463 ParserOptions.IsPicEnabled =
true;
3467 if (Option ==
"nopic") {
3471 getTargetStreamer().emitDirectiveOptionNoPIC();
3472 ParserOptions.IsPicEnabled =
false;
3476 if (Option ==
"relax") {
3480 getTargetStreamer().emitDirectiveOptionRelax();
3481 setFeatureBits(RISCV::FeatureRelax,
"relax");
3485 if (Option ==
"norelax") {
3489 getTargetStreamer().emitDirectiveOptionNoRelax();
3490 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3496 "unknown option, expected 'push', 'pop', "
3497 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3498 "'exact', or 'noexact'");
3506bool RISCVAsmParser::parseDirectiveAttribute() {
3507 MCAsmParser &Parser = getParser();
3513 std::optional<unsigned> Ret =
3516 return Error(TagLoc,
"attribute name not recognised: " + Name);
3520 const MCExpr *AttrExpr;
3527 if (check(!CE, TagLoc,
"expected numeric constant"))
3530 Tag =
CE->getValue();
3536 StringRef StringValue;
3537 int64_t IntegerValue = 0;
3538 bool IsIntegerValue =
true;
3543 IsIntegerValue =
false;
3546 if (IsIntegerValue) {
3547 const MCExpr *ValueExpr;
3553 return Error(ValueExprLoc,
"expected numeric constant");
3554 IntegerValue =
CE->getValue();
3567 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3569 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3572 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3576 getTargetStreamer().emitTextAttribute(
Tag, Result);
3580 getTargetStreamer().setArchString(Result);
3588 .
Cases({
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s"},
true)
3589 .Cases({
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj"},
3591 .
Cases({
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es"},
3600bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3601 MCAsmParser &Parser = getParser();
3608 std::optional<int64_t>
Length;
3618 return Error(ErrorLoc,
3619 "instruction lengths must be a non-zero multiple of two");
3623 return Error(ErrorLoc,
3624 "instruction lengths over 64 bits are not supported");
3630 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3635 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3636 return Error(ErrorLoc,
3637 "instruction length does not match the encoding");
3640 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3643 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3646 if (!getSTI().
hasFeature(RISCV::FeatureStdExtZca) &&
3647 (EncodingDerivedLength == 2))
3648 return Error(ErrorLoc,
"compressed instructions are not allowed");
3650 if (getParser().parseEOL(
"invalid operand for instruction")) {
3651 getParser().eatToEndOfStatement();
3659 Opcode = RISCV::Insn16;
3662 Opcode = RISCV::Insn32;
3665 Opcode = RISCV::Insn48;
3668 Opcode = RISCV::Insn64;
3674 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3676 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3681 return Error(ErrorLoc,
"invalid instruction format");
3683 std::string FormatName = (
".insn_" +
Format).str();
3685 ParseInstructionInfo
Info;
3688 if (parseInstruction(Info, FormatName, L, Operands))
3693 return matchAndEmitInstruction(L, Opcode, Operands, Parser.
getStreamer(),
3700bool RISCVAsmParser::parseDirectiveVariantCC() {
3702 if (getParser().parseIdentifier(Name))
3703 return TokError(
"expected symbol name");
3706 getTargetStreamer().emitDirectiveVariantCC(
3711void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3714 const MCSubtargetInfo &STI = getSTI();
3715 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3718 ++RISCVNumInstrsCompressed;
3722void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3727 for (MCInst &Inst : Seq) {
3728 emitToStreamer(Out, Inst);
3732void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3733 const MCExpr *Symbol,
3735 unsigned SecondOpcode, SMLoc IDLoc,
3747 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3752 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3755 .addExpr(RefToLinkTmpLabel));
3758void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3771 Out, MCInstBuilder(RISCV::QC_E_LI).addReg(DestReg).addExpr(Symbol));
3777void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3787 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3788 emitAuipcInstPair(DestReg, DestReg, Symbol,
RISCV::S_GOT_HI, SecondOpcode,
3792void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3801 if (ParserOptions.IsPicEnabled)
3802 emitLoadGlobalAddress(Inst, IDLoc, Out);
3804 emitLoadLocalAddress(Inst, IDLoc, Out);
3807void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3817 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3818 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3819 SecondOpcode, IDLoc, Out);
3822void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3832 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3833 RISCV::ADDI, IDLoc, Out);
3836void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3837 SMLoc IDLoc, MCStreamer &Out,
3846 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3848 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3852 if (getRISCVMCRegisterClass(RISCV::GPRPairRegClassID).
contains(TmpReg)) {
3853 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3854 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3862void RISCVAsmParser::emitQCELILoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3863 SMLoc IDLoc, MCStreamer &Out,
3873 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3877 MCInstBuilder(RISCV::QC_E_LI).addReg(AddrReg).addExpr(Symbol));
3880 const MCExpr *AccessExpr =
3886 struct CompressedForm {
3890 std::optional<CompressedForm> Compressed;
3894 case RISCV::PseudoQCAccessLBU:
3895 Compressed = {RISCV::PseudoQCAccessC_LBU, RISCV::FeatureStdExtZcb};
3897 case RISCV::PseudoQCAccessLH:
3898 Compressed = {RISCV::PseudoQCAccessC_LH, RISCV::FeatureStdExtZcb};
3900 case RISCV::PseudoQCAccessLHU:
3901 Compressed = {RISCV::PseudoQCAccessC_LHU, RISCV::FeatureStdExtZcb};
3903 case RISCV::PseudoQCAccessLW:
3904 Compressed = {RISCV::PseudoQCAccessC_LW, RISCV::FeatureStdExtZca};
3906 case RISCV::PseudoQCAccessSB:
3907 Compressed = {RISCV::PseudoQCAccessC_SB, RISCV::FeatureStdExtZcb};
3909 case RISCV::PseudoQCAccessSH:
3910 Compressed = {RISCV::PseudoQCAccessC_SH, RISCV::FeatureStdExtZcb};
3912 case RISCV::PseudoQCAccessSW:
3913 Compressed = {RISCV::PseudoQCAccessC_SW, RISCV::FeatureStdExtZca};
3920 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(AddrReg);
3921 if (HasTmpReg && CanUseGPRC) {
3924 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(DataReg);
3927 bool UseCompressed =
3928 Compressed && getSTI().hasFeature(Compressed->Feature) && CanUseGPRC;
3930 unsigned ActualOpcode = UseCompressed ? Compressed->Opcode : Opcode;
3933 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3937 .addExpr(AccessExpr));
3939 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3943 .addExpr(AccessExpr));
3947void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3948 int64_t Width, SMLoc IDLoc,
3957 const MCOperand &DestReg = Inst.
getOperand(0);
3958 const MCOperand &SourceReg = Inst.
getOperand(1);
3960 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3961 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3963 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3965 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3970 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3976void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
3983 emitToStreamer(Out, MCInstBuilder(Opcode)
3987 .addReg(MCRegister())
3989 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
4000 "The destination register should not be V0.");
4002 emitToStreamer(Out, MCInstBuilder(Opcode)
4008 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
4020 "The temporary vector register should not be V0.");
4021 emitToStreamer(Out, MCInstBuilder(Opcode)
4025 .addReg(MCRegister())
4027 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4039 "The temporary vector register should not be V0.");
4040 emitToStreamer(Out, MCInstBuilder(Opcode)
4044 .addReg(MCRegister())
4046 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4051 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4056 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
4064bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
4066 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
4069 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
4070 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
4071 "%tprel_add specifier");
4077bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
4079 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
4082 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
4083 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
4084 "%tlsdesc_call specifier");
4090std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
4091 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
4094std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
4095 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
4099std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
4100 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
4108 case RISCV::VLOXSEG2EI8_V:
4109 case RISCV::VLOXSEG2EI16_V:
4110 case RISCV::VLOXSEG2EI32_V:
4111 case RISCV::VLOXSEG2EI64_V:
4112 case RISCV::VLUXSEG2EI8_V:
4113 case RISCV::VLUXSEG2EI16_V:
4114 case RISCV::VLUXSEG2EI32_V:
4115 case RISCV::VLUXSEG2EI64_V:
4117 case RISCV::VLOXSEG3EI8_V:
4118 case RISCV::VLOXSEG3EI16_V:
4119 case RISCV::VLOXSEG3EI32_V:
4120 case RISCV::VLOXSEG3EI64_V:
4121 case RISCV::VLUXSEG3EI8_V:
4122 case RISCV::VLUXSEG3EI16_V:
4123 case RISCV::VLUXSEG3EI32_V:
4124 case RISCV::VLUXSEG3EI64_V:
4126 case RISCV::VLOXSEG4EI8_V:
4127 case RISCV::VLOXSEG4EI16_V:
4128 case RISCV::VLOXSEG4EI32_V:
4129 case RISCV::VLOXSEG4EI64_V:
4130 case RISCV::VLUXSEG4EI8_V:
4131 case RISCV::VLUXSEG4EI16_V:
4132 case RISCV::VLUXSEG4EI32_V:
4133 case RISCV::VLUXSEG4EI64_V:
4135 case RISCV::VLOXSEG5EI8_V:
4136 case RISCV::VLOXSEG5EI16_V:
4137 case RISCV::VLOXSEG5EI32_V:
4138 case RISCV::VLOXSEG5EI64_V:
4139 case RISCV::VLUXSEG5EI8_V:
4140 case RISCV::VLUXSEG5EI16_V:
4141 case RISCV::VLUXSEG5EI32_V:
4142 case RISCV::VLUXSEG5EI64_V:
4144 case RISCV::VLOXSEG6EI8_V:
4145 case RISCV::VLOXSEG6EI16_V:
4146 case RISCV::VLOXSEG6EI32_V:
4147 case RISCV::VLOXSEG6EI64_V:
4148 case RISCV::VLUXSEG6EI8_V:
4149 case RISCV::VLUXSEG6EI16_V:
4150 case RISCV::VLUXSEG6EI32_V:
4151 case RISCV::VLUXSEG6EI64_V:
4153 case RISCV::VLOXSEG7EI8_V:
4154 case RISCV::VLOXSEG7EI16_V:
4155 case RISCV::VLOXSEG7EI32_V:
4156 case RISCV::VLOXSEG7EI64_V:
4157 case RISCV::VLUXSEG7EI8_V:
4158 case RISCV::VLUXSEG7EI16_V:
4159 case RISCV::VLUXSEG7EI32_V:
4160 case RISCV::VLUXSEG7EI64_V:
4162 case RISCV::VLOXSEG8EI8_V:
4163 case RISCV::VLOXSEG8EI16_V:
4164 case RISCV::VLOXSEG8EI32_V:
4165 case RISCV::VLOXSEG8EI64_V:
4166 case RISCV::VLUXSEG8EI8_V:
4167 case RISCV::VLUXSEG8EI16_V:
4168 case RISCV::VLUXSEG8EI32_V:
4169 case RISCV::VLUXSEG8EI64_V:
4175 if (getRISCVMCRegisterClass(RISCV::VRM2RegClassID).
contains(
Reg))
4177 if (getRISCVMCRegisterClass(RISCV::VRM4RegClassID).
contains(
Reg))
4179 if (getRISCVMCRegisterClass(RISCV::VRM8RegClassID).
contains(
Reg))
4186 case RISCV::VFWMMACC_VV_SCALE:
4187 case RISCV::VFQMMACC_VV_SCALE:
4188 case RISCV::VF8WMMACC_VV_SCALE:
4189 case RISCV::VFWIMMACC_VV:
4190 case RISCV::VFQIMMACC_VV:
4191 case RISCV::VF8WIMMACC_VV:
4198bool RISCVAsmParser::validateInstruction(MCInst &Inst,
4202 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
4203 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
4206 if (DestReg == TempReg) {
4207 SMLoc Loc = Operands.
back()->getStartLoc();
4208 return Error(Loc,
"the temporary vector register cannot be the same as "
4209 "the destination register");
4213 if (Opcode == RISCV::PseudoVMSGEU_VX_M || Opcode == RISCV::PseudoVMSGE_VX_M) {
4216 if (MaskReg == RISCV::V0 && DestReg == RISCV::V0) {
4217 SMLoc Loc = Operands.
back()->getStartLoc();
4218 return Error(Loc,
"the destination vector register cannot overlap the "
4219 "mask register unless a temporary register is "
4224 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
4225 Opcode == RISCV::TH_LWD) {
4230 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
4231 SMLoc Loc = Operands[1]->getStartLoc();
4232 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
4236 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
4240 SMLoc Loc = Operands[1]->getStartLoc();
4241 return Error(Loc,
"rs1 and rs2 must be different");
4246 auto CheckOperandDoesNotOverlapV0 = [&](
int OperandIdx,
4247 unsigned ParsedIdx) {
4249 return Error(Operands[ParsedIdx]->getStartLoc(),
4250 "vd, vs1, and vs2 cannot overlap v0.scale");
4255 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4257 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4259 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4260 assert(DestIdx >= 0 && VS1Idx >= 0 && VS2Idx >= 0 &&
4261 "Unexpected Zvvfmm scaled operand list");
4263 if (CheckOperandDoesNotOverlapV0(DestIdx, 1) ||
4264 CheckOperandDoesNotOverlapV0(VS1Idx, 2) ||
4265 CheckOperandDoesNotOverlapV0(VS2Idx, 3))
4269 const MCInstrDesc &MCID = MII.
get(Opcode);
4273 int DestIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4277 const MCParsedAsmOperand *ParsedOp = Operands[1].get();
4278 if (!ParsedOp->
isReg()) {
4281 ParsedOp = Operands[2].get();
4283 assert(ParsedOp->
getReg() == DestReg &&
"Can't find parsed dest operand");
4287 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4291 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4292 assert(VS2Idx >= 0 &&
"No vs2 operand?");
4293 unsigned CheckEncoding =
4296 for (
unsigned i = 0; i < std::max(NF, Lmul); i++) {
4297 if ((DestEncoding + i) == CheckEncoding)
4298 return Error(Loc,
"the destination vector register group cannot overlap"
4299 " the source vector register group");
4304 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4308 unsigned CheckEncoding =
4310 for (
unsigned i = 0; i < Lmul; i++) {
4311 if ((DestEncoding + i) == CheckEncoding)
4313 "the destination vector register group cannot overlap"
4314 " the source vector register group");
4320 int VMIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vm);
4321 assert(VMIdx >= 0 &&
"No vm operand?");
4323 if (DestReg == RISCV::V0) {
4326 return Error(Loc,
"the destination vector register group cannot be V0");
4334 "Unexpected mask operand register");
4336 return Error(Loc,
"the destination vector register group cannot overlap"
4337 " the mask register");
4345 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vmask);
4347 if (MaskReg != RISCV::V0 && MaskReg != RISCV::V1)
4348 return Error(Operands[VMaskIdx]->getStartLoc(),
4349 "vmask operand only supports v0 or v1");
4352 RISCV::OpName RegOps[] = {RISCV::OpName::vd, RISCV::OpName::vs1,
4353 RISCV::OpName::vs2};
4354 for (RISCV::OpName OpN : RegOps) {
4355 int Idx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), OpN);
4361 for (
unsigned i = 0; i < RegLmul; i++) {
4362 if ((RegEnc + i) == MaskEnc) {
4363 SMLoc Loc = Operands[Idx]->getStartLoc();
4364 return Error(Loc, Twine(
"register conflicts with vmask register ") +
4374bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
4382 case RISCV::PseudoC_ADDI_NOP: {
4384 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
4394 if (getSTI().
hasFeature(RISCV::Feature64Bit))
4396 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV32)
4401 case RISCV::PACKW: {
4405 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV64)
4410 case RISCV::PseudoLLAImm:
4411 case RISCV::PseudoLAImm:
4412 case RISCV::PseudoLI: {
4418 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
4430 emitLoadImm(
Reg, Imm, Out);
4433 case RISCV::PseudoLLA:
4434 emitLoadLocalAddress(Inst, IDLoc, Out);
4436 case RISCV::PseudoLGA:
4437 emitLoadGlobalAddress(Inst, IDLoc, Out);
4439 case RISCV::PseudoLA:
4440 emitLoadAddress(Inst, IDLoc, Out);
4442 case RISCV::PseudoLA_TLS_IE:
4443 emitLoadTLSIEAddress(Inst, IDLoc, Out);
4445 case RISCV::PseudoLA_TLS_GD:
4446 emitLoadTLSGDAddress(Inst, IDLoc, Out);
4448 case RISCV::PseudoLB:
4449 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
4451 case RISCV::PseudoLBU:
4452 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
4454 case RISCV::PseudoLH:
4455 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
4457 case RISCV::PseudoLHU:
4458 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
4460 case RISCV::PseudoLW:
4461 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
4463 case RISCV::PseudoLWU:
4464 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
4466 case RISCV::PseudoLD:
4467 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
4469 case RISCV::PseudoLD_RV32:
4470 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
4472 case RISCV::PseudoFLH:
4473 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
4475 case RISCV::PseudoFLW:
4476 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
4478 case RISCV::PseudoFLD:
4479 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
4481 case RISCV::PseudoFLQ:
4482 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
4484 case RISCV::PseudoSB:
4485 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
4487 case RISCV::PseudoSH:
4488 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
4490 case RISCV::PseudoSW:
4491 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
4493 case RISCV::PseudoSD:
4494 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
4496 case RISCV::PseudoSD_RV32:
4497 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
4499 case RISCV::PseudoQC_E_LB:
4500 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLB, IDLoc, Out,
4503 case RISCV::PseudoQC_E_LBU:
4504 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLBU, IDLoc, Out,
4507 case RISCV::PseudoQC_E_LH:
4508 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLH, IDLoc, Out,
4511 case RISCV::PseudoQC_E_LHU:
4512 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLHU, IDLoc, Out,
4515 case RISCV::PseudoQC_E_LW:
4516 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLW, IDLoc, Out,
4519 case RISCV::PseudoQC_E_SB:
4520 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSB, IDLoc, Out,
4523 case RISCV::PseudoQC_E_SH:
4524 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSH, IDLoc, Out,
4527 case RISCV::PseudoQC_E_SW:
4528 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSW, IDLoc, Out,
4531 case RISCV::PseudoFSH:
4532 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
4534 case RISCV::PseudoFSW:
4535 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
4537 case RISCV::PseudoFSD:
4538 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4540 case RISCV::PseudoFSQ:
4541 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4543 case RISCV::PseudoAddTPRel:
4544 if (checkPseudoAddTPRel(Inst, Operands))
4547 case RISCV::PseudoTLSDESCCall:
4548 if (checkPseudoTLSDESCCall(Inst, Operands))
4551 case RISCV::PseudoSEXT_B:
4552 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4554 case RISCV::PseudoSEXT_H:
4555 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4557 case RISCV::PseudoZEXT_H:
4558 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4560 case RISCV::PseudoZEXT_W:
4561 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4563 case RISCV::PseudoVMSGEU_VX_M:
4564 case RISCV::PseudoVMSGEU_VX_M_T:
4565 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4567 case RISCV::PseudoVMSGE_VX_M:
4568 case RISCV::PseudoVMSGE_VX_M_T:
4569 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4571 case RISCV::PseudoVMSGE_VI:
4572 case RISCV::PseudoVMSLT_VI: {
4576 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4578 emitToStreamer(Out, MCInstBuilder(
Opc)
4586 case RISCV::PseudoVMSGEU_VI:
4587 case RISCV::PseudoVMSLTU_VI: {
4594 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4597 emitToStreamer(Out, MCInstBuilder(
Opc)
4605 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4608 emitToStreamer(Out, MCInstBuilder(
Opc)
4618 case RISCV::PseudoCV_ELW:
4619 emitLoadStoreSymbol(Inst, RISCV::CV_ELW, IDLoc, Out,
false);
4623 emitToStreamer(Out, Inst);
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
static MCRegister MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, MCRegister &Reg, StringRef Name)
#define LLVM_EXTERNAL_VISIBILITY
const FeatureInfo AllFeatures[]
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static MCRegister convertGPRToYGPR(MCRegister Reg)
bool isValidInsnFormat(StringRef Format, const MCSubtargetInfo &STI)
static bool isZvvfmmScaleOpcode(unsigned Opcode)
static MCRegister convertFPR64ToFPR128(MCRegister Reg)
static MCRegister convertFPR64ToFPR32(MCRegister Reg)
static cl::opt< bool > AddBuildAttributes("riscv-add-build-attributes", cl::init(false))
static MCRegister convertFPR64ToFPR16(MCRegister Reg)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser()
static MCRegister convertFPR64ToFPR256(MCRegister Reg)
static MCRegister convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg, unsigned Kind)
static unsigned getNFforLXSEG(unsigned Opcode)
unsigned getLMULFromVectorRegister(MCRegister Reg)
static bool isUImm2(const MachineOperand &MO)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
StringRef getStringContents() const
Get the contents of a string token (without quotes).
bool is(TokenKind K) const
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Encoding
Size and signedness of expression operations' operands.
void printExpr(raw_ostream &, const MCExpr &) const
const AsmToken & getTok()
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
MCStreamer & getStreamer()
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
const MCObjectFileInfo * getObjectFileInfo() const
LLVM_ABI MCSymbol * createNamedTempSymbol()
Create a temporary symbol with a unique name whose name cannot be omitted in the symbol table.
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
ArrayRef< MCOperandInfo > operands() const
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
StringRef getName(unsigned Opcode) const
Returns the name for the instructions with the given opcode.
bool isPositionIndependent() const
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual MCRegister getReg() const =0
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const FeatureBitset & getFeatureBits() const
const FeatureBitset & ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
const MCSymbol * getAddSym() const
uint32_t getSpecifier() const
const MCSymbol * getSubSym() const
Ternary parse status returned by various parse* methods.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
static LLVM_ABI bool isSupportedExtensionFeature(StringRef Ext)
static LLVM_ABI std::string getTargetFeatureForExtension(StringRef Ext)
static LLVM_ABI llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseArchString(StringRef Arch, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck=true)
Parse RISC-V ISA info from arch string.
static const char * getRegisterName(MCRegister Reg)
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
std::string str() const
Get the contents as an std::string.
char back() const
Get the last character in the string.
A switch()-like statement whose cases are string literals.
StringSwitch & Cases(std::initializer_list< StringLiteral > CaseStrings, T Value)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
uint16_t StackAdjustment(const RuntimeFunction &RF)
StackAdjustment - calculated stack adjustment in words.
LLVM_ABI std::optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)
MCExpr const & getExpr(MCExpr const &Expr)
ABI computeTargetABI(const MCSubtargetInfo &STI, StringRef ABIName)
LLVM_ABI const TagNameMap & getRISCVAttributeTags()
static RoundingMode stringToRoundingMode(StringRef Str)
llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseFeatureBits(const MCSubtargetInfo &STI)
int getLoadFPImm(APFloat FPImm)
getLoadFPImm - Return a 5-bit binary encoding of the floating-point immediate value.
void generateMCInstSeq(int64_t Val, const MCSubtargetInfo &STI, MCRegister DestReg, SmallVectorImpl< MCInst > &Insts)
bool compress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI)
static VLMUL encodeLMUL(unsigned LMUL, bool Fractional)
LLVM_ABI unsigned encodeXSfmmVType(unsigned SEW, unsigned Widen, bool AltFmt)
static bool isValidLMUL(unsigned LMUL, bool Fractional)
static bool isValidSEW(unsigned SEW)
LLVM_ABI void printVType(unsigned VType, raw_ostream &OS)
static bool isValidXSfmmVType(unsigned VTypeI)
LLVM_ABI unsigned encodeVTYPE(VLMUL VLMUL, unsigned SEW, bool TailAgnostic, bool MaskAgnostic, bool AltFmt=false)
unsigned encodeRegList(MCRegister EndReg, bool IsRVE=false)
static unsigned getStackAdjBase(unsigned RlistVal, bool IsRV64)
void printRegList(unsigned RlistEncode, raw_ostream &OS)
Specifier parseSpecifierName(StringRef name)
void updateCZceFeatureImplications(MCSubtargetInfo &STI)
bool isValidYBNDSWImm(int64_t Imm)
@ CE
Windows NT (Windows on ARM)
static SMTVTypeMode stringToSMTVTypeMode(StringRef Str)
static bool isValidSMTVTypeMode(unsigned Mode)
@ Valid
The data is already valid.
initializer< Ty > init(const Ty &Val)
std::function< llvm::json::Value()> Lambda
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
testing::Matcher< const detail::ErrorHolder & > Failed()
Target & getTheRISCV32Target()
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Target & getTheRISCV64beTarget()
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isDigit(char C)
Checks if character C is one of the 10 decimal digits.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
DWARFExpression::Operation Op
Target & getTheRISCV64Target()
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
Target & getTheRISCV32beTarget()
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...