49#define DEBUG_TYPE "riscv-asm-parser"
52 "Number of RISC-V Compressed instructions emitted");
64struct ParserOptionsSet {
71 enum class VTypeState {
82 ParserOptionsSet ParserOptions;
84 SMLoc getLoc()
const {
return getParser().
getTok().
getLoc(); }
85 bool isRV64()
const {
return getSTI().hasFeature(RISCV::Feature64Bit); }
86 bool isRVE()
const {
return getSTI().hasFeature(RISCV::FeatureStdExtE); }
87 bool enableExperimentalExtension()
const {
88 return getSTI().hasFeature(RISCV::Experimental);
91 RISCVTargetStreamer &getTargetStreamer() {
92 assert(getParser().getStreamer().getTargetStreamer() &&
93 "do not have a target streamer");
94 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
95 return static_cast<RISCVTargetStreamer &
>(TS);
98 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
99 unsigned Kind)
override;
101 bool generateImmOutOfRangeError(
OperandVector &Operands, uint64_t ErrorInfo,
104 bool generateImmOutOfRangeError(SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
107 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
110 bool MatchingInlineAsm)
override;
113 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
114 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
115 SMLoc &EndLoc)
override;
117 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
120 ParseStatus parseDirective(AsmToken DirectiveID)
override;
122 bool parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
unsigned &Sew,
123 unsigned &Lmul,
bool &Fractional,
bool &TailAgnostic,
124 bool &MaskAgnostic,
bool &AltFmt);
125 bool generateVTypeError(SMLoc ErrorLoc);
127 bool generateXSfmmVTypeError(SMLoc ErrorLoc);
130 void emitToStreamer(MCStreamer &S,
const MCInst &Inst);
134 void emitLoadImm(MCRegister DestReg, int64_t
Value, MCStreamer &Out);
138 void emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
140 unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out);
143 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
146 void emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
149 void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
153 void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
157 void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
160 void emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
161 MCStreamer &Out,
bool HasTmpReg);
164 void emitPseudoExtend(MCInst &Inst,
bool SignExtend, int64_t Width,
165 SMLoc IDLoc, MCStreamer &Out);
168 void emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc, MCStreamer &Out);
174 bool checkPseudoAddTPRel(MCInst &Inst,
OperandVector &Operands);
180 bool checkPseudoTLSDESCCall(MCInst &Inst,
OperandVector &Operands);
183 bool validateInstruction(MCInst &Inst,
OperandVector &Operands);
189 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
OperandVector &Operands,
193#define GET_ASSEMBLER_HEADER
194#include "RISCVGenAsmMatcher.inc"
222 return parseRegList(Operands,
true);
228 bool ExpectNegative =
false);
230 return parseZcmpStackAdj(Operands,
true);
233 bool parseOperand(
OperandVector &Operands, StringRef Mnemonic);
234 bool parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
235 bool parseDataExpr(
const MCExpr *&Res)
override;
237 bool parseDirectiveOption();
238 bool parseDirectiveAttribute();
239 bool parseDirectiveInsn(SMLoc L);
240 bool parseDirectiveVariantCC();
245 bool resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
246 bool FromOptionDirective);
248 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
249 if (!(getSTI().hasFeature(Feature))) {
250 MCSubtargetInfo &STI = copySTI();
256 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
260 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
261 if (getSTI().hasFeature(Feature)) {
262 MCSubtargetInfo &STI = copySTI();
263 setAvailableFeatures(
268 void pushFeatureBits() {
269 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
270 "These two stacks must be kept synchronized");
271 FeatureBitStack.push_back(getSTI().getFeatureBits());
272 ParserOptionsStack.push_back(ParserOptions);
275 bool popFeatureBits() {
276 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
277 "These two stacks must be kept synchronized");
278 if (FeatureBitStack.empty())
281 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
282 copySTI().setFeatureBits(FeatureBits);
283 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
285 ParserOptions = ParserOptionsStack.pop_back_val();
290 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
291 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
292 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
295 enum RISCVMatchResultTy :
unsigned {
296 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
297#define GET_OPERAND_DIAGNOSTIC_TYPES
298#include "RISCVGenAsmMatcher.inc"
299#undef GET_OPERAND_DIAGNOSTIC_TYPES
303 static bool isSymbolDiff(
const MCExpr *Expr);
305 RISCVAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
306 const MCInstrInfo &MII)
307 : MCTargetAsmParser(STI, MII) {
314 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
316 auto ABIName = StringRef(getTargetOptions().ABIName);
317 if (ABIName.ends_with(
"f") && !getSTI().hasFeature(RISCV::FeatureStdExtF)) {
318 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
319 "doesn't support the F instruction set extension (ignoring "
321 }
else if (ABIName.ends_with(
"d") &&
322 !getSTI().hasFeature(RISCV::FeatureStdExtD)) {
323 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
324 "doesn't support the D instruction set extension (ignoring "
337 getTargetStreamer().emitTargetAttributes(STI,
false);
403 MCRegister OffsetReg;
406 SMLoc StartLoc, EndLoc;
421 RISCVOperand(KindTy K) : Kind(
K) {}
424 RISCVOperand(
const RISCVOperand &o) : MCParsedAsmOperand() {
426 StartLoc =
o.StartLoc;
429 case KindTy::Register:
432 case KindTy::Expression:
435 case KindTy::FPImmediate:
441 case KindTy::SystemRegister:
453 case KindTy::RegList:
456 case KindTy::StackAdj:
457 StackAdj =
o.StackAdj;
465 bool isToken()
const override {
return Kind == KindTy::Token; }
466 bool isReg()
const override {
return Kind == KindTy::Register; }
467 bool isExpr()
const {
return Kind == KindTy::Expression; }
468 bool isV0Reg()
const {
469 return Kind == KindTy::Register &&
Reg.Reg == RISCV::V0;
471 bool isAnyReg()
const {
472 return Kind == KindTy::Register &&
473 (RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.Reg) ||
474 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg.Reg) ||
475 RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg.Reg));
477 bool isAnyRegC()
const {
478 return Kind == KindTy::Register &&
479 (RISCVMCRegisterClasses[RISCV::GPRCRegClassID].contains(
Reg.Reg) ||
480 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg.Reg));
482 bool isImm()
const override {
return isExpr(); }
483 bool isMem()
const override {
return false; }
484 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
485 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
486 bool isRegList()
const {
return Kind == KindTy::RegList; }
487 bool isRegListS0()
const {
488 return Kind == KindTy::RegList && RegList.Encoding !=
RISCVZC::RA;
490 bool isStackAdj()
const {
return Kind == KindTy::StackAdj; }
493 return Kind == KindTy::Register &&
494 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.Reg);
497 bool isYGPR()
const {
498 return Kind == KindTy::Register &&
499 RISCVMCRegisterClasses[RISCV::YGPRRegClassID].contains(
Reg.Reg);
502 bool isGPRPair()
const {
503 return Kind == KindTy::Register &&
504 RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(
Reg.Reg);
507 bool isGPRPairC()
const {
508 return Kind == KindTy::Register &&
509 RISCVMCRegisterClasses[RISCV::GPRPairCRegClassID].contains(
Reg.Reg);
512 bool isGPRPairNoX0()
const {
513 return Kind == KindTy::Register &&
514 RISCVMCRegisterClasses[RISCV::GPRPairNoX0RegClassID].contains(
518 bool isGPRF16()
const {
519 return Kind == KindTy::Register &&
520 RISCVMCRegisterClasses[RISCV::GPRF16RegClassID].contains(
Reg.Reg);
523 bool isGPRF32()
const {
524 return Kind == KindTy::Register &&
525 RISCVMCRegisterClasses[RISCV::GPRF32RegClassID].contains(
Reg.Reg);
528 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
529 bool isGPRAsFPR16()
const {
return isGPRF16() &&
Reg.IsGPRAsFPR; }
530 bool isGPRAsFPR32()
const {
return isGPRF32() &&
Reg.IsGPRAsFPR; }
531 bool isGPRPairAsFPR64()
const {
return isGPRPair() &&
Reg.IsGPRAsFPR; }
533 static bool evaluateConstantExpr(
const MCExpr *Expr, int64_t &Imm) {
535 Imm =
CE->getValue();
544 template <
int N>
bool isBareSimmNLsb0()
const {
549 if (evaluateConstantExpr(
getExpr(), Imm))
550 return isShiftedInt<
N - 1, 1>(fixImmediateForRV32(Imm, isRV64Expr()));
553 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
559 template <
int N>
bool isBareSimmN()
const {
564 if (evaluateConstantExpr(
getExpr(), Imm))
565 return isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
568 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
574 bool isBareSymbol()
const {
577 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
581 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
585 bool isCallSymbol()
const {
588 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
592 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
596 bool isPseudoJumpSymbol()
const {
599 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
603 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
607 bool isTPRelAddSymbol()
const {
610 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
614 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
615 VK == ELF::R_RISCV_TPREL_ADD;
618 bool isTLSDESCCallSymbol()
const {
621 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
625 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
626 VK == ELF::R_RISCV_TLSDESC_CALL;
629 bool isQCAccessSymbol()
const {
632 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
636 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
640 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
644 bool isVTypeI10()
const {
645 if (Kind == KindTy::VType)
649 bool isVTypeI11()
const {
650 if (Kind == KindTy::VType)
655 bool isXSfmmVType()
const {
659 bool isTileLambda()
const {
660 return isUImmPred([](int64_t Imm) {
return Imm &&
isUInt<3>(Imm); });
665 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
668 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
669 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
673 bool isLoadFPImm()
const {
676 if (Kind != KindTy::FPImmediate)
679 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
682 return Idx >= 0 && Idx != 1;
685 bool isImmXLenLI()
const {
691 if (evaluateConstantExpr(
getExpr(), Imm))
694 return RISCVAsmParser::isSymbolDiff(
getExpr());
697 bool isImmXLenLI_Restricted()
const {
701 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
703 return IsConstantImm &&
707 template <
unsigned N>
bool isUImm()
const {
711 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
715 template <
unsigned N,
unsigned S>
bool isUImmShifted()
const {
719 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
723 template <
class Pred>
bool isUImmPred(Pred p)
const {
727 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
728 return IsConstantImm &&
p(Imm);
731 bool isUImmLog2XLen()
const {
732 if (isExpr() && isRV64Expr())
737 bool isUImmLog2XLenNonZero()
const {
738 if (isExpr() && isRV64Expr())
739 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<6>(Imm); });
740 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<5>(Imm); });
743 bool isUImmLog2XLenHalf()
const {
744 if (isExpr() && isRV64Expr())
749 bool isUImm1()
const {
return isUImm<1>(); }
750 bool isUImm2()
const {
return isUImm<2>(); }
751 bool isUImm3()
const {
return isUImm<3>(); }
752 bool isUImm4()
const {
return isUImm<4>(); }
753 bool isUImm5()
const {
return isUImm<5>(); }
754 bool isUImm6()
const {
return isUImm<6>(); }
755 bool isUImm7()
const {
return isUImm<7>(); }
756 bool isUImm8()
const {
return isUImm<8>(); }
757 bool isUImm9()
const {
return isUImm<9>(); }
758 bool isUImm10()
const {
return isUImm<10>(); }
759 bool isUImm11()
const {
return isUImm<11>(); }
760 bool isUImm16()
const {
return isUImm<16>(); }
761 bool isUImm20()
const {
return isUImm<20>(); }
762 bool isUImm32()
const {
return isUImm<32>(); }
763 bool isUImm48()
const {
return isUImm<48>(); }
764 bool isUImm64()
const {
return isUImm<64>(); }
766 bool isUImm5NonZero()
const {
767 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<5>(Imm); });
770 bool isUImm5GT3()
const {
771 return isUImmPred([](int64_t Imm) {
return isUInt<5>(Imm) &&
Imm > 3; });
774 bool isUImm4Plus1()
const {
776 [](int64_t Imm) {
return Imm > 0 &&
isUInt<4>(Imm - 1); });
779 bool isUImm5Plus1()
const {
781 [](int64_t Imm) {
return Imm > 0 &&
isUInt<5>(Imm - 1); });
784 bool isUImm6Plus1()
const {
786 [](int64_t Imm) {
return Imm > 0 &&
isUInt<6>(Imm - 1); });
789 bool isUImm5GE6Plus1()
const {
791 [](int64_t Imm) {
return Imm >= 6 &&
isUInt<5>(Imm - 1); });
794 bool isUImm5Slist()
const {
795 return isUImmPred([](int64_t Imm) {
796 return (Imm == 0) || (
Imm == 1) || (Imm == 2) || (
Imm == 4) ||
797 (Imm == 8) || (
Imm == 16) || (Imm == 15) || (
Imm == 31);
801 bool isUImm7EqXLen()
const {
803 [
this](int64_t Imm) {
return isRV64Expr() ?
Imm == 64 :
Imm == 32; });
806 bool isUImm8GE32()
const {
807 return isUImmPred([](int64_t Imm) {
return isUInt<8>(Imm) &&
Imm >= 32; });
810 bool isRnumArg()
const {
812 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(10); });
815 bool isRnumArg_0_7()
const {
817 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(7); });
820 bool isRnumArg_1_10()
const {
822 [](int64_t Imm) {
return Imm >= INT64_C(1) &&
Imm <= INT64_C(10); });
825 bool isRnumArg_2_14()
const {
827 [](int64_t Imm) {
return Imm >= INT64_C(2) &&
Imm <= INT64_C(14); });
830 template <
unsigned N>
bool isSImm()
const {
834 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
835 return IsConstantImm &&
isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
838 bool isYBNDSWImm()
const {
843 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
847 template <
class Pred>
bool isSImmPred(Pred p)
const {
851 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
852 return IsConstantImm &&
p(fixImmediateForRV32(Imm, isRV64Expr()));
855 bool isSImm5()
const {
return isSImm<5>(); }
856 bool isSImm6()
const {
return isSImm<6>(); }
857 bool isSImm10()
const {
return isSImm<10>(); }
858 bool isSImm11()
const {
return isSImm<11>(); }
859 bool isSImm12()
const {
return isSImm<12>(); }
860 bool isSImm16()
const {
return isSImm<16>(); }
861 bool isSImm26()
const {
return isSImm<26>(); }
863 bool isSImm5NonZero()
const {
864 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<5>(Imm); });
867 bool isSImm6NonZero()
const {
868 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<6>(Imm); });
871 bool isCLUIImm()
const {
872 return isUImmPred([](int64_t Imm) {
873 return (
isUInt<5>(Imm) && Imm != 0) || (
Imm >= 0xfffe0 &&
Imm <= 0xfffff);
877 bool isUImm2Lsb0()
const {
return isUImmShifted<1, 1>(); }
879 bool isUImm5Lsb0()
const {
return isUImmShifted<4, 1>(); }
881 bool isUImm6Lsb0()
const {
return isUImmShifted<5, 1>(); }
883 bool isUImm7Lsb00()
const {
return isUImmShifted<5, 2>(); }
885 bool isUImm7Lsb000()
const {
return isUImmShifted<4, 3>(); }
887 bool isUImm8Lsb00()
const {
return isUImmShifted<6, 2>(); }
889 bool isUImm8Lsb000()
const {
return isUImmShifted<5, 3>(); }
891 bool isUImm9Lsb000()
const {
return isUImmShifted<6, 3>(); }
893 bool isUImm14Lsb00()
const {
return isUImmShifted<12, 2>(); }
895 bool isUImm10Lsb00NonZero()
const {
902 static int64_t fixImmediateForRV32(int64_t Imm,
bool IsRV64Imm) {
908 bool isSImm12LO()
const {
913 if (evaluateConstantExpr(
getExpr(), Imm))
914 return isInt<12>(fixImmediateForRV32(Imm, isRV64Expr()));
917 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
920 VK == ELF::R_RISCV_TLSDESC_ADD_LO12);
923 bool isSImm12Lsb00000()
const {
927 bool isSImm10Lsb0000NonZero()
const {
932 bool isSImm16NonZero()
const {
933 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<16>(Imm); });
936 bool isUImm16NonZero()
const {
937 return isUImmPred([](int64_t Imm) {
return isUInt<16>(Imm) &&
Imm != 0; });
940 bool isSImm20LI()
const {
945 if (evaluateConstantExpr(
getExpr(), Imm))
946 return isInt<20>(fixImmediateForRV32(Imm, isRV64Expr()));
949 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
953 bool isSImm8PLI_B()
const {
return isSImm<8>() || isUImm<8>(); }
954 bool isSImm10PLUI()
const {
return isSImm<10>() || isUImm<10>(); }
956 bool isSImm10PLI_H()
const {
957 return isSImm<10>() || isUImmPred([](int64_t Imm) {
961 bool isSImm10PLI_W()
const {
962 return isSImm<10>() || isUImmPred([](int64_t Imm) {
967 bool isUImm20LUI()
const {
972 if (evaluateConstantExpr(
getExpr(), Imm))
976 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
977 (VK == ELF::R_RISCV_HI20 || VK == ELF::R_RISCV_TPREL_HI20);
980 bool isUImm20AUIPC()
const {
985 if (evaluateConstantExpr(
getExpr(), Imm))
989 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
991 VK == ELF::R_RISCV_TLS_GOT_HI20 || VK == ELF::R_RISCV_TLS_GD_HI20 ||
992 VK == ELF::R_RISCV_TLSDESC_HI20);
995 bool isImmZero()
const {
996 return isUImmPred([](int64_t Imm) {
return 0 ==
Imm; });
999 bool isImmThree()
const {
1000 return isUImmPred([](int64_t Imm) {
return 3 ==
Imm; });
1003 bool isImmFour()
const {
1004 return isUImmPred([](int64_t Imm) {
return 4 ==
Imm; });
1007 bool isImm5Zibi()
const {
1009 [](int64_t Imm) {
return (Imm != 0 &&
isUInt<5>(Imm)) ||
Imm == -1; });
1012 bool isSImm5Plus1()
const {
1017 bool isSImm18()
const {
1018 return isSImmPred([](int64_t Imm) {
return isInt<18>(Imm); });
1021 bool isSImm18Lsb0()
const {
1025 bool isSImm19Lsb00()
const {
1029 bool isSImm20Lsb000()
const {
1033 bool isSImm32Lsb0()
const {
1038 SMLoc getStartLoc()
const override {
return StartLoc; }
1040 SMLoc getEndLoc()
const override {
return EndLoc; }
1043 bool isRV64Expr()
const {
1044 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1048 MCRegister
getReg()
const override {
1049 assert(Kind == KindTy::Register &&
"Invalid type access!");
1053 StringRef getSysReg()
const {
1054 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
1055 return StringRef(SysReg.Data, SysReg.Length);
1058 const MCExpr *
getExpr()
const {
1059 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1063 uint64_t getFPConst()
const {
1064 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1069 assert(Kind == KindTy::Token &&
"Invalid type access!");
1073 unsigned getVType()
const {
1074 assert(Kind == KindTy::VType &&
"Invalid type access!");
1079 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1083 unsigned getFence()
const {
1084 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1088 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1097 case KindTy::Expression:
1100 OS <<
' ' << (Expr.IsRV64 ?
"rv64" :
"rv32") <<
'>';
1102 case KindTy::FPImmediate:
1103 OS <<
"<fpimm: " << FPImm.Val <<
">";
1105 case KindTy::Register:
1107 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1112 case KindTy::SystemRegister:
1113 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1122 OS << roundingModeToString(getFRM());
1130 case KindTy::RegList:
1135 case KindTy::StackAdj:
1136 OS <<
"<stackadj: ";
1140 case KindTy::RegReg:
1141 OS <<
"<RegReg: BaseReg " <<
RegName(
RegReg.BaseReg) <<
" OffsetReg "
1147 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1148 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1155 static std::unique_ptr<RISCVOperand>
1156 createReg(MCRegister
Reg, SMLoc S, SMLoc
E,
bool IsGPRAsFPR =
false) {
1157 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1159 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1165 static std::unique_ptr<RISCVOperand> createExpr(
const MCExpr *Val, SMLoc S,
1166 SMLoc
E,
bool IsRV64) {
1167 auto Op = std::make_unique<RISCVOperand>(KindTy::Expression);
1168 Op->Expr.Expr = Val;
1169 Op->Expr.IsRV64 = IsRV64;
1175 static std::unique_ptr<RISCVOperand> createFPImm(uint64_t Val, SMLoc S) {
1176 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1177 Op->FPImm.Val = Val;
1183 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1184 unsigned Encoding) {
1185 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1186 Op->SysReg.Data = Str.data();
1187 Op->SysReg.Length = Str.size();
1194 static std::unique_ptr<RISCVOperand>
1196 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1203 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val, SMLoc S) {
1204 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1205 Op->Fence.Val = Val;
1211 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI, SMLoc S) {
1212 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1213 Op->VType.Val = VTypeI;
1219 static std::unique_ptr<RISCVOperand> createRegList(
unsigned RlistEncode,
1221 auto Op = std::make_unique<RISCVOperand>(KindTy::RegList);
1227 static std::unique_ptr<RISCVOperand>
1228 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {
1229 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1231 Op->RegReg.OffsetReg = OffsetReg;
1237 static std::unique_ptr<RISCVOperand> createStackAdj(
unsigned StackAdj, SMLoc S) {
1238 auto Op = std::make_unique<RISCVOperand>(KindTy::StackAdj);
1239 Op->StackAdj.Val = StackAdj;
1244 static void addExpr(MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1245 assert(Expr &&
"Expr shouldn't be null!");
1247 bool IsConstant = evaluateConstantExpr(Expr, Imm);
1257 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1258 assert(
N == 1 &&
"Invalid number of operands!");
1262 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1263 assert(
N == 1 &&
"Invalid number of operands!");
1264 addExpr(Inst,
getExpr(), isRV64Expr());
1267 template <
unsigned Bits>
1268 void addSExtImmOperands(MCInst &Inst,
unsigned N)
const {
1269 assert(
N == 1 &&
"Invalid number of operands!");
1276 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
1277 assert(
N == 1 &&
"Invalid number of operands!");
1279 addExpr(Inst,
getExpr(), isRV64Expr());
1284 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1288 void addFenceArgOperands(MCInst &Inst,
unsigned N)
const {
1289 assert(
N == 1 &&
"Invalid number of operands!");
1293 void addCSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
1294 assert(
N == 1 &&
"Invalid number of operands!");
1301 void addVTypeIOperands(MCInst &Inst,
unsigned N)
const {
1302 assert(
N == 1 &&
"Invalid number of operands!");
1304 if (Kind == KindTy::Expression) {
1305 [[maybe_unused]]
bool IsConstantImm =
1306 evaluateConstantExpr(
getExpr(), Imm);
1307 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1314 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1315 assert(
N == 1 &&
"Invalid number of operands!");
1319 void addRegRegOperands(MCInst &Inst,
unsigned N)
const {
1320 assert(
N == 2 &&
"Invalid number of operands!");
1325 void addStackAdjOperands(MCInst &Inst,
unsigned N)
const {
1326 assert(
N == 1 &&
"Invalid number of operands!");
1330 void addFRMArgOperands(MCInst &Inst,
unsigned N)
const {
1331 assert(
N == 1 &&
"Invalid number of operands!");
1337#define GET_REGISTER_MATCHER
1338#define GET_SUBTARGET_FEATURE_NAME
1339#define GET_MATCHER_IMPLEMENTATION
1340#define GET_MNEMONIC_SPELL_CHECKER
1341#include "RISCVGenAsmMatcher.inc"
1344 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1345 return Reg - RISCV::F0_D + RISCV::F0_H;
1349 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1350 return Reg - RISCV::F0_D + RISCV::F0_F;
1354 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1355 return Reg - RISCV::F0_D + RISCV::F0_Q;
1359 assert(
Reg >= RISCV::X0 &&
Reg <= RISCV::X31 &&
"Invalid register");
1360 return Reg - RISCV::X0 + RISCV::X0_Y;
1365 unsigned RegClassID;
1366 if (Kind == MCK_VRM2)
1367 RegClassID = RISCV::VRM2RegClassID;
1368 else if (Kind == MCK_VRM4)
1369 RegClassID = RISCV::VRM4RegClassID;
1370 else if (Kind == MCK_VRM8)
1371 RegClassID = RISCV::VRM8RegClassID;
1375 &RISCVMCRegisterClasses[RegClassID]);
1379 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1380 return Reg - RISCV::F0_D + RISCV::F0_Q2;
1385 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1387 return Match_InvalidOperand;
1389 MCRegister
Reg =
Op.getReg();
1391 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg);
1393 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg);
1394 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg);
1396 if (
Op.isGPR() && Kind == MCK_YGPR) {
1399 return Match_Success;
1401 if (IsRegFPR64 && Kind == MCK_FPR256) {
1403 return Match_Success;
1405 if (IsRegFPR64 && Kind == MCK_FPR128) {
1407 return Match_Success;
1411 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1412 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1414 return Match_Success;
1418 if (IsRegFPR64 && Kind == MCK_FPR16) {
1420 return Match_Success;
1422 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1423 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_H;
1424 return Match_Success;
1426 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1427 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_W;
1428 return Match_Success;
1435 if (RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg) &&
1436 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1438 return Match_Success;
1442 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1445 return Match_InvalidOperand;
1446 return Match_Success;
1448 return Match_InvalidOperand;
1451bool RISCVAsmParser::generateImmOutOfRangeError(
1452 SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
1453 const Twine &Msg =
"immediate must be an integer in the range") {
1454 return Error(ErrorLoc, Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]");
1457bool RISCVAsmParser::generateImmOutOfRangeError(
1459 const Twine &Msg =
"immediate must be an integer in the range") {
1460 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1461 return generateImmOutOfRangeError(ErrorLoc,
Lower,
Upper, Msg);
1464bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1467 uint64_t &ErrorInfo,
1468 bool MatchingInlineAsm) {
1470 FeatureBitset MissingFeatures;
1472 auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
1478 if (validateInstruction(Inst, Operands))
1480 return processInstruction(Inst, IDLoc, Operands, Out);
1481 case Match_MissingFeature: {
1482 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1483 bool FirstFeature =
true;
1484 std::string Msg =
"instruction requires the following:";
1485 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1486 if (MissingFeatures[i]) {
1487 Msg += FirstFeature ?
" " :
", ";
1489 FirstFeature =
false;
1492 return Error(IDLoc, Msg);
1494 case Match_MnemonicFail: {
1495 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1496 std::string Suggestion = RISCVMnemonicSpellCheck(
1497 ((RISCVOperand &)*Operands[0]).
getToken(), FBS, 0);
1498 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1500 case Match_InvalidOperand: {
1501 SMLoc ErrorLoc = IDLoc;
1502 if (ErrorInfo != ~0ULL) {
1503 if (ErrorInfo >= Operands.
size())
1504 return Error(ErrorLoc,
"too few operands for instruction");
1506 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1507 if (ErrorLoc == SMLoc())
1510 return Error(ErrorLoc,
"invalid operand for instruction");
1517 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1518 SMLoc ErrorLoc = IDLoc;
1519 if (ErrorInfo != ~0ULL && ErrorInfo >= Operands.
size())
1520 return Error(ErrorLoc,
"too few operands for instruction");
1526 case Match_InvalidImmXLenLI:
1528 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1529 return Error(ErrorLoc,
"operand must be a constant 64-bit integer");
1531 return generateImmOutOfRangeError(Operands, ErrorInfo,
1532 std::numeric_limits<int32_t>::min(),
1533 std::numeric_limits<uint32_t>::max());
1534 case Match_InvalidImmXLenLI_Restricted:
1536 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1537 return Error(ErrorLoc,
"operand either must be a constant 64-bit integer "
1538 "or a bare symbol name");
1540 return generateImmOutOfRangeError(
1541 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1542 std::numeric_limits<uint32_t>::max(),
1543 "operand either must be a bare symbol name or an immediate integer in "
1545 case Match_InvalidUImmLog2XLen:
1547 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1548 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1549 case Match_InvalidUImmLog2XLenNonZero:
1551 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
1552 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1553 case Match_InvalidUImm1:
1554 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
1555 case Match_InvalidUImm2:
1556 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
1557 case Match_InvalidUImm2Lsb0:
1558 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 2,
1559 "immediate must be one of");
1560 case Match_InvalidUImm3:
1561 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
1562 case Match_InvalidUImm4:
1563 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
1564 case Match_InvalidUImm4Plus1:
1565 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4));
1566 case Match_InvalidUImm5:
1567 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1568 case Match_InvalidUImm5NonZero:
1569 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1570 case Match_InvalidUImm5GT3:
1571 return generateImmOutOfRangeError(Operands, ErrorInfo, 4, (1 << 5) - 1);
1572 case Match_InvalidUImm5Plus1:
1573 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));
1574 case Match_InvalidUImm5GE6Plus1:
1575 return generateImmOutOfRangeError(Operands, ErrorInfo, 6, (1 << 5));
1576 case Match_InvalidUImm5Slist: {
1577 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1578 return Error(ErrorLoc,
1579 "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31");
1581 case Match_InvalidUImm6:
1582 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1583 case Match_InvalidUImm6Plus1:
1584 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6));
1585 case Match_InvalidUImm7:
1586 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
1587 case Match_InvalidUImm8:
1588 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
1589 case Match_InvalidUImm8GE32:
1590 return generateImmOutOfRangeError(Operands, ErrorInfo, 32, (1 << 8) - 1);
1591 case Match_InvalidSImm5:
1592 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4),
1594 case Match_InvalidSImm5NonZero:
1595 return generateImmOutOfRangeError(
1596 Operands, ErrorInfo, -(1 << 4), (1 << 4) - 1,
1597 "immediate must be non-zero in the range");
1598 case Match_InvalidSImm6:
1599 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
1601 case Match_InvalidSImm6NonZero:
1602 return generateImmOutOfRangeError(
1603 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
1604 "immediate must be non-zero in the range");
1605 case Match_InvalidCLUIImm:
1606 return generateImmOutOfRangeError(
1607 Operands, ErrorInfo, 1, (1 << 5) - 1,
1608 "immediate must be in [0xfffe0, 0xfffff] or");
1609 case Match_InvalidUImm5Lsb0:
1610 return generateImmOutOfRangeError(
1611 Operands, ErrorInfo, 0, (1 << 5) - 2,
1612 "immediate must be a multiple of 2 bytes in the range");
1613 case Match_InvalidUImm6Lsb0:
1614 return generateImmOutOfRangeError(
1615 Operands, ErrorInfo, 0, (1 << 6) - 2,
1616 "immediate must be a multiple of 2 bytes in the range");
1617 case Match_InvalidUImm7Lsb00:
1618 return generateImmOutOfRangeError(
1619 Operands, ErrorInfo, 0, (1 << 7) - 4,
1620 "immediate must be a multiple of 4 bytes in the range");
1621 case Match_InvalidUImm8Lsb00:
1622 return generateImmOutOfRangeError(
1623 Operands, ErrorInfo, 0, (1 << 8) - 4,
1624 "immediate must be a multiple of 4 bytes in the range");
1625 case Match_InvalidUImm8Lsb000:
1626 return generateImmOutOfRangeError(
1627 Operands, ErrorInfo, 0, (1 << 8) - 8,
1628 "immediate must be a multiple of 8 bytes in the range");
1629 case Match_InvalidUImm9:
1630 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 9) - 1,
1631 "immediate offset must be in the range");
1632 case Match_InvalidBareSImm9Lsb0:
1633 return generateImmOutOfRangeError(
1634 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
1635 "immediate must be a multiple of 2 bytes in the range");
1636 case Match_InvalidUImm9Lsb000:
1637 return generateImmOutOfRangeError(
1638 Operands, ErrorInfo, 0, (1 << 9) - 8,
1639 "immediate must be a multiple of 8 bytes in the range");
1640 case Match_InvalidSImm8PLI_B:
1641 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
1643 case Match_InvalidSImm10:
1644 case Match_InvalidSImm10PLI_H:
1645 case Match_InvalidSImm10PLI_W:
1646 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
1648 case Match_InvalidSImm10PLUI:
1649 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
1651 case Match_InvalidUImm10Lsb00NonZero:
1652 return generateImmOutOfRangeError(
1653 Operands, ErrorInfo, 4, (1 << 10) - 4,
1654 "immediate must be a multiple of 4 bytes in the range");
1655 case Match_InvalidSImm10Lsb0000NonZero:
1656 return generateImmOutOfRangeError(
1657 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
1658 "immediate must be a multiple of 16 bytes and non-zero in the range");
1659 case Match_InvalidSImm11:
1660 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 10),
1662 case Match_InvalidBareSImm11Lsb0:
1663 return generateImmOutOfRangeError(
1664 Operands, ErrorInfo, -(1 << 10), (1 << 10) - 2,
1665 "immediate must be a multiple of 2 bytes in the range");
1666 case Match_InvalidUImm10:
1667 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 10) - 1);
1668 case Match_InvalidUImm11:
1669 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
1670 case Match_InvalidUImm14Lsb00:
1671 return generateImmOutOfRangeError(
1672 Operands, ErrorInfo, 0, (1 << 14) - 4,
1673 "immediate must be a multiple of 4 bytes in the range");
1674 case Match_InvalidUImm16NonZero:
1675 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16) - 1);
1676 case Match_InvalidSImm12:
1677 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11),
1679 case Match_InvalidSImm12LO:
1680 return generateImmOutOfRangeError(
1681 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
1682 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo specifier or an "
1683 "integer in the range");
1684 case Match_InvalidBareSImm12Lsb0:
1685 return generateImmOutOfRangeError(
1686 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
1687 "immediate must be a multiple of 2 bytes in the range");
1688 case Match_InvalidSImm12Lsb00000:
1689 return generateImmOutOfRangeError(
1690 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 32,
1691 "immediate must be a multiple of 32 bytes in the range");
1692 case Match_InvalidBareSImm13Lsb0:
1693 return generateImmOutOfRangeError(
1694 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
1695 "immediate must be a multiple of 2 bytes in the range");
1696 case Match_InvalidSImm16:
1697 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 15),
1699 case Match_InvalidSImm16NonZero:
1700 return generateImmOutOfRangeError(
1701 Operands, ErrorInfo, -(1 << 15), (1 << 15) - 1,
1702 "immediate must be non-zero in the range");
1703 case Match_InvalidSImm20LI:
1704 return generateImmOutOfRangeError(
1705 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 1,
1706 "operand must be a symbol with a %qc.abs20 specifier or an integer "
1708 case Match_InvalidUImm20LUI:
1709 return generateImmOutOfRangeError(
1710 Operands, ErrorInfo, 0, (1 << 20) - 1,
1711 "operand must be a symbol with "
1712 "%hi/%tprel_hi specifier or an integer in "
1714 case Match_InvalidUImm20:
1715 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1);
1716 case Match_InvalidUImm20AUIPC:
1717 return generateImmOutOfRangeError(
1718 Operands, ErrorInfo, 0, (1 << 20) - 1,
1719 "operand must be a symbol with a "
1720 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
1722 "an integer in the range");
1723 case Match_InvalidBareSImm21Lsb0:
1724 return generateImmOutOfRangeError(
1725 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
1726 "immediate must be a multiple of 2 bytes in the range");
1727 case Match_InvalidCSRSystemRegister: {
1728 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1,
1729 "operand must be a valid system register "
1730 "name or an integer in the range");
1732 case Match_InvalidImm5Zibi:
1733 return generateImmOutOfRangeError(
1734 Operands, ErrorInfo, -1, (1 << 5) - 1,
1735 "immediate must be non-zero in the range");
1736 case Match_InvalidVTypeI: {
1737 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1738 return generateVTypeError(ErrorLoc);
1740 case Match_InvalidSImm5Plus1: {
1741 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1,
1743 "immediate must be in the range");
1745 case Match_InvalidSImm18:
1746 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 17),
1748 case Match_InvalidSImm18Lsb0:
1749 return generateImmOutOfRangeError(
1750 Operands, ErrorInfo, -(1 << 17), (1 << 17) - 2,
1751 "immediate must be a multiple of 2 bytes in the range");
1752 case Match_InvalidSImm19Lsb00:
1753 return generateImmOutOfRangeError(
1754 Operands, ErrorInfo, -(1 << 18), (1 << 18) - 4,
1755 "immediate must be a multiple of 4 bytes in the range");
1756 case Match_InvalidSImm20Lsb000:
1757 return generateImmOutOfRangeError(
1758 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 8,
1759 "immediate must be a multiple of 8 bytes in the range");
1760 case Match_InvalidSImm26:
1761 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 25),
1764 case Match_InvalidBareSymbolQC_E_LI:
1767 case Match_InvalidBareSImm32:
1768 return generateImmOutOfRangeError(Operands, ErrorInfo,
1769 std::numeric_limits<int32_t>::min(),
1770 std::numeric_limits<uint32_t>::max());
1771 case Match_InvalidBareSImm32Lsb0:
1772 return generateImmOutOfRangeError(
1773 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1774 std::numeric_limits<int32_t>::max() - 1,
1775 "operand must be a multiple of 2 bytes in the range");
1776 case Match_InvalidRnumArg: {
1777 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10);
1779 case Match_InvalidStackAdj: {
1780 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1783 "stack adjustment is invalid for this instruction and register list");
1785 case Match_InvalidYBNDSWImm: {
1786 const SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1787 return Error(ErrorLoc,
"immediate must be an integer in the range "
1788 "[1, 255], a multiple of 8 in the range [256, 504], "
1789 "or a multiple of 16 in the range [512, 4096]");
1791 case Match_InvalidUImm7EqXLen: {
1792 const SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1793 return Error(ErrorLoc,
"immediate must be an integer equal to XLEN (" +
1794 Twine(isRV64() ?
"64" :
"32") +
")");
1798 if (
const char *MatchDiag = getMatchKindDiag((RISCVMatchResultTy)Result)) {
1799 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1800 return Error(ErrorLoc, MatchDiag);
1810MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name)
const {
1819 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1820 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1821 static_assert(RISCV::F0_D < RISCV::F0_Q,
"FPR matching must be updated");
1824 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1829bool RISCVAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1831 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1832 return Error(StartLoc,
"invalid register name");
1836ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1838 const AsmToken &Tok = getParser().getTok();
1841 StringRef
Name = getLexer().getTok().getIdentifier();
1851ParseStatus RISCVAsmParser::parseRegister(
OperandVector &Operands,
1853 SMLoc FirstS = getLoc();
1854 bool HadParens =
false;
1861 size_t ReadCount = getLexer().peekTokens(Buf);
1864 LParen = getParser().getTok();
1869 switch (getLexer().getKind()) {
1872 getLexer().UnLex(LParen);
1875 StringRef
Name = getLexer().getTok().getIdentifier();
1880 getLexer().UnLex(LParen);
1884 Operands.
push_back(RISCVOperand::createToken(
"(", FirstS));
1886 SMLoc
E = getTok().getEndLoc();
1893 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
1899ParseStatus RISCVAsmParser::parseInsnDirectiveOpcode(
OperandVector &Operands) {
1904 switch (getLexer().getKind()) {
1914 if (getParser().parseExpression(Res,
E))
1919 int64_t
Imm =
CE->getValue();
1921 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1930 if (getParser().parseIdentifier(Identifier))
1933 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1936 "Unexpected opcode");
1939 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1949 return generateImmOutOfRangeError(
1951 "opcode must be a valid opcode name or an immediate in the range");
1954ParseStatus RISCVAsmParser::parseInsnCDirectiveOpcode(
OperandVector &Operands) {
1959 switch (getLexer().getKind()) {
1969 if (getParser().parseExpression(Res,
E))
1974 int64_t
Imm =
CE->getValue();
1975 if (Imm >= 0 && Imm <= 2) {
1976 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1985 if (getParser().parseIdentifier(Identifier))
1989 if (Identifier ==
"C0")
1991 else if (Identifier ==
"C1")
1993 else if (Identifier ==
"C2")
2000 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2009 return generateImmOutOfRangeError(
2011 "opcode must be a valid opcode name or an immediate in the range");
2014ParseStatus RISCVAsmParser::parseCSRSystemRegister(
OperandVector &Operands) {
2018 auto SysRegFromConstantInt = [
this](
const MCExpr *
E, SMLoc S) {
2020 int64_t
Imm =
CE->getValue();
2022 auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
2026 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2029 return RISCVOperand::createSysReg(
Reg.Name, S, Imm);
2033 return RISCVOperand::createSysReg(
"", S, Imm);
2036 return std::unique_ptr<RISCVOperand>();
2039 switch (getLexer().getKind()) {
2049 if (getParser().parseExpression(Res))
2052 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
2057 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2061 if (getParser().parseIdentifier(Identifier))
2064 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
2067 if (SysReg->IsDeprecatedName) {
2069 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
2071 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2073 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
2079 const auto &FeatureBits = getSTI().getFeatureBits();
2080 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
2082 return SysReg->FeaturesRequired[Feature.Value];
2084 auto ErrorMsg = std::string(
"system register '") + SysReg->Name +
"' ";
2085 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
2086 ErrorMsg +=
"is RV32 only";
2088 ErrorMsg +=
" and ";
2092 "requires '" + std::string(Feature->Key) +
"' to be enabled";
2095 return Error(S, ErrorMsg);
2098 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
2113 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2114 "operand must be a valid system register "
2115 "name or an integer in the range");
2119 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2126ParseStatus RISCVAsmParser::parseFPImm(
OperandVector &Operands) {
2131 StringRef
Identifier = getTok().getIdentifier();
2132 if (
Identifier.compare_insensitive(
"inf") == 0) {
2135 getTok().getEndLoc(), isRV64()));
2136 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2139 getTok().getEndLoc(), isRV64()));
2140 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2143 getTok().getEndLoc(), isRV64()));
2145 return TokError(
"invalid floating point literal");
2156 const AsmToken &Tok = getTok();
2158 return TokError(
"invalid floating point immediate");
2161 APFloat RealVal(APFloat::IEEEdouble());
2163 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2165 return TokError(
"invalid floating point representation");
2168 RealVal.changeSign();
2170 Operands.
push_back(RISCVOperand::createFPImm(
2171 RealVal.bitcastToAPInt().getZExtValue(), S));
2178ParseStatus RISCVAsmParser::parseExpression(
OperandVector &Operands) {
2183 switch (getLexer().getKind()) {
2195 if (getParser().parseExpression(Res,
E))
2199 return parseOperandWithSpecifier(Operands);
2202 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2206ParseStatus RISCVAsmParser::parseOperandWithSpecifier(
OperandVector &Operands) {
2212 const MCExpr *Expr =
nullptr;
2213 bool Failed = parseExprWithSpecifier(Expr,
E);
2215 Operands.
push_back(RISCVOperand::createExpr(Expr, S,
E, isRV64()));
2219bool RISCVAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
2220 SMLoc Loc = getLoc();
2222 return TokError(
"expected '%' relocation specifier");
2223 StringRef
Identifier = getParser().getTok().getIdentifier();
2226 return TokError(
"invalid relocation specifier");
2232 const MCExpr *SubExpr;
2233 if (getParser().parseParenExpression(SubExpr,
E))
2240bool RISCVAsmParser::parseDataExpr(
const MCExpr *&Res) {
2243 return parseExprWithSpecifier(Res,
E);
2244 return getParser().parseExpression(Res);
2247ParseStatus RISCVAsmParser::parseBareSymbol(
OperandVector &Operands) {
2254 StringRef
Identifier = getTok().getIdentifier();
2264 if (getParser().parseExpression(Res,
E))
2267 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2271ParseStatus RISCVAsmParser::parseCallSymbol(
OperandVector &Operands) {
2277 std::string
Identifier(getTok().getIdentifier());
2283 SMLoc Loc = getLoc();
2284 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2285 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2299 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2303ParseStatus RISCVAsmParser::parsePseudoJumpSymbol(
OperandVector &Operands) {
2308 if (getParser().parseExpression(Res,
E))
2311 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef)
2312 return Error(S,
"operand must be a valid jump target");
2315 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2319ParseStatus RISCVAsmParser::parseJALOffset(
OperandVector &Operands) {
2333 return parseExpression(Operands);
2336bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2337 unsigned &Sew,
unsigned &Lmul,
2338 bool &Fractional,
bool &TailAgnostic,
2339 bool &MaskAgnostic,
bool &AltFmt) {
2344 if (State < VTypeState::SeenSew &&
Identifier.consume_front(
"e")) {
2346 if (Identifier ==
"16alt") {
2349 }
else if (Identifier ==
"8alt") {
2359 State = VTypeState::SeenSew;
2363 if (State < VTypeState::SeenLmul &&
Identifier.consume_front(
"m")) {
2366 if (Identifier ==
"a" || Identifier ==
"u") {
2368 State = VTypeState::SeenMaskPolicy;
2379 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2380 unsigned MinLMUL = ELEN / 8;
2383 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2384 Twine(MinLMUL) +
" is reserved");
2387 State = VTypeState::SeenLmul;
2391 if (State < VTypeState::SeenTailPolicy &&
Identifier.starts_with(
"t")) {
2392 if (Identifier ==
"ta")
2393 TailAgnostic =
true;
2394 else if (Identifier ==
"tu")
2395 TailAgnostic =
false;
2399 State = VTypeState::SeenTailPolicy;
2403 if (State < VTypeState::SeenMaskPolicy &&
Identifier.starts_with(
"m")) {
2404 if (Identifier ==
"ma")
2405 MaskAgnostic =
true;
2406 else if (Identifier ==
"mu")
2407 MaskAgnostic =
false;
2411 State = VTypeState::SeenMaskPolicy;
2418ParseStatus RISCVAsmParser::parseVTypeI(
OperandVector &Operands) {
2424 bool Fractional =
false;
2425 bool TailAgnostic =
false;
2426 bool MaskAgnostic =
false;
2429 VTypeState State = VTypeState::SeenNothingYet;
2431 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2432 MaskAgnostic, AltFmt)) {
2434 if (State == VTypeState::SeenNothingYet)
2443 State == VTypeState::SeenNothingYet)
2444 return generateVTypeError(S);
2448 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2449 unsigned MaxSEW = ELEN / Lmul;
2451 if (MaxSEW >= 8 && Sew > MaxSEW)
2452 Warning(S,
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2453 " and LMUL == mf" + Twine(Lmul) +
2454 " may not be compatible with all RVV implementations");
2459 Operands.
push_back(RISCVOperand::createVType(VTypeI, S));
2463bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2464 if (STI->
hasFeature(RISCV::FeatureStdExtZvfbfa) ||
2465 STI->
hasFeature(RISCV::FeatureStdExtZvqwdota8i) ||
2466 STI->
hasFeature(RISCV::FeatureStdExtZvqwdota16i) ||
2467 STI->
hasFeature(RISCV::FeatureStdExtZvfwdota16bf) ||
2468 STI->
hasFeature(RISCV::FeatureStdExtZvfqwdota8f) ||
2469 STI->
hasFeature(RISCV::FeatureStdExtZvfofp8min) ||
2470 STI->
hasFeature(RISCV::FeatureVendorXSfvfbfexp16e) ||
2471 STI->
hasFeature(RISCV::FeatureStdExtZvqwbdota8i) ||
2472 STI->
hasFeature(RISCV::FeatureStdExtZvqwbdota16i) ||
2473 STI->
hasFeature(RISCV::FeatureStdExtZvfqwbdota8f) ||
2474 STI->
hasFeature(RISCV::FeatureStdExtZvfwbdota16bf))
2478 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2482 "e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2485ParseStatus RISCVAsmParser::parseXSfmmVType(
OperandVector &Operands) {
2502 if (Identifier !=
"16alt")
2531 Operands.
push_back(RISCVOperand::createVType(
2537 return generateXSfmmVTypeError(S);
2540bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
2541 return Error(ErrorLoc,
"operand must be e[8|16|16alt|32|64],w[1|2|4]");
2544ParseStatus RISCVAsmParser::parseMaskReg(
OperandVector &Operands) {
2548 StringRef
Name = getLexer().getTok().getIdentifier();
2549 if (!
Name.consume_back(
".t")) {
2553 return Error(getLoc(),
"expected '.t' suffix");
2560 if (
Reg != RISCV::V0)
2563 SMLoc
E = getTok().getEndLoc();
2569ParseStatus RISCVAsmParser::parseVScaleReg(
OperandVector &Operands) {
2573 StringRef
Name = getLexer().getTok().getIdentifier();
2574 if (!
Name.consume_back(
".scale"))
2575 return Error(getLoc(),
"expected '.scale' suffix");
2580 if (
Reg != RISCV::V0)
2583 SMLoc
E = getTok().getEndLoc();
2589ParseStatus RISCVAsmParser::parseTileLambda(
OperandVector &Operands) {
2594 StringRef
Name = getLexer().getTok().getIdentifier();
2595 if (!
Name.consume_front(
"L") && !
Name.consume_front(
"l"))
2600 return Error(S,
"operand must be L1, L2, L4, L8, L16, L32, or L64");
2602 unsigned EncodedLambda =
Log2_32(Lambda) + 1;
2604 SMLoc
E = getTok().getEndLoc();
2606 Operands.
push_back(RISCVOperand::createExpr(
2611ParseStatus RISCVAsmParser::parseGPRAsFPR64(
OperandVector &Operands) {
2612 if (!isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2615 return parseGPRAsFPR(Operands);
2618ParseStatus RISCVAsmParser::parseGPRAsFPR(
OperandVector &Operands) {
2622 StringRef
Name = getLexer().getTok().getIdentifier();
2628 SMLoc
E = getTok().getEndLoc();
2630 Operands.
push_back(RISCVOperand::createReg(
2631 Reg, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2635ParseStatus RISCVAsmParser::parseGPRPairAsFPR64(
OperandVector &Operands) {
2636 if (isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2642 StringRef
Name = getLexer().getTok().getIdentifier();
2648 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2651 if ((
Reg - RISCV::X0) & 1) {
2654 if (getSTI().hasFeature(RISCV::FeatureStdExtZfinx))
2655 return TokError(
"double precision floating point operands must use even "
2656 "numbered X register");
2661 SMLoc
E = getTok().getEndLoc();
2664 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2666 Reg, RISCV::sub_gpr_even,
2667 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2668 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2672template <
bool IsRV64>
2673ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands) {
2674 return parseGPRPair(Operands, IsRV64);
2677ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands,
2684 if (!IsRV64Inst && isRV64())
2690 StringRef
Name = getLexer().getTok().getIdentifier();
2696 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2699 if ((
Reg - RISCV::X0) & 1)
2700 return TokError(
"register must be even");
2703 SMLoc
E = getTok().getEndLoc();
2706 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2708 Reg, RISCV::sub_gpr_even,
2709 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2710 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E));
2714ParseStatus RISCVAsmParser::parseFRMArg(
OperandVector &Operands) {
2717 "operand must be a valid floating point rounding mode mnemonic");
2719 StringRef Str = getLexer().getTok().getIdentifier();
2724 "operand must be a valid floating point rounding mode mnemonic");
2726 Operands.
push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2731ParseStatus RISCVAsmParser::parseFenceArg(
OperandVector &Operands) {
2732 const AsmToken &Tok = getLexer().getTok();
2738 Operands.
push_back(RISCVOperand::createFenceArg(0, getLoc()));
2752 for (
char c : Str) {
2781 Operands.
push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2787 return TokError(
"operand must be formed of letters selected in-order from "
2791ParseStatus RISCVAsmParser::parseMemOpBaseReg(
OperandVector &Operands) {
2794 Operands.
push_back(RISCVOperand::createToken(
"(", getLoc()));
2796 if (!parseRegister(Operands).isSuccess())
2797 return Error(getLoc(),
"expected register");
2801 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
2806ParseStatus RISCVAsmParser::parseZeroOffsetMemOp(
OperandVector &Operands) {
2825 std::unique_ptr<RISCVOperand> OptionalImmOp;
2832 SMLoc ImmStart = getLoc();
2833 if (getParser().parseIntToken(ImmVal,
2834 "expected '(' or optional integer offset"))
2839 SMLoc ImmEnd = getLoc();
2842 ImmStart, ImmEnd, isRV64());
2846 OptionalImmOp ?
"expected '(' after optional integer offset"
2847 :
"expected '(' or optional integer offset"))
2850 if (!parseRegister(Operands).isSuccess())
2851 return Error(getLoc(),
"expected register");
2857 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2859 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2860 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2865ParseStatus RISCVAsmParser::parseRegReg(
OperandVector &Operands) {
2871 StringRef OffsetRegName = getLexer().getTok().getIdentifier();
2874 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(OffsetReg))
2875 return Error(getLoc(),
"expected GPR register");
2882 return Error(getLoc(),
"expected GPR register");
2884 StringRef BaseRegName = getLexer().getTok().getIdentifier();
2887 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(BaseReg))
2888 return Error(getLoc(),
"expected GPR register");
2894 Operands.
push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));
2906ParseStatus RISCVAsmParser::parseRegList(
OperandVector &Operands,
2907 bool MustIncludeS0) {
2919 return Error(getLoc(),
"invalid register");
2921 StringRef
RegName = getTok().getIdentifier();
2924 return Error(getLoc(),
"invalid register");
2927 UsesXRegs =
RegName[0] ==
'x';
2928 if (
Reg != RISCV::X1)
2929 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2930 }
else if (RegEnd == RISCV::X1) {
2931 if (
Reg != RISCV::X8 || (UsesXRegs != (
RegName[0] ==
'x')))
2932 return Error(getLoc(), Twine(
"register must be '") +
2933 (UsesXRegs ?
"x8" :
"s0") +
"'");
2934 }
else if (RegEnd == RISCV::X9 && UsesXRegs) {
2935 if (
Reg != RISCV::X18 || (
RegName[0] !=
'x'))
2936 return Error(getLoc(),
"register must be 'x18'");
2938 return Error(getLoc(),
"too many register ranges");
2945 SMLoc MinusLoc = getLoc();
2947 if (RegEnd == RISCV::X1)
2948 return Error(MinusLoc, Twine(
"register '") + (UsesXRegs ?
"x1" :
"ra") +
2949 "' cannot start a multiple register range");
2952 return Error(getLoc(),
"invalid register");
2954 StringRef
RegName = getTok().getIdentifier();
2957 return Error(getLoc(),
"invalid register");
2959 if (RegEnd == RISCV::X8) {
2960 if ((
Reg != RISCV::X9 &&
2962 (UsesXRegs != (
RegName[0] ==
'x'))) {
2964 return Error(getLoc(),
"register must be 'x9'");
2965 return Error(getLoc(),
"register must be in the range 's1' to 's11'");
2967 }
else if (RegEnd == RISCV::X18) {
2969 return Error(getLoc(),
2970 "register must be in the range 'x19' to 'x27'");
2983 if (RegEnd == RISCV::X26)
2984 return Error(S,
"invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "
2985 "x18-x26}' is not supported");
2991 return Error(S,
"register list must include 's0' or 'x8'");
2993 Operands.
push_back(RISCVOperand::createRegList(Encode, S));
2998ParseStatus RISCVAsmParser::parseZcmpStackAdj(
OperandVector &Operands,
2999 bool ExpectNegative) {
3008 auto *RegListOp =
static_cast<RISCVOperand *
>(Operands.
back().
get());
3009 if (!RegListOp->isRegList())
3012 unsigned RlistEncode = RegListOp->RegList.Encoding;
3016 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||
3017 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {
3018 int64_t
Lower = StackAdjBase;
3019 int64_t
Upper = StackAdjBase + 48;
3020 if (ExpectNegative) {
3025 return generateImmOutOfRangeError(S,
Lower,
Upper,
3026 "stack adjustment for register list must "
3027 "be a multiple of 16 bytes in the range");
3031 Operands.
push_back(RISCVOperand::createStackAdj(StackAdj, S));
3039bool RISCVAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
3043 MatchOperandParserImpl(Operands, Mnemonic,
true);
3050 if (parseRegister(Operands,
true).isSuccess())
3054 if (parseExpression(Operands).isSuccess()) {
3057 return !parseMemOpBaseReg(Operands).isSuccess();
3062 Error(getLoc(),
"unknown operand");
3066bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &Info,
3067 StringRef Name, SMLoc NameLoc,
3073 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
3077 Operands.
push_back(RISCVOperand::createToken(Name, NameLoc));
3086 if (parseOperand(Operands, Name))
3092 if (parseOperand(Operands, Name))
3096 if (getParser().parseEOL(
"unexpected token")) {
3097 getParser().eatToEndOfStatement();
3103bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
3107 Kind = RE->getSpecifier();
3108 Expr = RE->getSubExpr();
3117bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
3126ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
3127 StringRef IDVal = DirectiveID.
getString();
3129 if (IDVal ==
".option")
3130 return parseDirectiveOption();
3131 if (IDVal ==
".attribute")
3132 return parseDirectiveAttribute();
3133 if (IDVal ==
".insn")
3134 return parseDirectiveInsn(DirectiveID.
getLoc());
3135 if (IDVal ==
".variant_cc")
3136 return parseDirectiveVariantCC();
3141bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
3142 bool FromOptionDirective) {
3145 clearFeatureBits(Feature.Value, Feature.Key);
3152 raw_string_ostream OutputErrMsg(Buffer);
3153 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3154 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
3155 << ErrMsg.getMessage();
3158 return Error(Loc, OutputErrMsg.str());
3160 auto &ISAInfo = *ParseResult;
3163 if (ISAInfo->hasExtension(Feature.Key))
3164 setFeatureBits(Feature.Value, Feature.Key);
3166 if (FromOptionDirective) {
3167 if (ISAInfo->getXLen() == 32 && isRV64())
3168 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3169 else if (ISAInfo->getXLen() == 64 && !isRV64())
3170 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3173 if (ISAInfo->getXLen() == 32)
3174 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
3175 else if (ISAInfo->getXLen() == 64)
3176 setFeatureBits(RISCV::Feature64Bit,
"64bit");
3178 return Error(Loc,
"bad arch string " + Arch);
3180 Result = ISAInfo->toString();
3184bool RISCVAsmParser::parseDirectiveOption() {
3185 MCAsmParser &Parser = getParser();
3187 AsmToken Tok = Parser.
getTok();
3195 if (Option ==
"push") {
3199 getTargetStreamer().emitDirectiveOptionPush();
3204 if (Option ==
"pop") {
3209 getTargetStreamer().emitDirectiveOptionPop();
3210 if (popFeatureBits())
3211 return Error(StartLoc,
".option pop with no .option push");
3216 if (Option ==
"arch") {
3224 Type = RISCVOptionArchArgType::Plus;
3226 Type = RISCVOptionArchArgType::Minus;
3227 else if (!
Args.empty())
3229 "unexpected token, expected + or -");
3231 Type = RISCVOptionArchArgType::Full;
3235 "unexpected token, expected identifier");
3241 if (
Type == RISCVOptionArchArgType::Full) {
3243 if (resetToArch(Arch, Loc, Result,
true))
3252 Loc,
"extension version number parsing not currently implemented");
3255 if (!enableExperimentalExtension() &&
3257 return Error(Loc,
"unexpected experimental extensions");
3259 if (Ext == std::end(
RISCVFeatureKV) || StringRef(Ext->Key) != Feature)
3260 return Error(Loc,
"unknown extension feature");
3264 if (
Type == RISCVOptionArchArgType::Plus) {
3267 setFeatureBits(Ext->Value, Ext->Key);
3270 copySTI().setFeatureBits(OldFeatureBits);
3271 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3274 raw_string_ostream OutputErrMsg(Buffer);
3275 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3276 OutputErrMsg << ErrMsg.getMessage();
3279 return Error(Loc, OutputErrMsg.str());
3282 assert(
Type == RISCVOptionArchArgType::Minus);
3287 if (getSTI().hasFeature(Feature.Value) &&
3288 Feature.Implies.test(Ext->Value))
3289 return Error(Loc, Twine(
"can't disable ") + Ext->Key +
3290 " extension; " + Feature.Key +
3291 " extension requires " + Ext->Key +
3295 clearFeatureBits(Ext->Value, Ext->Key);
3302 getTargetStreamer().emitDirectiveOptionArch(Args);
3304 if (
auto ParseResult =
3306 getTargetStreamer().setArchString((*ParseResult)->toString());
3310 if (Option ==
"exact") {
3314 getTargetStreamer().emitDirectiveOptionExact();
3315 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3316 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3320 if (Option ==
"noexact") {
3324 getTargetStreamer().emitDirectiveOptionNoExact();
3325 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3326 setFeatureBits(RISCV::FeatureRelax,
"relax");
3330 if (Option ==
"rvc") {
3334 getTargetStreamer().emitDirectiveOptionRVC();
3335 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3336 if (
auto ParseResult =
3338 getTargetStreamer().setArchString((*ParseResult)->toString());
3342 if (Option ==
"norvc") {
3346 getTargetStreamer().emitDirectiveOptionNoRVC();
3347 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3348 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3349 if (
auto ParseResult =
3351 getTargetStreamer().setArchString((*ParseResult)->toString());
3355 if (Option ==
"pic") {
3359 getTargetStreamer().emitDirectiveOptionPIC();
3360 ParserOptions.IsPicEnabled =
true;
3364 if (Option ==
"nopic") {
3368 getTargetStreamer().emitDirectiveOptionNoPIC();
3369 ParserOptions.IsPicEnabled =
false;
3373 if (Option ==
"relax") {
3377 getTargetStreamer().emitDirectiveOptionRelax();
3378 setFeatureBits(RISCV::FeatureRelax,
"relax");
3382 if (Option ==
"norelax") {
3386 getTargetStreamer().emitDirectiveOptionNoRelax();
3387 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3393 "unknown option, expected 'push', 'pop', "
3394 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3395 "'exact', or 'noexact'");
3403bool RISCVAsmParser::parseDirectiveAttribute() {
3404 MCAsmParser &Parser = getParser();
3410 std::optional<unsigned> Ret =
3413 return Error(TagLoc,
"attribute name not recognised: " + Name);
3417 const MCExpr *AttrExpr;
3424 if (check(!CE, TagLoc,
"expected numeric constant"))
3427 Tag =
CE->getValue();
3433 StringRef StringValue;
3434 int64_t IntegerValue = 0;
3435 bool IsIntegerValue =
true;
3440 IsIntegerValue =
false;
3443 if (IsIntegerValue) {
3444 const MCExpr *ValueExpr;
3450 return Error(ValueExprLoc,
"expected numeric constant");
3451 IntegerValue =
CE->getValue();
3464 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3466 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3469 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3473 getTargetStreamer().emitTextAttribute(
Tag, Result);
3477 getTargetStreamer().setArchString(Result);
3485 .
Cases({
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s"},
true)
3486 .Cases({
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj"},
3488 .
Cases({
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es"},
3497bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3498 MCAsmParser &Parser = getParser();
3505 std::optional<int64_t>
Length;
3515 return Error(ErrorLoc,
3516 "instruction lengths must be a non-zero multiple of two");
3520 return Error(ErrorLoc,
3521 "instruction lengths over 64 bits are not supported");
3527 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3532 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3533 return Error(ErrorLoc,
3534 "instruction length does not match the encoding");
3537 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3540 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3543 if (!getSTI().hasFeature(RISCV::FeatureStdExtZca) &&
3544 (EncodingDerivedLength == 2))
3545 return Error(ErrorLoc,
"compressed instructions are not allowed");
3547 if (getParser().parseEOL(
"invalid operand for instruction")) {
3548 getParser().eatToEndOfStatement();
3556 Opcode = RISCV::Insn16;
3559 Opcode = RISCV::Insn32;
3562 Opcode = RISCV::Insn48;
3565 Opcode = RISCV::Insn64;
3571 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3573 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3578 return Error(ErrorLoc,
"invalid instruction format");
3580 std::string FormatName = (
".insn_" +
Format).str();
3582 ParseInstructionInfo
Info;
3585 if (parseInstruction(Info, FormatName, L, Operands))
3590 return matchAndEmitInstruction(L, Opcode, Operands, Parser.
getStreamer(),
3597bool RISCVAsmParser::parseDirectiveVariantCC() {
3599 if (getParser().parseIdentifier(Name))
3600 return TokError(
"expected symbol name");
3603 getTargetStreamer().emitDirectiveVariantCC(
3608void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3611 const MCSubtargetInfo &STI = getSTI();
3612 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3615 ++RISCVNumInstrsCompressed;
3619void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3624 for (MCInst &Inst : Seq) {
3625 emitToStreamer(Out, Inst);
3629void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3630 const MCExpr *Symbol,
3632 unsigned SecondOpcode, SMLoc IDLoc,
3644 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3649 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3652 .addExpr(RefToLinkTmpLabel));
3655void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3669void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3679 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3680 emitAuipcInstPair(DestReg, DestReg, Symbol,
RISCV::S_GOT_HI, SecondOpcode,
3684void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3693 if (ParserOptions.IsPicEnabled)
3694 emitLoadGlobalAddress(Inst, IDLoc, Out);
3696 emitLoadLocalAddress(Inst, IDLoc, Out);
3699void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3709 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3710 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3711 SecondOpcode, IDLoc, Out);
3714void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3724 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3725 RISCV::ADDI, IDLoc, Out);
3728void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3729 SMLoc IDLoc, MCStreamer &Out,
3738 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3740 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3744 if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].
contains(TmpReg)) {
3745 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3746 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3754void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3755 int64_t Width, SMLoc IDLoc,
3764 const MCOperand &DestReg = Inst.
getOperand(0);
3765 const MCOperand &SourceReg = Inst.
getOperand(1);
3767 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3768 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3770 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3772 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3777 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3783void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
3790 emitToStreamer(Out, MCInstBuilder(Opcode)
3794 .addReg(MCRegister())
3796 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
3807 "The destination register should not be V0.");
3808 emitToStreamer(Out, MCInstBuilder(Opcode)
3814 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
3826 "The destination register should be V0.");
3828 "The temporary vector register should not be V0.");
3829 emitToStreamer(Out, MCInstBuilder(Opcode)
3833 .addReg(MCRegister())
3835 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3847 "The temporary vector register should not be V0.");
3848 emitToStreamer(Out, MCInstBuilder(Opcode)
3852 .addReg(MCRegister())
3854 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3859 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3864 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
3872bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
3874 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3877 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
3878 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3879 "%tprel_add specifier");
3885bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
3887 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
3890 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
3891 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
3892 "%tlsdesc_call specifier");
3898std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3899 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
3902std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3903 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3907std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3908 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3916 case RISCV::VLOXSEG2EI8_V:
3917 case RISCV::VLOXSEG2EI16_V:
3918 case RISCV::VLOXSEG2EI32_V:
3919 case RISCV::VLOXSEG2EI64_V:
3920 case RISCV::VLUXSEG2EI8_V:
3921 case RISCV::VLUXSEG2EI16_V:
3922 case RISCV::VLUXSEG2EI32_V:
3923 case RISCV::VLUXSEG2EI64_V:
3925 case RISCV::VLOXSEG3EI8_V:
3926 case RISCV::VLOXSEG3EI16_V:
3927 case RISCV::VLOXSEG3EI32_V:
3928 case RISCV::VLOXSEG3EI64_V:
3929 case RISCV::VLUXSEG3EI8_V:
3930 case RISCV::VLUXSEG3EI16_V:
3931 case RISCV::VLUXSEG3EI32_V:
3932 case RISCV::VLUXSEG3EI64_V:
3934 case RISCV::VLOXSEG4EI8_V:
3935 case RISCV::VLOXSEG4EI16_V:
3936 case RISCV::VLOXSEG4EI32_V:
3937 case RISCV::VLOXSEG4EI64_V:
3938 case RISCV::VLUXSEG4EI8_V:
3939 case RISCV::VLUXSEG4EI16_V:
3940 case RISCV::VLUXSEG4EI32_V:
3941 case RISCV::VLUXSEG4EI64_V:
3943 case RISCV::VLOXSEG5EI8_V:
3944 case RISCV::VLOXSEG5EI16_V:
3945 case RISCV::VLOXSEG5EI32_V:
3946 case RISCV::VLOXSEG5EI64_V:
3947 case RISCV::VLUXSEG5EI8_V:
3948 case RISCV::VLUXSEG5EI16_V:
3949 case RISCV::VLUXSEG5EI32_V:
3950 case RISCV::VLUXSEG5EI64_V:
3952 case RISCV::VLOXSEG6EI8_V:
3953 case RISCV::VLOXSEG6EI16_V:
3954 case RISCV::VLOXSEG6EI32_V:
3955 case RISCV::VLOXSEG6EI64_V:
3956 case RISCV::VLUXSEG6EI8_V:
3957 case RISCV::VLUXSEG6EI16_V:
3958 case RISCV::VLUXSEG6EI32_V:
3959 case RISCV::VLUXSEG6EI64_V:
3961 case RISCV::VLOXSEG7EI8_V:
3962 case RISCV::VLOXSEG7EI16_V:
3963 case RISCV::VLOXSEG7EI32_V:
3964 case RISCV::VLOXSEG7EI64_V:
3965 case RISCV::VLUXSEG7EI8_V:
3966 case RISCV::VLUXSEG7EI16_V:
3967 case RISCV::VLUXSEG7EI32_V:
3968 case RISCV::VLUXSEG7EI64_V:
3970 case RISCV::VLOXSEG8EI8_V:
3971 case RISCV::VLOXSEG8EI16_V:
3972 case RISCV::VLOXSEG8EI32_V:
3973 case RISCV::VLOXSEG8EI64_V:
3974 case RISCV::VLUXSEG8EI8_V:
3975 case RISCV::VLUXSEG8EI16_V:
3976 case RISCV::VLUXSEG8EI32_V:
3977 case RISCV::VLUXSEG8EI64_V:
3983 if (RISCVMCRegisterClasses[RISCV::VRM2RegClassID].
contains(
Reg))
3985 if (RISCVMCRegisterClasses[RISCV::VRM4RegClassID].
contains(
Reg))
3987 if (RISCVMCRegisterClasses[RISCV::VRM8RegClassID].
contains(
Reg))
3994 case RISCV::VFWMMACC_VV_SCALE:
3995 case RISCV::VFQMMACC_VV_SCALE:
3996 case RISCV::VF8WMMACC_VV_SCALE:
3997 case RISCV::VFWIMMACC_VV:
3998 case RISCV::VFQIMMACC_VV:
3999 case RISCV::VF8WIMMACC_VV:
4006bool RISCVAsmParser::validateInstruction(MCInst &Inst,
4010 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
4011 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
4014 if (DestReg == TempReg) {
4015 SMLoc Loc = Operands.
back()->getStartLoc();
4016 return Error(Loc,
"the temporary vector register cannot be the same as "
4017 "the destination register");
4021 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
4022 Opcode == RISCV::TH_LWD) {
4027 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
4028 SMLoc Loc = Operands[1]->getStartLoc();
4029 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
4033 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
4037 SMLoc Loc = Operands[1]->getStartLoc();
4038 return Error(Loc,
"rs1 and rs2 must be different");
4043 auto CheckOperandDoesNotOverlapV0 = [&](
int OperandIdx,
4044 unsigned ParsedIdx) {
4046 return Error(Operands[ParsedIdx]->getStartLoc(),
4047 "vd, vs1, and vs2 cannot overlap v0.scale");
4052 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4054 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4056 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4057 assert(DestIdx >= 0 && VS1Idx >= 0 && VS2Idx >= 0 &&
4058 "Unexpected Zvvfmm scaled operand list");
4060 if (CheckOperandDoesNotOverlapV0(DestIdx, 1) ||
4061 CheckOperandDoesNotOverlapV0(VS1Idx, 2) ||
4062 CheckOperandDoesNotOverlapV0(VS2Idx, 3))
4066 const MCInstrDesc &MCID = MII.
get(Opcode);
4070 int DestIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4074 const MCParsedAsmOperand *ParsedOp = Operands[1].get();
4075 if (!ParsedOp->
isReg()) {
4078 ParsedOp = Operands[2].get();
4080 assert(ParsedOp->
getReg() == DestReg &&
"Can't find parsed dest operand");
4084 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4088 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4089 assert(VS2Idx >= 0 &&
"No vs2 operand?");
4090 unsigned CheckEncoding =
4093 for (
unsigned i = 0; i < std::max(NF, Lmul); i++) {
4094 if ((DestEncoding + i) == CheckEncoding)
4095 return Error(Loc,
"the destination vector register group cannot overlap"
4096 " the source vector register group");
4101 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4105 unsigned CheckEncoding =
4107 for (
unsigned i = 0; i < Lmul; i++) {
4108 if ((DestEncoding + i) == CheckEncoding)
4110 "the destination vector register group cannot overlap"
4111 " the source vector register group");
4117 int VMIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vm);
4118 assert(VMIdx >= 0 &&
"No vm operand?");
4120 if (DestReg == RISCV::V0) {
4123 return Error(Loc,
"the destination vector register group cannot be V0");
4131 "Unexpected mask operand register");
4133 return Error(Loc,
"the destination vector register group cannot overlap"
4134 " the mask register");
4141bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
4149 case RISCV::PseudoC_ADDI_NOP: {
4151 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
4161 if (getSTI().hasFeature(RISCV::Feature64Bit))
4163 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV32)
4168 case RISCV::PACKW: {
4172 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV64)
4177 case RISCV::PseudoLLAImm:
4178 case RISCV::PseudoLAImm:
4179 case RISCV::PseudoLI: {
4185 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
4197 emitLoadImm(
Reg, Imm, Out);
4200 case RISCV::PseudoLLA:
4201 emitLoadLocalAddress(Inst, IDLoc, Out);
4203 case RISCV::PseudoLGA:
4204 emitLoadGlobalAddress(Inst, IDLoc, Out);
4206 case RISCV::PseudoLA:
4207 emitLoadAddress(Inst, IDLoc, Out);
4209 case RISCV::PseudoLA_TLS_IE:
4210 emitLoadTLSIEAddress(Inst, IDLoc, Out);
4212 case RISCV::PseudoLA_TLS_GD:
4213 emitLoadTLSGDAddress(Inst, IDLoc, Out);
4215 case RISCV::PseudoLB:
4216 case RISCV::PseudoQC_E_LB:
4217 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
4219 case RISCV::PseudoLBU:
4220 case RISCV::PseudoQC_E_LBU:
4221 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
4223 case RISCV::PseudoLH:
4224 case RISCV::PseudoQC_E_LH:
4225 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
4227 case RISCV::PseudoLHU:
4228 case RISCV::PseudoQC_E_LHU:
4229 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
4231 case RISCV::PseudoLW:
4232 case RISCV::PseudoQC_E_LW:
4233 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
4235 case RISCV::PseudoLWU:
4236 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
4238 case RISCV::PseudoLD:
4239 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
4241 case RISCV::PseudoLD_RV32:
4242 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
4244 case RISCV::PseudoFLH:
4245 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
4247 case RISCV::PseudoFLW:
4248 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
4250 case RISCV::PseudoFLD:
4251 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
4253 case RISCV::PseudoFLQ:
4254 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
4256 case RISCV::PseudoSB:
4257 case RISCV::PseudoQC_E_SB:
4258 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
4260 case RISCV::PseudoSH:
4261 case RISCV::PseudoQC_E_SH:
4262 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
4264 case RISCV::PseudoSW:
4265 case RISCV::PseudoQC_E_SW:
4266 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
4268 case RISCV::PseudoSD:
4269 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
4271 case RISCV::PseudoSD_RV32:
4272 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
4274 case RISCV::PseudoFSH:
4275 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
4277 case RISCV::PseudoFSW:
4278 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
4280 case RISCV::PseudoFSD:
4281 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4283 case RISCV::PseudoFSQ:
4284 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4286 case RISCV::PseudoAddTPRel:
4287 if (checkPseudoAddTPRel(Inst, Operands))
4290 case RISCV::PseudoTLSDESCCall:
4291 if (checkPseudoTLSDESCCall(Inst, Operands))
4294 case RISCV::PseudoSEXT_B:
4295 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4297 case RISCV::PseudoSEXT_H:
4298 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4300 case RISCV::PseudoZEXT_H:
4301 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4303 case RISCV::PseudoZEXT_W:
4304 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4306 case RISCV::PseudoVMSGEU_VX:
4307 case RISCV::PseudoVMSGEU_VX_M:
4308 case RISCV::PseudoVMSGEU_VX_M_T:
4309 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4311 case RISCV::PseudoVMSGE_VX:
4312 case RISCV::PseudoVMSGE_VX_M:
4313 case RISCV::PseudoVMSGE_VX_M_T:
4314 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4316 case RISCV::PseudoVMSGE_VI:
4317 case RISCV::PseudoVMSLT_VI: {
4321 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4323 emitToStreamer(Out, MCInstBuilder(
Opc)
4331 case RISCV::PseudoVMSGEU_VI:
4332 case RISCV::PseudoVMSLTU_VI: {
4339 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4342 emitToStreamer(Out, MCInstBuilder(
Opc)
4350 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4353 emitToStreamer(Out, MCInstBuilder(
Opc)
4363 case RISCV::PseudoCV_ELW:
4364 emitLoadStoreSymbol(Inst, RISCV::CV_ELW, IDLoc, Out,
false);
4368 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
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 contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector 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.
constexpr size_t size() const
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.
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 Triple & getTargetTriple() 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
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 Triple &TT, const FeatureBitset &FeatureBits, StringRef ABIName)
LLVM_ABI const TagNameMap & getRISCVAttributeTags()
static RoundingMode stringToRoundingMode(StringRef Str)
llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseFeatureBits(bool IsRV64, const FeatureBitset &FeatureBits)
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
Context & getContext() const
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.
FunctionAddr VTableAddr Value
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()
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)
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.
const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures]
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,...
Used to provide key value pairs for feature and CPU bit flags.