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"
237 return parseRegList(Operands,
true);
243 bool ExpectNegative =
false);
245 return parseZcmpStackAdj(Operands,
true);
248 bool parseOperand(
OperandVector &Operands, StringRef Mnemonic);
249 bool parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
250 bool parseDataExpr(
const MCExpr *&Res)
override;
252 bool parseDirectiveOption();
253 bool parseDirectiveAttribute();
254 bool parseDirectiveInsn(SMLoc L);
255 bool parseDirectiveVariantCC();
260 bool resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
261 bool FromOptionDirective);
263 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
265 MCSubtargetInfo &STI = copySTI();
271 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
275 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
277 MCSubtargetInfo &STI = copySTI();
278 setAvailableFeatures(
283 void pushFeatureBits() {
284 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
285 "These two stacks must be kept synchronized");
286 FeatureBitStack.push_back(getSTI().getFeatureBits());
287 ParserOptionsStack.push_back(ParserOptions);
290 bool popFeatureBits() {
291 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
292 "These two stacks must be kept synchronized");
293 if (FeatureBitStack.empty())
296 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
297 copySTI().setFeatureBits(FeatureBits);
298 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
300 ParserOptions = ParserOptionsStack.pop_back_val();
305 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
306 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
307 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
310 enum RISCVMatchResultTy :
unsigned {
311 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
312#define GET_OPERAND_DIAGNOSTIC_TYPES
313#include "RISCVGenAsmMatcher.inc"
314#undef GET_OPERAND_DIAGNOSTIC_TYPES
318 static bool isSymbolDiff(
const MCExpr *Expr);
320 RISCVAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
321 const MCInstrInfo &MII)
322 : MCTargetAsmParser(STI, MII) {
329 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
331 auto ABIName = StringRef(getTargetOptions().ABIName);
332 if (ABIName.ends_with(
"f") && !getSTI().
hasFeature(RISCV::FeatureStdExtF)) {
333 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
334 "doesn't support the F instruction set extension (ignoring "
336 }
else if (ABIName.ends_with(
"d") &&
337 !getSTI().
hasFeature(RISCV::FeatureStdExtD)) {
338 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
339 "doesn't support the D instruction set extension (ignoring "
351 getTargetStreamer().emitTargetAttributes(STI,
false);
417 MCRegister OffsetReg;
420 SMLoc StartLoc, EndLoc;
435 RISCVOperand(KindTy K) : Kind(
K) {}
438 RISCVOperand(
const RISCVOperand &o) : MCParsedAsmOperand() {
440 StartLoc =
o.StartLoc;
443 case KindTy::Register:
446 case KindTy::Expression:
449 case KindTy::FPImmediate:
455 case KindTy::SystemRegister:
467 case KindTy::RegList:
470 case KindTy::StackAdj:
471 StackAdj =
o.StackAdj;
479 bool isToken()
const override {
return Kind == KindTy::Token; }
480 bool isReg()
const override {
return Kind == KindTy::Register; }
481 bool isExpr()
const {
return Kind == KindTy::Expression; }
482 bool isV0Reg()
const {
483 return Kind == KindTy::Register &&
Reg.Reg == RISCV::V0;
485 bool isAnyReg()
const {
486 return Kind == KindTy::Register &&
487 (getRISCVMCRegisterClass(RISCV::GPRRegClassID).contains(
Reg.Reg) ||
488 getRISCVMCRegisterClass(RISCV::FPR64RegClassID).contains(
Reg.Reg) ||
489 getRISCVMCRegisterClass(RISCV::VRRegClassID).contains(
Reg.Reg));
491 bool isAnyRegC()
const {
492 return Kind == KindTy::Register &&
493 (getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(
Reg.Reg) ||
494 getRISCVMCRegisterClass(RISCV::FPR64CRegClassID).contains(
Reg.Reg));
496 bool isImm()
const override {
return isExpr(); }
497 bool isMem()
const override {
return false; }
498 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
499 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
500 bool isRegList()
const {
return Kind == KindTy::RegList; }
501 bool isRegListS0()
const {
502 return Kind == KindTy::RegList && RegList.Encoding !=
RISCVZC::RA;
504 bool isStackAdj()
const {
return Kind == KindTy::StackAdj; }
507 return Kind == KindTy::Register &&
508 getRISCVMCRegisterClass(RISCV::GPRRegClassID).contains(
Reg.Reg);
511 bool isYGPR()
const {
512 return Kind == KindTy::Register &&
513 getRISCVMCRegisterClass(RISCV::YGPRRegClassID).contains(
Reg.Reg);
516 bool isGPRPair()
const {
517 return Kind == KindTy::Register &&
518 getRISCVMCRegisterClass(RISCV::GPRPairRegClassID).contains(
Reg.Reg);
521 bool isGPRPairC()
const {
522 return Kind == KindTy::Register &&
523 getRISCVMCRegisterClass(RISCV::GPRPairCRegClassID).contains(
Reg.Reg);
526 bool isGPRPairNoX0()
const {
527 return Kind == KindTy::Register &&
528 getRISCVMCRegisterClass(RISCV::GPRPairNoX0RegClassID)
532 bool isGPRF16()
const {
533 return Kind == KindTy::Register &&
534 getRISCVMCRegisterClass(RISCV::GPRF16RegClassID).contains(
Reg.Reg);
537 bool isGPRF32()
const {
538 return Kind == KindTy::Register &&
539 getRISCVMCRegisterClass(RISCV::GPRF32RegClassID).contains(
Reg.Reg);
542 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
543 bool isGPRAsFPR16()
const {
return isGPRF16() &&
Reg.IsGPRAsFPR; }
544 bool isGPRAsFPR32()
const {
return isGPRF32() &&
Reg.IsGPRAsFPR; }
545 bool isGPRPairAsFPR64()
const {
return isGPRPair() &&
Reg.IsGPRAsFPR; }
547 static bool evaluateConstantExpr(
const MCExpr *Expr, int64_t &Imm) {
549 Imm =
CE->getValue();
558 template <
int N>
bool isBareSimmNLsb0()
const {
563 if (evaluateConstantExpr(
getExpr(), Imm))
564 return isShiftedInt<
N - 1, 1>(fixImmediateForRV32(Imm, isRV64Expr()));
567 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
573 template <
int N>
bool isBareSimmN()
const {
578 if (evaluateConstantExpr(
getExpr(), Imm))
579 return isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
582 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
588 bool isBareSymbol()
const {
591 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
595 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
599 bool isCallSymbol()
const {
602 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
606 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
610 bool isPseudoJumpSymbol()
const {
613 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
617 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
621 bool isTPRelAddSymbol()
const {
624 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
628 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
629 VK == ELF::R_RISCV_TPREL_ADD;
632 bool isTLSDESCCallSymbol()
const {
635 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
639 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
640 VK == ELF::R_RISCV_TLSDESC_CALL;
643 bool isQCAccessSymbol()
const {
646 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
650 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
654 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
658 bool isVTypeI10()
const {
659 if (Kind == KindTy::VType)
663 bool isVTypeI11()
const {
664 if (Kind == KindTy::VType)
669 bool isXSfmmVType()
const {
673 bool isTileLambda()
const {
674 return isUImmPred([](int64_t Imm) {
return Imm &&
isUInt<3>(Imm); });
679 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
682 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
683 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
687 bool isLoadFPImm()
const {
690 if (Kind != KindTy::FPImmediate)
693 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
696 return Idx >= 0 && Idx != 1;
699 bool isImmXLenLI()
const {
705 if (evaluateConstantExpr(
getExpr(), Imm))
708 return RISCVAsmParser::isSymbolDiff(
getExpr());
711 bool isImmXLenLI_Restricted()
const {
715 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
717 return IsConstantImm &&
721 template <
unsigned N>
bool isUImm()
const {
725 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
729 template <
unsigned N,
unsigned S>
bool isUImmShifted()
const {
733 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
737 template <
class Pred>
bool isUImmPred(Pred p)
const {
741 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
742 return IsConstantImm &&
p(Imm);
745 bool isUImmLog2XLen()
const {
746 if (isExpr() && isRV64Expr())
751 bool isUImmLog2XLenNonZero()
const {
752 if (isExpr() && isRV64Expr())
753 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<6>(Imm); });
754 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<5>(Imm); });
757 bool isUImmLog2XLenHalf()
const {
758 if (isExpr() && isRV64Expr())
763 bool isUImm1()
const {
return isUImm<1>(); }
764 bool isUImm2()
const {
return isUImm<2>(); }
765 bool isUImm3()
const {
return isUImm<3>(); }
766 bool isUImm4()
const {
return isUImm<4>(); }
767 bool isUImm5()
const {
return isUImm<5>(); }
768 bool isUImm6()
const {
return isUImm<6>(); }
769 bool isUImm7()
const {
return isUImm<7>(); }
770 bool isUImm8()
const {
return isUImm<8>(); }
771 bool isUImm9()
const {
return isUImm<9>(); }
772 bool isUImm10()
const {
return isUImm<10>(); }
773 bool isUImm11()
const {
return isUImm<11>(); }
774 bool isUImm16()
const {
return isUImm<16>(); }
775 bool isUImm20()
const {
return isUImm<20>(); }
776 bool isUImm32()
const {
return isUImm<32>(); }
777 bool isUImm48()
const {
return isUImm<48>(); }
778 bool isUImm64()
const {
return isUImm<64>(); }
780 bool isUImm5NonZero()
const {
781 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<5>(Imm); });
784 bool isUImm5GT3()
const {
785 return isUImmPred([](int64_t Imm) {
return isUInt<5>(Imm) &&
Imm > 3; });
788 bool isUImm4Plus1()
const {
790 [](int64_t Imm) {
return Imm > 0 &&
isUInt<4>(Imm - 1); });
793 bool isUImm5Plus1()
const {
795 [](int64_t Imm) {
return Imm > 0 &&
isUInt<5>(Imm - 1); });
798 bool isUImm6Plus1()
const {
800 [](int64_t Imm) {
return Imm > 0 &&
isUInt<6>(Imm - 1); });
803 bool isUImm5GE6Plus1()
const {
805 [](int64_t Imm) {
return Imm >= 6 &&
isUInt<5>(Imm - 1); });
808 bool isUImm5Slist()
const {
809 return isUImmPred([](int64_t Imm) {
810 return (Imm == 0) || (
Imm == 1) || (Imm == 2) || (
Imm == 4) ||
811 (Imm == 8) || (
Imm == 16) || (Imm == 15) || (
Imm == 31);
815 bool isUImm7EqXLen()
const {
817 [
this](int64_t Imm) {
return isRV64Expr() ?
Imm == 64 :
Imm == 32; });
820 bool isUImm8GE32()
const {
821 return isUImmPred([](int64_t Imm) {
return isUInt<8>(Imm) &&
Imm >= 32; });
824 bool isRnumArg()
const {
826 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(10); });
829 bool isRnumArg_0_7()
const {
831 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(7); });
834 bool isRnumArg_1_10()
const {
836 [](int64_t Imm) {
return Imm >= INT64_C(1) &&
Imm <= INT64_C(10); });
839 bool isRnumArg_2_14()
const {
841 [](int64_t Imm) {
return Imm >= INT64_C(2) &&
Imm <= INT64_C(14); });
844 template <
unsigned N>
bool isSImm()
const {
848 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
849 return IsConstantImm &&
isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
852 bool isYBNDSWImm()
const {
857 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
861 template <
class Pred>
bool isSImmPred(Pred p)
const {
865 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
866 return IsConstantImm &&
p(fixImmediateForRV32(Imm, isRV64Expr()));
869 bool isSImm5()
const {
return isSImm<5>(); }
870 bool isSImm6()
const {
return isSImm<6>(); }
871 bool isSImm10()
const {
return isSImm<10>(); }
872 bool isSImm11()
const {
return isSImm<11>(); }
873 bool isSImm12()
const {
return isSImm<12>(); }
874 bool isSImm16()
const {
return isSImm<16>(); }
875 bool isSImm26()
const {
return isSImm<26>(); }
877 bool isSImm5NonZero()
const {
878 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<5>(Imm); });
881 bool isSImm6NonZero()
const {
882 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<6>(Imm); });
885 bool isCLUIImm()
const {
886 return isUImmPred([](int64_t Imm) {
887 return (
isUInt<5>(Imm) && Imm != 0) || (
Imm >= 0xfffe0 &&
Imm <= 0xfffff);
891 bool isUImm2Lsb0()
const {
return isUImmShifted<1, 1>(); }
893 bool isUImm5Lsb0()
const {
return isUImmShifted<4, 1>(); }
895 bool isUImm6Lsb0()
const {
return isUImmShifted<5, 1>(); }
897 bool isUImm7Lsb00()
const {
return isUImmShifted<5, 2>(); }
899 bool isUImm7Lsb000()
const {
return isUImmShifted<4, 3>(); }
901 bool isUImm8Lsb00()
const {
return isUImmShifted<6, 2>(); }
903 bool isUImm8Lsb000()
const {
return isUImmShifted<5, 3>(); }
905 bool isUImm9Lsb000()
const {
return isUImmShifted<6, 3>(); }
907 bool isUImm14Lsb00()
const {
return isUImmShifted<12, 2>(); }
909 bool isUImm10Lsb00NonZero()
const {
916 static int64_t fixImmediateForRV32(int64_t Imm,
bool IsRV64Imm) {
922 bool isSImm12LO()
const {
927 if (evaluateConstantExpr(
getExpr(), Imm))
928 return isInt<12>(fixImmediateForRV32(Imm, isRV64Expr()));
931 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
934 VK == ELF::R_RISCV_TLSDESC_ADD_LO12);
937 bool isSImm12Lsb00000()
const {
941 bool isSImm10Lsb0000NonZero()
const {
946 bool isSImm16NonZero()
const {
947 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<16>(Imm); });
950 bool isUImm16NonZero()
const {
951 return isUImmPred([](int64_t Imm) {
return isUInt<16>(Imm) &&
Imm != 0; });
954 bool isSImm20LI()
const {
959 if (evaluateConstantExpr(
getExpr(), Imm))
960 return isInt<20>(fixImmediateForRV32(Imm, isRV64Expr()));
963 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
967 bool isSImm8PLI_B()
const {
return isSImm<8>() || isUImm<8>(); }
968 bool isSImm10PLUI()
const {
return isSImm<10>() || isUImm<10>(); }
970 bool isSImm10PLI_H()
const {
971 return isSImm<10>() || isUImmPred([](int64_t Imm) {
975 bool isSImm10PLI_W()
const {
976 return isSImm<10>() || isUImmPred([](int64_t Imm) {
981 bool isUImm20LUI()
const {
986 if (evaluateConstantExpr(
getExpr(), Imm))
990 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
991 (VK == ELF::R_RISCV_HI20 || VK == ELF::R_RISCV_TPREL_HI20);
994 bool isUImm20AUIPC()
const {
999 if (evaluateConstantExpr(
getExpr(), Imm))
1003 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
1005 VK == ELF::R_RISCV_TLS_GOT_HI20 || VK == ELF::R_RISCV_TLS_GD_HI20 ||
1006 VK == ELF::R_RISCV_TLSDESC_HI20);
1009 bool isImmZero()
const {
1010 return isUImmPred([](int64_t Imm) {
return 0 ==
Imm; });
1013 bool isImmThree()
const {
1014 return isUImmPred([](int64_t Imm) {
return 3 ==
Imm; });
1017 bool isImmFour()
const {
1018 return isUImmPred([](int64_t Imm) {
return 4 ==
Imm; });
1021 bool isImm5Zibi()
const {
1023 [](int64_t Imm) {
return (Imm != 0 &&
isUInt<5>(Imm)) ||
Imm == -1; });
1026 bool isSImm5Plus1()
const {
1031 bool isSImm18()
const {
1032 return isSImmPred([](int64_t Imm) {
return isInt<18>(Imm); });
1035 bool isSImm18Lsb0()
const {
1039 bool isSImm19Lsb00()
const {
1043 bool isSImm20Lsb000()
const {
1047 bool isSImm32Lsb0()
const {
1052 SMLoc getStartLoc()
const override {
return StartLoc; }
1054 SMLoc getEndLoc()
const override {
return EndLoc; }
1057 bool isRV64Expr()
const {
1058 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1062 MCRegister
getReg()
const override {
1063 assert(Kind == KindTy::Register &&
"Invalid type access!");
1067 StringRef getSysReg()
const {
1068 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
1069 return StringRef(SysReg.Data, SysReg.Length);
1072 const MCExpr *
getExpr()
const {
1073 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1077 uint64_t getFPConst()
const {
1078 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1083 assert(Kind == KindTy::Token &&
"Invalid type access!");
1087 unsigned getVType()
const {
1088 assert(Kind == KindTy::VType &&
"Invalid type access!");
1093 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1097 unsigned getFence()
const {
1098 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1102 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1111 case KindTy::Expression:
1114 OS <<
' ' << (Expr.IsRV64 ?
"rv64" :
"rv32") <<
'>';
1116 case KindTy::FPImmediate:
1117 OS <<
"<fpimm: " << FPImm.Val <<
">";
1119 case KindTy::Register:
1121 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1126 case KindTy::SystemRegister:
1127 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1136 OS << roundingModeToString(getFRM());
1144 case KindTy::RegList:
1149 case KindTy::StackAdj:
1150 OS <<
"<stackadj: ";
1154 case KindTy::RegReg:
1155 OS <<
"<RegReg: BaseReg " <<
RegName(
RegReg.BaseReg) <<
" OffsetReg "
1161 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1162 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1169 static std::unique_ptr<RISCVOperand>
1170 createReg(MCRegister
Reg, SMLoc S, SMLoc
E,
bool IsGPRAsFPR =
false) {
1171 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1173 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1179 static std::unique_ptr<RISCVOperand> createExpr(
const MCExpr *Val, SMLoc S,
1180 SMLoc
E,
bool IsRV64) {
1181 auto Op = std::make_unique<RISCVOperand>(KindTy::Expression);
1182 Op->Expr.Expr = Val;
1183 Op->Expr.IsRV64 = IsRV64;
1189 static std::unique_ptr<RISCVOperand> createFPImm(uint64_t Val, SMLoc S) {
1190 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1191 Op->FPImm.Val = Val;
1197 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1198 unsigned Encoding) {
1199 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1200 Op->SysReg.Data = Str.data();
1201 Op->SysReg.Length = Str.size();
1208 static std::unique_ptr<RISCVOperand>
1210 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1217 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val, SMLoc S) {
1218 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1219 Op->Fence.Val = Val;
1225 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI, SMLoc S) {
1226 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1227 Op->VType.Val = VTypeI;
1233 static std::unique_ptr<RISCVOperand> createRegList(
unsigned RlistEncode,
1235 auto Op = std::make_unique<RISCVOperand>(KindTy::RegList);
1241 static std::unique_ptr<RISCVOperand>
1242 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {
1243 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1245 Op->RegReg.OffsetReg = OffsetReg;
1251 static std::unique_ptr<RISCVOperand> createStackAdj(
unsigned StackAdj, SMLoc S) {
1252 auto Op = std::make_unique<RISCVOperand>(KindTy::StackAdj);
1253 Op->StackAdj.Val = StackAdj;
1258 static void addExpr(MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1259 assert(Expr &&
"Expr shouldn't be null!");
1261 bool IsConstant = evaluateConstantExpr(Expr, Imm);
1271 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1272 assert(
N == 1 &&
"Invalid number of operands!");
1276 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1277 assert(
N == 1 &&
"Invalid number of operands!");
1278 addExpr(Inst,
getExpr(), isRV64Expr());
1281 template <
unsigned Bits>
1282 void addSExtImmOperands(MCInst &Inst,
unsigned N)
const {
1283 assert(
N == 1 &&
"Invalid number of operands!");
1290 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
1291 assert(
N == 1 &&
"Invalid number of operands!");
1293 addExpr(Inst,
getExpr(), isRV64Expr());
1298 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1302 void addFenceArgOperands(MCInst &Inst,
unsigned N)
const {
1303 assert(
N == 1 &&
"Invalid number of operands!");
1307 void addCSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
1308 assert(
N == 1 &&
"Invalid number of operands!");
1315 void addVTypeIOperands(MCInst &Inst,
unsigned N)
const {
1316 assert(
N == 1 &&
"Invalid number of operands!");
1318 if (Kind == KindTy::Expression) {
1319 [[maybe_unused]]
bool IsConstantImm =
1320 evaluateConstantExpr(
getExpr(), Imm);
1321 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1328 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1329 assert(
N == 1 &&
"Invalid number of operands!");
1333 void addRegRegOperands(MCInst &Inst,
unsigned N)
const {
1334 assert(
N == 2 &&
"Invalid number of operands!");
1339 void addStackAdjOperands(MCInst &Inst,
unsigned N)
const {
1340 assert(
N == 1 &&
"Invalid number of operands!");
1344 void addFRMArgOperands(MCInst &Inst,
unsigned N)
const {
1345 assert(
N == 1 &&
"Invalid number of operands!");
1351#define GET_REGISTER_MATCHER
1352#define GET_SUBTARGET_FEATURE_NAME
1353#define GET_MATCHER_IMPLEMENTATION
1354#define GET_MNEMONIC_SPELL_CHECKER
1355#include "RISCVGenAsmMatcher.inc"
1358 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1359 return Reg - RISCV::F0_D + RISCV::F0_H;
1363 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1364 return Reg - RISCV::F0_D + RISCV::F0_F;
1368 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1369 return Reg - RISCV::F0_D + RISCV::F0_Q;
1373 assert(
Reg >= RISCV::X0 &&
Reg <= RISCV::X31 &&
"Invalid register");
1374 return Reg - RISCV::X0 + RISCV::X0_Y;
1379 unsigned RegClassID;
1380 if (Kind == MCK_VRM2)
1381 RegClassID = RISCV::VRM2RegClassID;
1382 else if (Kind == MCK_VRM4)
1383 RegClassID = RISCV::VRM4RegClassID;
1384 else if (Kind == MCK_VRM8)
1385 RegClassID = RISCV::VRM8RegClassID;
1389 &getRISCVMCRegisterClass(RegClassID));
1393 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1394 return Reg - RISCV::F0_D + RISCV::F0_Q2;
1399 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1401 return Match_InvalidOperand;
1403 MCRegister
Reg =
Op.getReg();
1405 getRISCVMCRegisterClass(RISCV::FPR64RegClassID).contains(
Reg);
1407 getRISCVMCRegisterClass(RISCV::FPR64CRegClassID).contains(
Reg);
1408 bool IsRegVR = getRISCVMCRegisterClass(RISCV::VRRegClassID).contains(
Reg);
1410 if (
Op.isGPR() && Kind == MCK_YGPR) {
1413 return Match_Success;
1415 if (IsRegFPR64 && Kind == MCK_FPR256) {
1417 return Match_Success;
1419 if (IsRegFPR64 && Kind == MCK_FPR128) {
1421 return Match_Success;
1425 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1426 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1428 return Match_Success;
1432 if (IsRegFPR64 && Kind == MCK_FPR16) {
1434 return Match_Success;
1436 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1437 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_H;
1438 return Match_Success;
1440 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1441 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_W;
1442 return Match_Success;
1449 if (getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg) &&
1450 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1452 return Match_Success;
1456 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1459 return Match_InvalidOperand;
1460 return Match_Success;
1462 return Match_InvalidOperand;
1465bool RISCVAsmParser::generateImmOutOfRangeError(
1466 SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
1467 const Twine &
Msg =
"immediate must be an integer in the range") {
1474std::string RISCVAsmParser::getCustomOperandDiag(
unsigned MatchError) {
1476 StringRef
Msg =
"immediate must be an integer in the range") {
1477 return (
Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]").str();
1480 switch (MatchError) {
1484 if (
const char *Diag = getMatchKindDiag((RISCVMatchResultTy)MatchError))
1486 return std::string();
1487 case Match_InvalidImmXLenLI:
1489 return "operand must be a constant 64-bit integer";
1490 return Range(std::numeric_limits<int32_t>::min(),
1491 std::numeric_limits<uint32_t>::max());
1492 case Match_InvalidImmXLenLI_Restricted:
1494 return "operand either must be a constant 64-bit integer "
1495 "or a bare symbol name";
1496 return Range(std::numeric_limits<int32_t>::min(),
1497 std::numeric_limits<uint32_t>::max(),
1498 "operand either must be a bare symbol name or an immediate "
1499 "integer in the range");
1500 case Match_InvalidUImmLog2XLen:
1502 return Range(0, (1 << 6) - 1);
1503 return Range(0, (1 << 5) - 1);
1504 case Match_InvalidUImmLog2XLenNonZero:
1506 return Range(1, (1 << 6) - 1);
1507 return Range(1, (1 << 5) - 1);
1508 case Match_InvalidUImm1:
1509 return Range(0, (1 << 1) - 1);
1510 case Match_InvalidUImm2:
1511 return Range(0, (1 << 2) - 1);
1512 case Match_InvalidUImm2Lsb0:
1513 return Range(0, 2,
"immediate must be one of");
1514 case Match_InvalidUImm3:
1515 return Range(0, (1 << 3) - 1);
1516 case Match_InvalidUImm4:
1517 return Range(0, (1 << 4) - 1);
1518 case Match_InvalidUImm4Plus1:
1519 return Range(1, (1 << 4));
1520 case Match_InvalidUImm5:
1521 return Range(0, (1 << 5) - 1);
1522 case Match_InvalidUImm5NonZero:
1523 return Range(1, (1 << 5) - 1);
1524 case Match_InvalidUImm5GT3:
1525 return Range(4, (1 << 5) - 1);
1526 case Match_InvalidUImm5Plus1:
1527 return Range(1, (1 << 5));
1528 case Match_InvalidUImm5GE6Plus1:
1529 return Range(6, (1 << 5));
1530 case Match_InvalidUImm5Slist:
1531 return "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31";
1532 case Match_InvalidUImm6:
1533 return Range(0, (1 << 6) - 1);
1534 case Match_InvalidUImm6Plus1:
1535 return Range(1, (1 << 6));
1536 case Match_InvalidUImm7:
1537 return Range(0, (1 << 7) - 1);
1538 case Match_InvalidUImm8:
1539 return Range(0, (1 << 8) - 1);
1540 case Match_InvalidUImm8GE32:
1541 return Range(32, (1 << 8) - 1);
1542 case Match_InvalidSImm5:
1543 return Range(-(1 << 4), (1 << 4) - 1);
1544 case Match_InvalidSImm5NonZero:
1545 return Range(-(1 << 4), (1 << 4) - 1,
1546 "immediate must be non-zero in the range");
1547 case Match_InvalidSImm6:
1548 return Range(-(1 << 5), (1 << 5) - 1);
1549 case Match_InvalidSImm6NonZero:
1550 return Range(-(1 << 5), (1 << 5) - 1,
1551 "immediate must be non-zero in the range");
1552 case Match_InvalidCLUIImm:
1553 return Range(1, (1 << 5) - 1,
"immediate must be in [0xfffe0, 0xfffff] or");
1554 case Match_InvalidUImm5Lsb0:
1555 return Range(0, (1 << 5) - 2,
1556 "immediate must be a multiple of 2 bytes in the range");
1557 case Match_InvalidUImm6Lsb0:
1558 return Range(0, (1 << 6) - 2,
1559 "immediate must be a multiple of 2 bytes in the range");
1560 case Match_InvalidUImm7Lsb00:
1561 return Range(0, (1 << 7) - 4,
1562 "immediate must be a multiple of 4 bytes in the range");
1563 case Match_InvalidUImm8Lsb00:
1564 return Range(0, (1 << 8) - 4,
1565 "immediate must be a multiple of 4 bytes in the range");
1566 case Match_InvalidUImm8Lsb000:
1567 return Range(0, (1 << 8) - 8,
1568 "immediate must be a multiple of 8 bytes in the range");
1569 case Match_InvalidUImm9:
1570 return Range(0, (1 << 9) - 1,
"immediate offset must be in the range");
1571 case Match_InvalidBareSImm9Lsb0:
1572 return Range(-(1 << 8), (1 << 8) - 2,
1573 "immediate must be a multiple of 2 bytes in the range");
1574 case Match_InvalidUImm9Lsb000:
1575 return Range(0, (1 << 9) - 8,
1576 "immediate must be a multiple of 8 bytes in the range");
1577 case Match_InvalidSImm8PLI_B:
1578 return Range(-(1 << 7), (1 << 8) - 1);
1579 case Match_InvalidSImm10:
1580 case Match_InvalidSImm10PLI_H:
1581 case Match_InvalidSImm10PLI_W:
1582 return Range(-(1 << 9), (1 << 9) - 1);
1583 case Match_InvalidSImm10PLUI:
1584 return Range(-(1 << 9), (1 << 10) - 1);
1585 case Match_InvalidUImm10Lsb00NonZero:
1586 return Range(4, (1 << 10) - 4,
1587 "immediate must be a multiple of 4 bytes in the range");
1588 case Match_InvalidSImm10Lsb0000NonZero:
1590 -(1 << 9), (1 << 9) - 16,
1591 "immediate must be a multiple of 16 bytes and non-zero in the range");
1592 case Match_InvalidSImm11:
1593 return Range(-(1 << 10), (1 << 10) - 1);
1594 case Match_InvalidBareSImm11Lsb0:
1595 return Range(-(1 << 10), (1 << 10) - 2,
1596 "immediate must be a multiple of 2 bytes in the range");
1597 case Match_InvalidUImm10:
1598 return Range(0, (1 << 10) - 1);
1599 case Match_InvalidUImm11:
1600 return Range(0, (1 << 11) - 1);
1601 case Match_InvalidUImm14Lsb00:
1602 return Range(0, (1 << 14) - 4,
1603 "immediate must be a multiple of 4 bytes in the range");
1604 case Match_InvalidUImm16NonZero:
1605 return Range(1, (1 << 16) - 1);
1606 case Match_InvalidSImm12:
1607 return Range(-(1 << 11), (1 << 11) - 1);
1608 case Match_InvalidSImm12LO:
1609 return Range(-(1 << 11), (1 << 11) - 1,
1610 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo "
1611 "specifier or an integer in the range");
1612 case Match_InvalidBareSImm12Lsb0:
1613 return Range(-(1 << 11), (1 << 11) - 2,
1614 "immediate must be a multiple of 2 bytes in the range");
1615 case Match_InvalidSImm12Lsb00000:
1616 return Range(-(1 << 11), (1 << 11) - 32,
1617 "immediate must be a multiple of 32 bytes in the range");
1618 case Match_InvalidBareSImm13Lsb0:
1619 return Range(-(1 << 12), (1 << 12) - 2,
1620 "immediate must be a multiple of 2 bytes in the range");
1621 case Match_InvalidSImm16:
1622 return Range(-(1 << 15), (1 << 15) - 1);
1623 case Match_InvalidSImm16NonZero:
1624 return Range(-(1 << 15), (1 << 15) - 1,
1625 "immediate must be non-zero in the range");
1626 case Match_InvalidSImm20LI:
1627 return Range(-(1 << 19), (1 << 19) - 1,
1628 "operand must be a symbol with a %qc.abs20 specifier or an "
1629 "integer in the range");
1630 case Match_InvalidUImm20LUI:
1631 return Range(0, (1 << 20) - 1,
1632 "operand must be a symbol with %hi/%tprel_hi specifier or an "
1633 "integer in the range");
1634 case Match_InvalidUImm20:
1635 return Range(0, (1 << 20) - 1);
1636 case Match_InvalidUImm20AUIPC:
1639 "operand must be a symbol with a "
1640 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
1641 "or an integer in the range");
1642 case Match_InvalidBareSImm21Lsb0:
1643 return Range(-(1 << 20), (1 << 20) - 2,
1644 "immediate must be a multiple of 2 bytes in the range");
1645 case Match_InvalidCSRSystemRegister:
1646 return Range(0, (1 << 12) - 1,
1647 "operand must be a valid system register name or an integer "
1649 case Match_InvalidImm5Zibi:
1650 return Range(-1, (1 << 5) - 1,
"immediate must be non-zero in the range");
1651 case Match_InvalidVTypeI:
1652 return "operand must be "
1653 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]";
1654 case Match_InvalidSImm5Plus1:
1655 return Range(-(1 << 4) + 1, (1 << 4),
"immediate must be in the range");
1656 case Match_InvalidSImm18:
1657 return Range(-(1 << 17), (1 << 17) - 1);
1658 case Match_InvalidSImm18Lsb0:
1659 return Range(-(1 << 17), (1 << 17) - 2,
1660 "immediate must be a multiple of 2 bytes in the range");
1661 case Match_InvalidSImm19Lsb00:
1662 return Range(-(1 << 18), (1 << 18) - 4,
1663 "immediate must be a multiple of 4 bytes in the range");
1664 case Match_InvalidSImm20Lsb000:
1665 return Range(-(1 << 19), (1 << 19) - 8,
1666 "immediate must be a multiple of 8 bytes in the range");
1667 case Match_InvalidSImm26:
1668 return Range(-(1 << 25), (1 << 25) - 1);
1670 case Match_InvalidBareSymbolQC_E_LI:
1673 case Match_InvalidBareSImm32:
1674 return Range(std::numeric_limits<int32_t>::min(),
1675 std::numeric_limits<uint32_t>::max());
1676 case Match_InvalidBareSImm32Lsb0:
1677 return Range(std::numeric_limits<int32_t>::min(),
1678 std::numeric_limits<int32_t>::max() - 1,
1679 "operand must be a multiple of 2 bytes in the range");
1680 case Match_InvalidRnumArg:
1681 return Range(0, 10);
1682 case Match_InvalidStackAdj:
1683 return "stack adjustment is invalid for this instruction and register "
1685 case Match_InvalidYBNDSWImm:
1686 return "immediate must be an integer in the range "
1687 "[1, 255], a multiple of 8 in the range [256, 504], "
1688 "or a multiple of 16 in the range [512, 4096]";
1689 case Match_InvalidUImm7EqXLen:
1690 return (
"immediate must be an integer equal to XLEN (" +
1691 Twine(isRV64() ?
"64" :
"32") +
")")
1699void RISCVAsmParser::FilterNearMisses(
1700 SmallVectorImpl<NearMissInfo> &NearMissesIn,
1701 SmallVectorImpl<NearMissMessage> &NearMissesOut, SMLoc IDLoc,
1705 std::multimap<unsigned, unsigned> OperandMissesSeen;
1706 SmallSet<FeatureBitset, 4> FeatureMissesSeen;
1707 bool ReportedTooFewOperands =
false;
1708 bool ReportedTooManyOperands =
false;
1710 for (NearMissInfo &
I : NearMissesIn) {
1711 switch (
I.getKind()) {
1714 ((RISCVOperand &)*Operands[
I.getOperandIndex()]).getStartLoc();
1719 if (
I.getOperandClass() == InvalidMatchClass) {
1720 if (!ReportedTooManyOperands) {
1722 OperandLoc,
"unexpected extra operand for instruction"});
1723 ReportedTooManyOperands =
true;
1728 std::string OperandDiag = getCustomOperandDiag(
I.getOperandError());
1732 unsigned DupCheckMatchClass =
1733 OperandDiag.empty() ? ~0
U :
I.getOperandClass();
1734 auto PrevReports = OperandMissesSeen.equal_range(
I.getOperandIndex());
1736 PrevReports.first, PrevReports.second,
1737 [DupCheckMatchClass](
const std::pair<unsigned, unsigned> Pair) {
1738 if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
1739 return Pair.second == DupCheckMatchClass;
1740 return isSubclass((MatchClassKind)DupCheckMatchClass,
1741 (MatchClassKind)Pair.second);
1744 OperandMissesSeen.insert(
1745 std::make_pair(
I.getOperandIndex(), DupCheckMatchClass));
1747 NearMissMessage Message;
1748 Message.Loc = OperandLoc;
1749 if (!OperandDiag.empty()) {
1750 Message.Message = OperandDiag;
1752 Message.Message =
"invalid operand for instruction";
1754 dbgs() <<
"Missing diagnostic string for operand class "
1755 << getMatchClassName((MatchClassKind)
I.getOperandClass())
1756 <<
I.getOperandClass() <<
", error " <<
I.getOperandError()
1757 <<
", opcode " << MII.
getName(
I.getOpcode()) <<
"\n");
1763 const FeatureBitset &MissingFeatures =
I.getFeatures();
1765 if (!FeatureMissesSeen.
insert(MissingFeatures).second)
1768 NearMissMessage Message;
1769 Message.Loc = IDLoc;
1770 bool FirstFeature =
true;
1771 Message.Message =
"instruction requires the following:";
1772 for (
unsigned Feature : MissingFeatures) {
1773 Message.Message += FirstFeature ?
" " :
", ";
1775 FirstFeature =
false;
1785 if (!ReportedTooFewOperands) {
1786 SMLoc EndLoc = ((RISCVOperand &)*Operands.
back()).getEndLoc();
1788 NearMissMessage{EndLoc,
"too few operands for instruction"});
1789 ReportedTooFewOperands =
true;
1801void RISCVAsmParser::ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses,
1804 FilterNearMisses(NearMisses, Messages, IDLoc, Operands);
1809 Error(IDLoc,
"invalid instruction");
1812 Error(Messages[0].Loc, Messages[0].Message);
1817 "invalid instruction, any one of the following would fix this:");
1818 for (
auto &M : Messages)
1823bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1826 uint64_t &ErrorInfo,
1827 bool MatchingInlineAsm) {
1832 MatchInstructionImpl(Operands, Inst, &NearMisses, MatchingInlineAsm);
1837 if (validateInstruction(Inst, Operands))
1839 return processInstruction(Inst, IDLoc, Operands, Out);
1840 case Match_MnemonicFail: {
1841 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1842 std::string Suggestion = RISCVMnemonicSpellCheck(
1843 ((RISCVOperand &)*Operands[0]).
getToken(), FBS, 0);
1844 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1846 case Match_NearMisses:
1847 ReportNearMisses(NearMisses, IDLoc, Operands);
1858MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name)
const {
1867 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1868 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1869 static_assert(RISCV::F0_D < RISCV::F0_Q,
"FPR matching must be updated");
1872 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1877bool RISCVAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1879 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1880 return Error(StartLoc,
"invalid register name");
1884ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1886 const AsmToken &Tok = getParser().getTok();
1889 StringRef
Name = getLexer().getTok().getIdentifier();
1899ParseStatus RISCVAsmParser::parseRegister(
OperandVector &Operands,
1901 SMLoc FirstS = getLoc();
1902 bool HadParens =
false;
1909 size_t ReadCount = getLexer().peekTokens(Buf);
1912 LParen = getParser().getTok();
1917 switch (getLexer().getKind()) {
1920 getLexer().UnLex(LParen);
1923 StringRef
Name = getLexer().getTok().getIdentifier();
1928 getLexer().UnLex(LParen);
1932 Operands.
push_back(RISCVOperand::createToken(
"(", FirstS));
1934 SMLoc
E = getTok().getEndLoc();
1941 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
1947ParseStatus RISCVAsmParser::parseInsnDirectiveOpcode(
OperandVector &Operands) {
1952 switch (getLexer().getKind()) {
1962 if (getParser().parseExpression(Res,
E))
1967 int64_t
Imm =
CE->getValue();
1969 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1978 if (getParser().parseIdentifier(Identifier))
1981 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1984 "Unexpected opcode");
1987 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1997 return generateImmOutOfRangeError(
1999 "opcode must be a valid opcode name or an immediate in the range");
2002ParseStatus RISCVAsmParser::parseInsnCDirectiveOpcode(
OperandVector &Operands) {
2007 switch (getLexer().getKind()) {
2017 if (getParser().parseExpression(Res,
E))
2022 int64_t
Imm =
CE->getValue();
2023 if (Imm >= 0 && Imm <= 2) {
2024 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2033 if (getParser().parseIdentifier(Identifier))
2037 if (Identifier ==
"C0")
2039 else if (Identifier ==
"C1")
2041 else if (Identifier ==
"C2")
2048 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2057 return generateImmOutOfRangeError(
2059 "opcode must be a valid opcode name or an immediate in the range");
2062ParseStatus RISCVAsmParser::parseCSRSystemRegister(
OperandVector &Operands) {
2066 auto SysRegFromConstantInt = [
this](
const MCExpr *
E, SMLoc S) {
2068 int64_t
Imm =
CE->getValue();
2070 auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
2074 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2077 return RISCVOperand::createSysReg(
2078 RISCVSysReg::getSysRegStr(
Reg.Name), S, Imm);
2082 return RISCVOperand::createSysReg(
"", S, Imm);
2085 return std::unique_ptr<RISCVOperand>();
2088 switch (getLexer().getKind()) {
2098 if (getParser().parseExpression(Res))
2101 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
2106 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2110 if (getParser().parseIdentifier(Identifier))
2113 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
2116 if (SysReg->IsDeprecatedName) {
2118 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
2120 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2122 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
2123 RISCVSysReg::getSysRegStr(
Reg.Name) +
"'");
2128 const auto &FeatureBits = getSTI().getFeatureBits();
2129 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
2130 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
2131 const auto *Feature =
2133 return SysReg->FeaturesRequired[Feature.Value];
2135 std::string ErrorMsg =
2136 std::string(
"system register '") +
2137 std::string(RISCVSysReg::getSysRegStr(SysReg->Name)) +
"' ";
2138 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
2139 ErrorMsg +=
"is RV32 only";
2141 ErrorMsg +=
" and ";
2145 "requires '" + std::string(Feature->key()) +
"' to be enabled";
2148 return Error(S, ErrorMsg);
2151 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
2166 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2167 "operand must be a valid system register "
2168 "name or an integer in the range");
2172 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2179ParseStatus RISCVAsmParser::parseFPImm(
OperandVector &Operands) {
2184 StringRef
Identifier = getTok().getIdentifier();
2185 if (
Identifier.compare_insensitive(
"inf") == 0) {
2188 getTok().getEndLoc(), isRV64()));
2189 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2192 getTok().getEndLoc(), isRV64()));
2193 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2196 getTok().getEndLoc(), isRV64()));
2198 return TokError(
"invalid floating point literal");
2209 const AsmToken &Tok = getTok();
2211 return TokError(
"invalid floating point immediate");
2214 APFloat RealVal(APFloat::IEEEdouble());
2216 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2218 return TokError(
"invalid floating point representation");
2221 RealVal.changeSign();
2223 Operands.
push_back(RISCVOperand::createFPImm(
2224 RealVal.bitcastToAPInt().getZExtValue(), S));
2231ParseStatus RISCVAsmParser::parseExpression(
OperandVector &Operands) {
2236 switch (getLexer().getKind()) {
2248 if (getParser().parseExpression(Res,
E))
2252 return parseOperandWithSpecifier(Operands);
2255 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2259ParseStatus RISCVAsmParser::parseOperandWithSpecifier(
OperandVector &Operands) {
2265 const MCExpr *Expr =
nullptr;
2266 bool Failed = parseExprWithSpecifier(Expr,
E);
2268 Operands.
push_back(RISCVOperand::createExpr(Expr, S,
E, isRV64()));
2272bool RISCVAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
2273 SMLoc Loc = getLoc();
2275 return TokError(
"expected '%' relocation specifier");
2276 StringRef
Identifier = getParser().getTok().getIdentifier();
2279 return TokError(
"invalid relocation specifier");
2285 const MCExpr *SubExpr;
2286 if (getParser().parseParenExpression(SubExpr,
E))
2293bool RISCVAsmParser::parseDataExpr(
const MCExpr *&Res) {
2296 return parseExprWithSpecifier(Res,
E);
2297 return getParser().parseExpression(Res);
2300ParseStatus RISCVAsmParser::parseBareSymbol(
OperandVector &Operands) {
2307 StringRef
Identifier = getTok().getIdentifier();
2317 if (getParser().parseExpression(Res,
E))
2320 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2324ParseStatus RISCVAsmParser::parseCallSymbol(
OperandVector &Operands) {
2330 std::string
Identifier(getTok().getIdentifier());
2336 SMLoc Loc = getLoc();
2337 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2338 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2352 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2356ParseStatus RISCVAsmParser::parsePseudoJumpSymbol(
OperandVector &Operands) {
2361 if (getParser().parseExpression(Res,
E))
2364 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef)
2365 return Error(S,
"operand must be a valid jump target");
2368 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2372ParseStatus RISCVAsmParser::parseJALOffset(
OperandVector &Operands) {
2386 return parseExpression(Operands);
2389bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2390 unsigned &Sew,
unsigned &Lmul,
2391 bool &Fractional,
bool &TailAgnostic,
2392 bool &MaskAgnostic,
bool &AltFmt) {
2397 if (State < VTypeState::SeenSew &&
Identifier.consume_front(
"e")) {
2399 if (Identifier ==
"16alt") {
2402 }
else if (Identifier ==
"8alt") {
2412 State = VTypeState::SeenSew;
2416 if (State < VTypeState::SeenLmul &&
Identifier.consume_front(
"m")) {
2419 if (Identifier ==
"a" || Identifier ==
"u") {
2421 State = VTypeState::SeenMaskPolicy;
2432 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2433 unsigned MinLMUL = ELEN / 8;
2436 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2437 Twine(MinLMUL) +
" is reserved");
2440 State = VTypeState::SeenLmul;
2444 if (State < VTypeState::SeenTailPolicy &&
Identifier.starts_with(
"t")) {
2445 if (Identifier ==
"ta")
2446 TailAgnostic =
true;
2447 else if (Identifier ==
"tu")
2448 TailAgnostic =
false;
2452 State = VTypeState::SeenTailPolicy;
2456 if (State < VTypeState::SeenMaskPolicy &&
Identifier.starts_with(
"m")) {
2457 if (Identifier ==
"ma")
2458 MaskAgnostic =
true;
2459 else if (Identifier ==
"mu")
2460 MaskAgnostic =
false;
2464 State = VTypeState::SeenMaskPolicy;
2471ParseStatus RISCVAsmParser::parseVTypeI(
OperandVector &Operands) {
2477 bool Fractional =
false;
2478 bool TailAgnostic =
false;
2479 bool MaskAgnostic =
false;
2482 VTypeState State = VTypeState::SeenNothingYet;
2484 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2485 MaskAgnostic, AltFmt)) {
2487 if (State == VTypeState::SeenNothingYet)
2496 State == VTypeState::SeenNothingYet)
2497 return generateVTypeError(S);
2501 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2502 unsigned MaxSEW = ELEN / Lmul;
2504 if (MaxSEW >= 8 && Sew > MaxSEW)
2505 Warning(S,
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2506 " and LMUL == mf" + Twine(Lmul) +
2507 " may not be compatible with all RVV implementations");
2512 Operands.
push_back(RISCVOperand::createVType(VTypeI, S));
2516bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2517 return Error(ErrorLoc,
2519 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2522ParseStatus RISCVAsmParser::parseXSfmmVType(
OperandVector &Operands) {
2539 if (Identifier !=
"16alt")
2568 Operands.
push_back(RISCVOperand::createVType(
2574 return generateXSfmmVTypeError(S);
2577bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
2578 return Error(ErrorLoc,
"operand must be e[8|16|16alt|32|64],w[1|2|4]");
2581ParseStatus RISCVAsmParser::parseMaskReg(
OperandVector &Operands) {
2585 StringRef
Name = getLexer().getTok().getIdentifier();
2586 if (!
Name.consume_back(
".t")) {
2590 return Error(getLoc(),
"expected '.t' suffix");
2597 if (
Reg != RISCV::V0)
2600 SMLoc
E = getTok().getEndLoc();
2606ParseStatus RISCVAsmParser::parseVScaleReg(
OperandVector &Operands) {
2610 StringRef
Name = getLexer().getTok().getIdentifier();
2611 if (!
Name.consume_back(
".scale"))
2612 return Error(getLoc(),
"expected '.scale' suffix");
2617 if (
Reg != RISCV::V0)
2620 SMLoc
E = getTok().getEndLoc();
2626ParseStatus RISCVAsmParser::parseTileLambda(
OperandVector &Operands) {
2631 StringRef
Name = getLexer().getTok().getIdentifier();
2632 if (!
Name.consume_front(
"L") && !
Name.consume_front(
"l"))
2637 return Error(S,
"operand must be L1, L2, L4, L8, L16, L32, or L64");
2639 unsigned EncodedLambda =
Log2_32(Lambda) + 1;
2641 SMLoc
E = getTok().getEndLoc();
2643 Operands.
push_back(RISCVOperand::createExpr(
2648ParseStatus RISCVAsmParser::parseGPRAsFPR64(
OperandVector &Operands) {
2649 if (!isRV64() || getSTI().
hasFeature(RISCV::FeatureStdExtF))
2652 return parseGPRAsFPR(Operands);
2655ParseStatus RISCVAsmParser::parseGPRAsFPR(
OperandVector &Operands) {
2659 StringRef
Name = getLexer().getTok().getIdentifier();
2665 SMLoc
E = getTok().getEndLoc();
2667 Operands.
push_back(RISCVOperand::createReg(
2672ParseStatus RISCVAsmParser::parseGPRPairAsFPR64(
OperandVector &Operands) {
2673 if (isRV64() || getSTI().
hasFeature(RISCV::FeatureStdExtF))
2679 StringRef
Name = getLexer().getTok().getIdentifier();
2685 if (!getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg))
2688 if ((
Reg - RISCV::X0) & 1) {
2691 if (getSTI().
hasFeature(RISCV::FeatureStdExtZfinx))
2692 return TokError(
"double precision floating point operands must use even "
2693 "numbered X register");
2698 SMLoc
E = getTok().getEndLoc();
2701 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2703 Reg, RISCV::sub_gpr_even,
2704 &getRISCVMCRegisterClass(RISCV::GPRPairRegClassID));
2705 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2709template <
bool IsRV64>
2710ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands) {
2711 return parseGPRPair(Operands, IsRV64);
2714ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands,
2721 if (!IsRV64Inst && isRV64())
2727 StringRef
Name = getLexer().getTok().getIdentifier();
2733 if (!getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg))
2736 if ((
Reg - RISCV::X0) & 1)
2737 return TokError(
"register must be even");
2740 SMLoc
E = getTok().getEndLoc();
2743 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2745 Reg, RISCV::sub_gpr_even,
2746 &getRISCVMCRegisterClass(RISCV::GPRPairRegClassID));
2747 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E));
2751ParseStatus RISCVAsmParser::parseFRMArg(
OperandVector &Operands) {
2754 "operand must be a valid floating point rounding mode mnemonic");
2756 StringRef Str = getLexer().getTok().getIdentifier();
2761 "operand must be a valid floating point rounding mode mnemonic");
2763 Operands.
push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2768ParseStatus RISCVAsmParser::parseFenceArg(
OperandVector &Operands) {
2769 const AsmToken &Tok = getLexer().getTok();
2775 Operands.
push_back(RISCVOperand::createFenceArg(0, getLoc()));
2789 for (
char c : Str) {
2818 Operands.
push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2824 return TokError(
"operand must be formed of letters selected in-order from "
2828ParseStatus RISCVAsmParser::parseMemOpBaseReg(
OperandVector &Operands) {
2831 Operands.
push_back(RISCVOperand::createToken(
"(", getLoc()));
2833 if (!parseRegister(Operands).isSuccess())
2834 return Error(getLoc(),
"expected register");
2838 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
2843ParseStatus RISCVAsmParser::parseZeroOffsetMemOp(
OperandVector &Operands) {
2862 std::unique_ptr<RISCVOperand> OptionalImmOp;
2869 SMLoc ImmStart = getLoc();
2870 if (getParser().parseIntToken(ImmVal,
2871 "expected '(' or optional integer offset"))
2876 SMLoc ImmEnd = getLoc();
2879 ImmStart, ImmEnd, isRV64());
2883 OptionalImmOp ?
"expected '(' after optional integer offset"
2884 :
"expected '(' or optional integer offset"))
2887 if (!parseRegister(Operands).isSuccess())
2888 return Error(getLoc(),
"expected register");
2894 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2896 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2897 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2902ParseStatus RISCVAsmParser::parseRegReg(
OperandVector &Operands) {
2908 StringRef OffsetRegName = getLexer().getTok().getIdentifier();
2911 !getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(OffsetReg))
2912 return Error(getLoc(),
"expected GPR register");
2919 return Error(getLoc(),
"expected GPR register");
2921 StringRef BaseRegName = getLexer().getTok().getIdentifier();
2924 !getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(BaseReg))
2925 return Error(getLoc(),
"expected GPR register");
2931 Operands.
push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));
2943ParseStatus RISCVAsmParser::parseRegList(
OperandVector &Operands,
2944 bool MustIncludeS0) {
2956 return Error(getLoc(),
"invalid register");
2958 StringRef
RegName = getTok().getIdentifier();
2961 return Error(getLoc(),
"invalid register");
2964 UsesXRegs =
RegName[0] ==
'x';
2965 if (
Reg != RISCV::X1)
2966 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2967 }
else if (RegEnd == RISCV::X1) {
2968 if (
Reg != RISCV::X8 || (UsesXRegs != (
RegName[0] ==
'x')))
2969 return Error(getLoc(), Twine(
"register must be '") +
2970 (UsesXRegs ?
"x8" :
"s0") +
"'");
2971 }
else if (RegEnd == RISCV::X9 && UsesXRegs) {
2972 if (
Reg != RISCV::X18 || (
RegName[0] !=
'x'))
2973 return Error(getLoc(),
"register must be 'x18'");
2975 return Error(getLoc(),
"too many register ranges");
2982 SMLoc MinusLoc = getLoc();
2984 if (RegEnd == RISCV::X1)
2985 return Error(MinusLoc, Twine(
"register '") + (UsesXRegs ?
"x1" :
"ra") +
2986 "' cannot start a multiple register range");
2989 return Error(getLoc(),
"invalid register");
2991 StringRef
RegName = getTok().getIdentifier();
2994 return Error(getLoc(),
"invalid register");
2996 if (RegEnd == RISCV::X8) {
2997 if ((
Reg != RISCV::X9 &&
2999 (UsesXRegs != (
RegName[0] ==
'x'))) {
3001 return Error(getLoc(),
"register must be 'x9'");
3002 return Error(getLoc(),
"register must be in the range 's1' to 's11'");
3004 }
else if (RegEnd == RISCV::X18) {
3006 return Error(getLoc(),
3007 "register must be in the range 'x19' to 'x27'");
3020 if (RegEnd == RISCV::X26)
3021 return Error(S,
"invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "
3022 "x18-x26}' is not supported");
3028 return Error(S,
"register list must include 's0' or 'x8'");
3030 Operands.
push_back(RISCVOperand::createRegList(Encode, S));
3035ParseStatus RISCVAsmParser::parseZcmpStackAdj(
OperandVector &Operands,
3036 bool ExpectNegative) {
3045 auto *RegListOp =
static_cast<RISCVOperand *
>(Operands.
back().
get());
3046 if (!RegListOp->isRegList())
3049 unsigned RlistEncode = RegListOp->RegList.Encoding;
3053 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||
3054 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {
3055 int64_t
Lower = StackAdjBase;
3056 int64_t
Upper = StackAdjBase + 48;
3057 if (ExpectNegative) {
3062 return generateImmOutOfRangeError(S,
Lower,
Upper,
3063 "stack adjustment for register list must "
3064 "be a multiple of 16 bytes in the range");
3068 Operands.
push_back(RISCVOperand::createStackAdj(StackAdj, S));
3076bool RISCVAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
3080 MatchOperandParserImpl(Operands, Mnemonic,
true);
3087 if (parseRegister(Operands,
true).isSuccess())
3091 if (parseExpression(Operands).isSuccess()) {
3094 return !parseMemOpBaseReg(Operands).isSuccess();
3099 Error(getLoc(),
"unknown operand");
3103bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &Info,
3104 StringRef Name, SMLoc NameLoc,
3110 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
3114 Operands.
push_back(RISCVOperand::createToken(Name, NameLoc));
3123 if (parseOperand(Operands, Name))
3129 if (parseOperand(Operands, Name))
3133 if (getParser().parseEOL(
"unexpected token")) {
3134 getParser().eatToEndOfStatement();
3140bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
3144 Kind = RE->getSpecifier();
3145 Expr = RE->getSubExpr();
3154bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
3163ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
3164 StringRef IDVal = DirectiveID.
getString();
3166 if (IDVal ==
".option")
3167 return parseDirectiveOption();
3168 if (IDVal ==
".attribute")
3169 return parseDirectiveAttribute();
3170 if (IDVal ==
".insn")
3171 return parseDirectiveInsn(DirectiveID.
getLoc());
3172 if (IDVal ==
".variant_cc")
3173 return parseDirectiveVariantCC();
3178bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
3179 bool FromOptionDirective) {
3180 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
3183 clearFeatureBits(Feature.Value, Feature.key());
3190 raw_string_ostream OutputErrMsg(Buffer);
3191 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3192 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
3193 << ErrMsg.getMessage();
3196 return Error(Loc, OutputErrMsg.str());
3198 auto &ISAInfo = *ParseResult;
3201 if (ISAInfo->hasExtension(Feature.key()))
3202 setFeatureBits(Feature.Value, Feature.key());
3204 if (FromOptionDirective) {
3205 if (ISAInfo->getXLen() == 32 && isRV64())
3206 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3207 else if (ISAInfo->getXLen() == 64 && !isRV64())
3208 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3211 if (ISAInfo->getXLen() == 32)
3212 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
3213 else if (ISAInfo->getXLen() == 64)
3214 setFeatureBits(RISCV::Feature64Bit,
"64bit");
3216 return Error(Loc,
"bad arch string " + Arch);
3218 Result = ISAInfo->toString();
3222bool RISCVAsmParser::parseDirectiveOption() {
3223 MCAsmParser &Parser = getParser();
3225 AsmToken Tok = Parser.
getTok();
3233 if (Option ==
"push") {
3237 getTargetStreamer().emitDirectiveOptionPush();
3242 if (Option ==
"pop") {
3247 getTargetStreamer().emitDirectiveOptionPop();
3248 if (popFeatureBits())
3249 return Error(StartLoc,
".option pop with no .option push");
3254 if (Option ==
"arch") {
3262 Type = RISCVOptionArchArgType::Plus;
3264 Type = RISCVOptionArchArgType::Minus;
3265 else if (!
Args.empty())
3267 "unexpected token, expected + or -");
3269 Type = RISCVOptionArchArgType::Full;
3273 "unexpected token, expected identifier");
3279 if (
Type == RISCVOptionArchArgType::Full) {
3281 if (resetToArch(Arch, Loc, Result,
true))
3290 Loc,
"extension version number parsing not currently implemented");
3293 if (!enableExperimentalExtension() &&
3295 return Error(Loc,
"unexpected experimental extensions");
3296 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
3298 if (Ext == std::end(
AllFeatures) || StringRef(Ext->key()) != Feature)
3299 return Error(Loc,
"unknown extension feature");
3303 if (
Type == RISCVOptionArchArgType::Plus) {
3306 setFeatureBits(Ext->Value, Ext->key());
3309 copySTI().setFeatureBits(OldFeatureBits);
3310 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3313 raw_string_ostream OutputErrMsg(Buffer);
3314 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3315 OutputErrMsg << ErrMsg.getMessage();
3318 return Error(Loc, OutputErrMsg.str());
3321 assert(
Type == RISCVOptionArchArgType::Minus);
3327 Feature.Implies.test(Ext->Value))
3328 return Error(Loc, Twine(
"can't disable ") + Ext->key() +
3329 " extension; " + Feature.key() +
3330 " extension requires " + Ext->key() +
3334 clearFeatureBits(Ext->Value, Ext->key());
3341 getTargetStreamer().emitDirectiveOptionArch(Args);
3344 getTargetStreamer().setArchString((*ParseResult)->toString());
3348 if (Option ==
"exact") {
3352 getTargetStreamer().emitDirectiveOptionExact();
3353 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3354 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3358 if (Option ==
"noexact") {
3362 getTargetStreamer().emitDirectiveOptionNoExact();
3363 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3364 setFeatureBits(RISCV::FeatureRelax,
"relax");
3368 if (Option ==
"rvc") {
3372 getTargetStreamer().emitDirectiveOptionRVC();
3373 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3375 getTargetStreamer().setArchString((*ParseResult)->toString());
3379 if (Option ==
"norvc") {
3383 getTargetStreamer().emitDirectiveOptionNoRVC();
3384 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3385 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3387 getTargetStreamer().setArchString((*ParseResult)->toString());
3391 if (Option ==
"pic") {
3395 getTargetStreamer().emitDirectiveOptionPIC();
3396 ParserOptions.IsPicEnabled =
true;
3400 if (Option ==
"nopic") {
3404 getTargetStreamer().emitDirectiveOptionNoPIC();
3405 ParserOptions.IsPicEnabled =
false;
3409 if (Option ==
"relax") {
3413 getTargetStreamer().emitDirectiveOptionRelax();
3414 setFeatureBits(RISCV::FeatureRelax,
"relax");
3418 if (Option ==
"norelax") {
3422 getTargetStreamer().emitDirectiveOptionNoRelax();
3423 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3429 "unknown option, expected 'push', 'pop', "
3430 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3431 "'exact', or 'noexact'");
3439bool RISCVAsmParser::parseDirectiveAttribute() {
3440 MCAsmParser &Parser = getParser();
3446 std::optional<unsigned> Ret =
3449 return Error(TagLoc,
"attribute name not recognised: " + Name);
3453 const MCExpr *AttrExpr;
3460 if (check(!CE, TagLoc,
"expected numeric constant"))
3463 Tag =
CE->getValue();
3469 StringRef StringValue;
3470 int64_t IntegerValue = 0;
3471 bool IsIntegerValue =
true;
3476 IsIntegerValue =
false;
3479 if (IsIntegerValue) {
3480 const MCExpr *ValueExpr;
3486 return Error(ValueExprLoc,
"expected numeric constant");
3487 IntegerValue =
CE->getValue();
3500 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3502 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3505 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3509 getTargetStreamer().emitTextAttribute(
Tag, Result);
3513 getTargetStreamer().setArchString(Result);
3521 .
Cases({
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s"},
true)
3522 .Cases({
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj"},
3524 .
Cases({
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es"},
3533bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3534 MCAsmParser &Parser = getParser();
3541 std::optional<int64_t>
Length;
3551 return Error(ErrorLoc,
3552 "instruction lengths must be a non-zero multiple of two");
3556 return Error(ErrorLoc,
3557 "instruction lengths over 64 bits are not supported");
3563 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3568 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3569 return Error(ErrorLoc,
3570 "instruction length does not match the encoding");
3573 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3576 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3579 if (!getSTI().
hasFeature(RISCV::FeatureStdExtZca) &&
3580 (EncodingDerivedLength == 2))
3581 return Error(ErrorLoc,
"compressed instructions are not allowed");
3583 if (getParser().parseEOL(
"invalid operand for instruction")) {
3584 getParser().eatToEndOfStatement();
3592 Opcode = RISCV::Insn16;
3595 Opcode = RISCV::Insn32;
3598 Opcode = RISCV::Insn48;
3601 Opcode = RISCV::Insn64;
3607 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3609 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3614 return Error(ErrorLoc,
"invalid instruction format");
3616 std::string FormatName = (
".insn_" +
Format).str();
3618 ParseInstructionInfo
Info;
3621 if (parseInstruction(Info, FormatName, L, Operands))
3626 return matchAndEmitInstruction(L, Opcode, Operands, Parser.
getStreamer(),
3633bool RISCVAsmParser::parseDirectiveVariantCC() {
3635 if (getParser().parseIdentifier(Name))
3636 return TokError(
"expected symbol name");
3639 getTargetStreamer().emitDirectiveVariantCC(
3644void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3647 const MCSubtargetInfo &STI = getSTI();
3648 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3651 ++RISCVNumInstrsCompressed;
3655void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3660 for (MCInst &Inst : Seq) {
3661 emitToStreamer(Out, Inst);
3665void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3666 const MCExpr *Symbol,
3668 unsigned SecondOpcode, SMLoc IDLoc,
3680 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3685 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3688 .addExpr(RefToLinkTmpLabel));
3691void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3704 Out, MCInstBuilder(RISCV::QC_E_LI).addReg(DestReg).addExpr(Symbol));
3710void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3720 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3721 emitAuipcInstPair(DestReg, DestReg, Symbol,
RISCV::S_GOT_HI, SecondOpcode,
3725void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3734 if (ParserOptions.IsPicEnabled)
3735 emitLoadGlobalAddress(Inst, IDLoc, Out);
3737 emitLoadLocalAddress(Inst, IDLoc, Out);
3740void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3750 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3751 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3752 SecondOpcode, IDLoc, Out);
3755void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3765 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3766 RISCV::ADDI, IDLoc, Out);
3769void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3770 SMLoc IDLoc, MCStreamer &Out,
3779 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3781 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3785 if (getRISCVMCRegisterClass(RISCV::GPRPairRegClassID).
contains(TmpReg)) {
3786 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3787 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3795void RISCVAsmParser::emitQCELILoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3796 SMLoc IDLoc, MCStreamer &Out,
3806 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3810 MCInstBuilder(RISCV::QC_E_LI).addReg(AddrReg).addExpr(Symbol));
3813 const MCExpr *AccessExpr =
3819 struct CompressedForm {
3823 std::optional<CompressedForm> Compressed;
3827 case RISCV::PseudoQCAccessLBU:
3828 Compressed = {RISCV::PseudoQCAccessC_LBU, RISCV::FeatureStdExtZcb};
3830 case RISCV::PseudoQCAccessLH:
3831 Compressed = {RISCV::PseudoQCAccessC_LH, RISCV::FeatureStdExtZcb};
3833 case RISCV::PseudoQCAccessLHU:
3834 Compressed = {RISCV::PseudoQCAccessC_LHU, RISCV::FeatureStdExtZcb};
3836 case RISCV::PseudoQCAccessLW:
3837 Compressed = {RISCV::PseudoQCAccessC_LW, RISCV::FeatureStdExtZca};
3839 case RISCV::PseudoQCAccessSB:
3840 Compressed = {RISCV::PseudoQCAccessC_SB, RISCV::FeatureStdExtZcb};
3842 case RISCV::PseudoQCAccessSH:
3843 Compressed = {RISCV::PseudoQCAccessC_SH, RISCV::FeatureStdExtZcb};
3845 case RISCV::PseudoQCAccessSW:
3846 Compressed = {RISCV::PseudoQCAccessC_SW, RISCV::FeatureStdExtZca};
3853 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(AddrReg);
3854 if (HasTmpReg && CanUseGPRC) {
3857 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(DataReg);
3860 bool UseCompressed =
3861 Compressed && getSTI().hasFeature(Compressed->Feature) && CanUseGPRC;
3863 unsigned ActualOpcode = UseCompressed ? Compressed->Opcode : Opcode;
3866 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3870 .addExpr(AccessExpr));
3872 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3876 .addExpr(AccessExpr));
3880void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3881 int64_t Width, SMLoc IDLoc,
3890 const MCOperand &DestReg = Inst.
getOperand(0);
3891 const MCOperand &SourceReg = Inst.
getOperand(1);
3893 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3894 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3896 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3898 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3903 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3909void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
3916 emitToStreamer(Out, MCInstBuilder(Opcode)
3920 .addReg(MCRegister())
3922 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
3933 "The destination register should not be V0.");
3935 emitToStreamer(Out, MCInstBuilder(Opcode)
3941 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
3953 "The temporary vector register should not be V0.");
3954 emitToStreamer(Out, MCInstBuilder(Opcode)
3958 .addReg(MCRegister())
3960 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3972 "The temporary vector register should not be V0.");
3973 emitToStreamer(Out, MCInstBuilder(Opcode)
3977 .addReg(MCRegister())
3979 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3984 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3989 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
3997bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
3999 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
4002 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
4003 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
4004 "%tprel_add specifier");
4010bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
4012 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
4015 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
4016 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
4017 "%tlsdesc_call specifier");
4023std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
4024 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
4027std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
4028 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
4032std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
4033 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
4041 case RISCV::VLOXSEG2EI8_V:
4042 case RISCV::VLOXSEG2EI16_V:
4043 case RISCV::VLOXSEG2EI32_V:
4044 case RISCV::VLOXSEG2EI64_V:
4045 case RISCV::VLUXSEG2EI8_V:
4046 case RISCV::VLUXSEG2EI16_V:
4047 case RISCV::VLUXSEG2EI32_V:
4048 case RISCV::VLUXSEG2EI64_V:
4050 case RISCV::VLOXSEG3EI8_V:
4051 case RISCV::VLOXSEG3EI16_V:
4052 case RISCV::VLOXSEG3EI32_V:
4053 case RISCV::VLOXSEG3EI64_V:
4054 case RISCV::VLUXSEG3EI8_V:
4055 case RISCV::VLUXSEG3EI16_V:
4056 case RISCV::VLUXSEG3EI32_V:
4057 case RISCV::VLUXSEG3EI64_V:
4059 case RISCV::VLOXSEG4EI8_V:
4060 case RISCV::VLOXSEG4EI16_V:
4061 case RISCV::VLOXSEG4EI32_V:
4062 case RISCV::VLOXSEG4EI64_V:
4063 case RISCV::VLUXSEG4EI8_V:
4064 case RISCV::VLUXSEG4EI16_V:
4065 case RISCV::VLUXSEG4EI32_V:
4066 case RISCV::VLUXSEG4EI64_V:
4068 case RISCV::VLOXSEG5EI8_V:
4069 case RISCV::VLOXSEG5EI16_V:
4070 case RISCV::VLOXSEG5EI32_V:
4071 case RISCV::VLOXSEG5EI64_V:
4072 case RISCV::VLUXSEG5EI8_V:
4073 case RISCV::VLUXSEG5EI16_V:
4074 case RISCV::VLUXSEG5EI32_V:
4075 case RISCV::VLUXSEG5EI64_V:
4077 case RISCV::VLOXSEG6EI8_V:
4078 case RISCV::VLOXSEG6EI16_V:
4079 case RISCV::VLOXSEG6EI32_V:
4080 case RISCV::VLOXSEG6EI64_V:
4081 case RISCV::VLUXSEG6EI8_V:
4082 case RISCV::VLUXSEG6EI16_V:
4083 case RISCV::VLUXSEG6EI32_V:
4084 case RISCV::VLUXSEG6EI64_V:
4086 case RISCV::VLOXSEG7EI8_V:
4087 case RISCV::VLOXSEG7EI16_V:
4088 case RISCV::VLOXSEG7EI32_V:
4089 case RISCV::VLOXSEG7EI64_V:
4090 case RISCV::VLUXSEG7EI8_V:
4091 case RISCV::VLUXSEG7EI16_V:
4092 case RISCV::VLUXSEG7EI32_V:
4093 case RISCV::VLUXSEG7EI64_V:
4095 case RISCV::VLOXSEG8EI8_V:
4096 case RISCV::VLOXSEG8EI16_V:
4097 case RISCV::VLOXSEG8EI32_V:
4098 case RISCV::VLOXSEG8EI64_V:
4099 case RISCV::VLUXSEG8EI8_V:
4100 case RISCV::VLUXSEG8EI16_V:
4101 case RISCV::VLUXSEG8EI32_V:
4102 case RISCV::VLUXSEG8EI64_V:
4108 if (getRISCVMCRegisterClass(RISCV::VRM2RegClassID).
contains(
Reg))
4110 if (getRISCVMCRegisterClass(RISCV::VRM4RegClassID).
contains(
Reg))
4112 if (getRISCVMCRegisterClass(RISCV::VRM8RegClassID).
contains(
Reg))
4119 case RISCV::VFWMMACC_VV_SCALE:
4120 case RISCV::VFQMMACC_VV_SCALE:
4121 case RISCV::VF8WMMACC_VV_SCALE:
4122 case RISCV::VFWIMMACC_VV:
4123 case RISCV::VFQIMMACC_VV:
4124 case RISCV::VF8WIMMACC_VV:
4131bool RISCVAsmParser::validateInstruction(MCInst &Inst,
4135 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
4136 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
4139 if (DestReg == TempReg) {
4140 SMLoc Loc = Operands.
back()->getStartLoc();
4141 return Error(Loc,
"the temporary vector register cannot be the same as "
4142 "the destination register");
4146 if (Opcode == RISCV::PseudoVMSGEU_VX_M || Opcode == RISCV::PseudoVMSGE_VX_M) {
4149 if (MaskReg == RISCV::V0 && DestReg == RISCV::V0) {
4150 SMLoc Loc = Operands.
back()->getStartLoc();
4151 return Error(Loc,
"the destination vector register cannot overlap the "
4152 "mask register unless a temporary register is "
4157 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
4158 Opcode == RISCV::TH_LWD) {
4163 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
4164 SMLoc Loc = Operands[1]->getStartLoc();
4165 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
4169 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
4173 SMLoc Loc = Operands[1]->getStartLoc();
4174 return Error(Loc,
"rs1 and rs2 must be different");
4179 auto CheckOperandDoesNotOverlapV0 = [&](
int OperandIdx,
4180 unsigned ParsedIdx) {
4182 return Error(Operands[ParsedIdx]->getStartLoc(),
4183 "vd, vs1, and vs2 cannot overlap v0.scale");
4188 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4190 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4192 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4193 assert(DestIdx >= 0 && VS1Idx >= 0 && VS2Idx >= 0 &&
4194 "Unexpected Zvvfmm scaled operand list");
4196 if (CheckOperandDoesNotOverlapV0(DestIdx, 1) ||
4197 CheckOperandDoesNotOverlapV0(VS1Idx, 2) ||
4198 CheckOperandDoesNotOverlapV0(VS2Idx, 3))
4202 const MCInstrDesc &MCID = MII.
get(Opcode);
4206 int DestIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4210 const MCParsedAsmOperand *ParsedOp = Operands[1].get();
4211 if (!ParsedOp->
isReg()) {
4214 ParsedOp = Operands[2].get();
4216 assert(ParsedOp->
getReg() == DestReg &&
"Can't find parsed dest operand");
4220 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4224 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4225 assert(VS2Idx >= 0 &&
"No vs2 operand?");
4226 unsigned CheckEncoding =
4229 for (
unsigned i = 0; i < std::max(NF, Lmul); i++) {
4230 if ((DestEncoding + i) == CheckEncoding)
4231 return Error(Loc,
"the destination vector register group cannot overlap"
4232 " the source vector register group");
4237 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4241 unsigned CheckEncoding =
4243 for (
unsigned i = 0; i < Lmul; i++) {
4244 if ((DestEncoding + i) == CheckEncoding)
4246 "the destination vector register group cannot overlap"
4247 " the source vector register group");
4253 int VMIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vm);
4254 assert(VMIdx >= 0 &&
"No vm operand?");
4256 if (DestReg == RISCV::V0) {
4259 return Error(Loc,
"the destination vector register group cannot be V0");
4267 "Unexpected mask operand register");
4269 return Error(Loc,
"the destination vector register group cannot overlap"
4270 " the mask register");
4277bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
4285 case RISCV::PseudoC_ADDI_NOP: {
4287 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
4297 if (getSTI().
hasFeature(RISCV::Feature64Bit))
4299 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV32)
4304 case RISCV::PACKW: {
4308 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV64)
4313 case RISCV::PseudoLLAImm:
4314 case RISCV::PseudoLAImm:
4315 case RISCV::PseudoLI: {
4321 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
4333 emitLoadImm(
Reg, Imm, Out);
4336 case RISCV::PseudoLLA:
4337 emitLoadLocalAddress(Inst, IDLoc, Out);
4339 case RISCV::PseudoLGA:
4340 emitLoadGlobalAddress(Inst, IDLoc, Out);
4342 case RISCV::PseudoLA:
4343 emitLoadAddress(Inst, IDLoc, Out);
4345 case RISCV::PseudoLA_TLS_IE:
4346 emitLoadTLSIEAddress(Inst, IDLoc, Out);
4348 case RISCV::PseudoLA_TLS_GD:
4349 emitLoadTLSGDAddress(Inst, IDLoc, Out);
4351 case RISCV::PseudoLB:
4352 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
4354 case RISCV::PseudoLBU:
4355 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
4357 case RISCV::PseudoLH:
4358 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
4360 case RISCV::PseudoLHU:
4361 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
4363 case RISCV::PseudoLW:
4364 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
4366 case RISCV::PseudoLWU:
4367 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
4369 case RISCV::PseudoLD:
4370 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
4372 case RISCV::PseudoLD_RV32:
4373 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
4375 case RISCV::PseudoFLH:
4376 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
4378 case RISCV::PseudoFLW:
4379 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
4381 case RISCV::PseudoFLD:
4382 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
4384 case RISCV::PseudoFLQ:
4385 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
4387 case RISCV::PseudoSB:
4388 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
4390 case RISCV::PseudoSH:
4391 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
4393 case RISCV::PseudoSW:
4394 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
4396 case RISCV::PseudoSD:
4397 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
4399 case RISCV::PseudoSD_RV32:
4400 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
4402 case RISCV::PseudoQC_E_LB:
4403 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLB, IDLoc, Out,
4406 case RISCV::PseudoQC_E_LBU:
4407 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLBU, IDLoc, Out,
4410 case RISCV::PseudoQC_E_LH:
4411 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLH, IDLoc, Out,
4414 case RISCV::PseudoQC_E_LHU:
4415 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLHU, IDLoc, Out,
4418 case RISCV::PseudoQC_E_LW:
4419 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLW, IDLoc, Out,
4422 case RISCV::PseudoQC_E_SB:
4423 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSB, IDLoc, Out,
4426 case RISCV::PseudoQC_E_SH:
4427 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSH, IDLoc, Out,
4430 case RISCV::PseudoQC_E_SW:
4431 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSW, IDLoc, Out,
4434 case RISCV::PseudoFSH:
4435 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
4437 case RISCV::PseudoFSW:
4438 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
4440 case RISCV::PseudoFSD:
4441 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4443 case RISCV::PseudoFSQ:
4444 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4446 case RISCV::PseudoAddTPRel:
4447 if (checkPseudoAddTPRel(Inst, Operands))
4450 case RISCV::PseudoTLSDESCCall:
4451 if (checkPseudoTLSDESCCall(Inst, Operands))
4454 case RISCV::PseudoSEXT_B:
4455 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4457 case RISCV::PseudoSEXT_H:
4458 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4460 case RISCV::PseudoZEXT_H:
4461 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4463 case RISCV::PseudoZEXT_W:
4464 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4466 case RISCV::PseudoVMSGEU_VX_M:
4467 case RISCV::PseudoVMSGEU_VX_M_T:
4468 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4470 case RISCV::PseudoVMSGE_VX_M:
4471 case RISCV::PseudoVMSGE_VX_M_T:
4472 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4474 case RISCV::PseudoVMSGE_VI:
4475 case RISCV::PseudoVMSLT_VI: {
4479 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4481 emitToStreamer(Out, MCInstBuilder(
Opc)
4489 case RISCV::PseudoVMSGEU_VI:
4490 case RISCV::PseudoVMSLTU_VI: {
4497 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4500 emitToStreamer(Out, MCInstBuilder(
Opc)
4508 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4511 emitToStreamer(Out, MCInstBuilder(
Opc)
4521 case RISCV::PseudoCV_ELW:
4522 emitLoadStoreSymbol(Inst, RISCV::CV_ELW, IDLoc, Out,
false);
4526 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)
@ 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,...