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;
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);
193#define GET_ASSEMBLER_HEADER
194#include "RISCVGenAsmMatcher.inc"
220 return parseRegList(
Operands,
true);
227 bool ExpectNegative =
false);
229 return parseZcmpStackAdj(
Operands,
true);
233 bool parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
234 bool parseDataExpr(
const MCExpr *&Res)
override;
236 bool parseDirectiveOption();
237 bool parseDirectiveAttribute();
238 bool parseDirectiveInsn(SMLoc L);
239 bool parseDirectiveVariantCC();
244 bool resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
245 bool FromOptionDirective);
247 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
248 if (!(getSTI().hasFeature(Feature))) {
249 MCSubtargetInfo &STI = copySTI();
250 setAvailableFeatures(
255 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
256 if (getSTI().hasFeature(Feature)) {
257 MCSubtargetInfo &STI = copySTI();
258 setAvailableFeatures(
263 void pushFeatureBits() {
264 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
265 "These two stacks must be kept synchronized");
266 FeatureBitStack.push_back(getSTI().getFeatureBits());
267 ParserOptionsStack.push_back(ParserOptions);
270 bool popFeatureBits() {
271 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
272 "These two stacks must be kept synchronized");
273 if (FeatureBitStack.empty())
276 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
277 copySTI().setFeatureBits(FeatureBits);
278 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
280 ParserOptions = ParserOptionsStack.pop_back_val();
285 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
286 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
287 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
290 enum RISCVMatchResultTy :
unsigned {
291 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
292#define GET_OPERAND_DIAGNOSTIC_TYPES
293#include "RISCVGenAsmMatcher.inc"
294#undef GET_OPERAND_DIAGNOSTIC_TYPES
298 static bool isSymbolDiff(
const MCExpr *Expr);
300 RISCVAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
301 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
302 : MCTargetAsmParser(
Options, STI, MII) {
309 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
311 auto ABIName = StringRef(
Options.ABIName);
312 if (ABIName.ends_with(
"f") && !getSTI().hasFeature(RISCV::FeatureStdExtF)) {
313 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
314 "doesn't support the F instruction set extension (ignoring "
316 }
else if (ABIName.ends_with(
"d") &&
317 !getSTI().hasFeature(RISCV::FeatureStdExtD)) {
318 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
319 "doesn't support the D instruction set extension (ignoring "
332 getTargetStreamer().emitTargetAttributes(STI,
false);
398 MCRegister OffsetReg;
401 SMLoc StartLoc, EndLoc;
416 RISCVOperand(KindTy K) : Kind(
K) {}
419 RISCVOperand(
const RISCVOperand &o) : MCParsedAsmOperand() {
421 StartLoc =
o.StartLoc;
424 case KindTy::Register:
427 case KindTy::Immediate:
430 case KindTy::FPImmediate:
436 case KindTy::SystemRegister:
448 case KindTy::RegList:
451 case KindTy::StackAdj:
452 StackAdj =
o.StackAdj;
460 bool isToken()
const override {
return Kind == KindTy::Token; }
461 bool isReg()
const override {
return Kind == KindTy::Register; }
462 bool isV0Reg()
const {
463 return Kind == KindTy::Register &&
Reg.RegNum == RISCV::V0;
465 bool isAnyReg()
const {
466 return Kind == KindTy::Register &&
467 (RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.RegNum) ||
468 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg.RegNum) ||
469 RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg.RegNum));
471 bool isAnyRegC()
const {
472 return Kind == KindTy::Register &&
473 (RISCVMCRegisterClasses[RISCV::GPRCRegClassID].contains(
475 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
478 bool isImm()
const override {
return Kind == KindTy::Immediate; }
479 bool isMem()
const override {
return false; }
480 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
481 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
482 bool isRegList()
const {
return Kind == KindTy::RegList; }
483 bool isRegListS0()
const {
484 return Kind == KindTy::RegList && RegList.Encoding !=
RISCVZC::RA;
486 bool isStackAdj()
const {
return Kind == KindTy::StackAdj; }
489 return Kind == KindTy::Register &&
490 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.RegNum);
493 bool isGPRPair()
const {
494 return Kind == KindTy::Register &&
495 RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(
499 bool isGPRPairC()
const {
500 return Kind == KindTy::Register &&
501 RISCVMCRegisterClasses[RISCV::GPRPairCRegClassID].contains(
505 bool isGPRPairNoX0()
const {
506 return Kind == KindTy::Register &&
507 RISCVMCRegisterClasses[RISCV::GPRPairNoX0RegClassID].contains(
511 bool isGPRF16()
const {
512 return Kind == KindTy::Register &&
513 RISCVMCRegisterClasses[RISCV::GPRF16RegClassID].contains(
Reg.RegNum);
516 bool isGPRF32()
const {
517 return Kind == KindTy::Register &&
518 RISCVMCRegisterClasses[RISCV::GPRF32RegClassID].contains(
Reg.RegNum);
521 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
522 bool isGPRAsFPR16()
const {
return isGPRF16() &&
Reg.IsGPRAsFPR; }
523 bool isGPRAsFPR32()
const {
return isGPRF32() &&
Reg.IsGPRAsFPR; }
524 bool isGPRPairAsFPR64()
const {
return isGPRPair() &&
Reg.IsGPRAsFPR; }
526 static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &Imm) {
528 Imm =
CE->getValue();
537 template <
int N>
bool isBareSimmNLsb0()
const {
542 if (evaluateConstantImm(
getImm(), Imm))
543 return isShiftedInt<
N - 1, 1>(fixImmediateForRV32(Imm, isRV64Imm()));
546 return RISCVAsmParser::classifySymbolRef(
getImm(), VK) &&
552 template <
int N>
bool isBareSimmN()
const {
557 if (evaluateConstantImm(
getImm(), Imm))
558 return isInt<N>(fixImmediateForRV32(Imm, isRV64Imm()));
561 return RISCVAsmParser::classifySymbolRef(
getImm(), VK) &&
567 bool isBareSymbol()
const {
570 if (!isImm() || evaluateConstantImm(
getImm(), Imm))
574 return RISCVAsmParser::classifySymbolRef(
getImm(), VK) &&
578 bool isCallSymbol()
const {
581 if (!isImm() || evaluateConstantImm(
getImm(), Imm))
585 return RISCVAsmParser::classifySymbolRef(
getImm(), VK) &&
586 VK == ELF::R_RISCV_CALL_PLT;
589 bool isPseudoJumpSymbol()
const {
592 if (!isImm() || evaluateConstantImm(
getImm(), Imm))
596 return RISCVAsmParser::classifySymbolRef(
getImm(), VK) &&
597 VK == ELF::R_RISCV_CALL_PLT;
600 bool isTPRelAddSymbol()
const {
603 if (!isImm() || evaluateConstantImm(
getImm(), Imm))
607 return RISCVAsmParser::classifySymbolRef(
getImm(), VK) &&
608 VK == ELF::R_RISCV_TPREL_ADD;
611 bool isTLSDESCCallSymbol()
const {
614 if (!isImm() || evaluateConstantImm(
getImm(), Imm))
618 return RISCVAsmParser::classifySymbolRef(
getImm(), VK) &&
619 VK == ELF::R_RISCV_TLSDESC_CALL;
622 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
626 bool isVTypeI10()
const {
627 if (Kind == KindTy::VType)
631 bool isVTypeI11()
const {
632 if (Kind == KindTy::VType)
637 bool isXSfmmVType()
const {
643 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
646 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
647 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
651 bool isLoadFPImm()
const {
654 if (Kind != KindTy::FPImmediate)
657 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
660 return Idx >= 0 && Idx != 1;
663 bool isImmXLenLI()
const {
669 if (evaluateConstantImm(
getImm(), Imm))
672 return RISCVAsmParser::isSymbolDiff(
getImm());
675 bool isImmXLenLI_Restricted()
const {
679 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm);
681 return IsConstantImm &&
685 template <
unsigned N>
bool isUImm()
const {
689 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm);
693 template <
unsigned N,
unsigned S>
bool isUImmShifted()
const {
697 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm);
701 template <
class Pred>
bool isUImmPred(Pred p)
const {
705 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm);
706 return IsConstantImm &&
p(Imm);
709 bool isUImmLog2XLen()
const {
710 if (isImm() && isRV64Imm())
715 bool isUImmLog2XLenNonZero()
const {
716 if (isImm() && isRV64Imm())
717 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<6>(Imm); });
718 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<5>(Imm); });
721 bool isUImmLog2XLenHalf()
const {
722 if (isImm() && isRV64Imm())
727 bool isUImm1()
const {
return isUImm<1>(); }
728 bool isUImm2()
const {
return isUImm<2>(); }
729 bool isUImm3()
const {
return isUImm<3>(); }
730 bool isUImm4()
const {
return isUImm<4>(); }
731 bool isUImm5()
const {
return isUImm<5>(); }
732 bool isUImm6()
const {
return isUImm<6>(); }
733 bool isUImm7()
const {
return isUImm<7>(); }
734 bool isUImm8()
const {
return isUImm<8>(); }
735 bool isUImm9()
const {
return isUImm<9>(); }
736 bool isUImm10()
const {
return isUImm<10>(); }
737 bool isUImm11()
const {
return isUImm<11>(); }
738 bool isUImm16()
const {
return isUImm<16>(); }
739 bool isUImm20()
const {
return isUImm<20>(); }
740 bool isUImm32()
const {
return isUImm<32>(); }
741 bool isUImm48()
const {
return isUImm<48>(); }
742 bool isUImm64()
const {
return isUImm<64>(); }
744 bool isUImm5NonZero()
const {
745 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<5>(Imm); });
748 bool isUImm5GT3()
const {
749 return isUImmPred([](int64_t Imm) {
return isUInt<5>(Imm) &&
Imm > 3; });
752 bool isUImm5Plus1()
const {
754 [](int64_t Imm) {
return Imm > 0 &&
isUInt<5>(Imm - 1); });
757 bool isUImm5GE6Plus1()
const {
759 [](int64_t Imm) {
return Imm >= 6 &&
isUInt<5>(Imm - 1); });
762 bool isUImm5Slist()
const {
763 return isUImmPred([](int64_t Imm) {
764 return (Imm == 0) || (
Imm == 1) || (Imm == 2) || (
Imm == 4) ||
765 (Imm == 8) || (
Imm == 16) || (Imm == 15) || (
Imm == 31);
769 bool isUImm8GE32()
const {
770 return isUImmPred([](int64_t Imm) {
return isUInt<8>(Imm) &&
Imm >= 32; });
773 bool isRnumArg()
const {
775 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(10); });
778 bool isRnumArg_0_7()
const {
780 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(7); });
783 bool isRnumArg_1_10()
const {
785 [](int64_t Imm) {
return Imm >= INT64_C(1) &&
Imm <= INT64_C(10); });
788 bool isRnumArg_2_14()
const {
790 [](int64_t Imm) {
return Imm >= INT64_C(2) &&
Imm <= INT64_C(14); });
793 template <
unsigned N>
bool isSImm()
const {
797 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm);
798 return IsConstantImm &&
isInt<N>(fixImmediateForRV32(Imm, isRV64Imm()));
801 template <
class Pred>
bool isSImmPred(Pred p)
const {
805 bool IsConstantImm = evaluateConstantImm(
getImm(), Imm);
806 return IsConstantImm &&
p(fixImmediateForRV32(Imm, isRV64Imm()));
809 bool isSImm5()
const {
return isSImm<5>(); }
810 bool isSImm6()
const {
return isSImm<6>(); }
811 bool isSImm10()
const {
return isSImm<10>(); }
812 bool isSImm11()
const {
return isSImm<11>(); }
813 bool isSImm16()
const {
return isSImm<16>(); }
814 bool isSImm26()
const {
return isSImm<26>(); }
816 bool isSImm5NonZero()
const {
817 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<5>(Imm); });
820 bool isSImm6NonZero()
const {
821 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<6>(Imm); });
824 bool isCLUIImm()
const {
825 return isUImmPred([](int64_t Imm) {
826 return (
isUInt<5>(Imm) && Imm != 0) || (
Imm >= 0xfffe0 &&
Imm <= 0xfffff);
830 bool isUImm2Lsb0()
const {
return isUImmShifted<1, 1>(); }
832 bool isUImm5Lsb0()
const {
return isUImmShifted<4, 1>(); }
834 bool isUImm6Lsb0()
const {
return isUImmShifted<5, 1>(); }
836 bool isUImm7Lsb00()
const {
return isUImmShifted<5, 2>(); }
838 bool isUImm7Lsb000()
const {
return isUImmShifted<4, 3>(); }
840 bool isUImm8Lsb00()
const {
return isUImmShifted<6, 2>(); }
842 bool isUImm8Lsb000()
const {
return isUImmShifted<5, 3>(); }
844 bool isUImm9Lsb000()
const {
return isUImmShifted<6, 3>(); }
846 bool isUImm14Lsb00()
const {
return isUImmShifted<12, 2>(); }
848 bool isUImm10Lsb00NonZero()
const {
855 static int64_t fixImmediateForRV32(int64_t Imm,
bool IsRV64Imm) {
861 bool isSImm12()
const {
866 if (evaluateConstantImm(
getImm(), Imm))
867 return isInt<12>(fixImmediateForRV32(Imm, isRV64Imm()));
870 return RISCVAsmParser::classifySymbolRef(
getImm(), VK) &&
873 VK == ELF::R_RISCV_TLSDESC_ADD_LO12);
876 bool isSImm12Lsb00000()
const {
880 bool isSImm10Lsb0000NonZero()
const {
885 bool isSImm16NonZero()
const {
886 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<16>(Imm); });
889 bool isUImm16NonZero()
const {
890 return isUImmPred([](int64_t Imm) {
return isUInt<16>(Imm) &&
Imm != 0; });
893 bool isSImm20LI()
const {
898 if (evaluateConstantImm(
getImm(), Imm))
899 return isInt<20>(fixImmediateForRV32(Imm, isRV64Imm()));
902 return RISCVAsmParser::classifySymbolRef(
getImm(), VK) &&
906 bool isSImm8Unsigned()
const {
return isSImm<8>() || isUImm<8>(); }
907 bool isSImm10Unsigned()
const {
return isSImm<10>() || isUImm<10>(); }
909 bool isUImm20LUI()
const {
914 if (evaluateConstantImm(
getImm(), Imm))
918 return RISCVAsmParser::classifySymbolRef(
getImm(), VK) &&
919 (VK == ELF::R_RISCV_HI20 || VK == ELF::R_RISCV_TPREL_HI20);
922 bool isUImm20AUIPC()
const {
927 if (evaluateConstantImm(
getImm(), Imm))
931 return RISCVAsmParser::classifySymbolRef(
getImm(), VK) &&
932 (VK == ELF::R_RISCV_PCREL_HI20 || VK == ELF::R_RISCV_GOT_HI20 ||
933 VK == ELF::R_RISCV_TLS_GOT_HI20 || VK == ELF::R_RISCV_TLS_GD_HI20 ||
934 VK == ELF::R_RISCV_TLSDESC_HI20);
937 bool isImmZero()
const {
938 return isUImmPred([](int64_t Imm) {
return 0 ==
Imm; });
941 bool isImmThree()
const {
942 return isUImmPred([](int64_t Imm) {
return 3 ==
Imm; });
945 bool isImmFour()
const {
946 return isUImmPred([](int64_t Imm) {
return 4 ==
Imm; });
949 bool isImm5Zibi()
const {
951 [](int64_t Imm) {
return (Imm != 0 &&
isUInt<5>(Imm)) ||
Imm == -1; });
954 bool isSImm5Plus1()
const {
959 bool isSImm18()
const {
960 return isSImmPred([](int64_t Imm) {
return isInt<18>(Imm); });
963 bool isSImm18Lsb0()
const {
967 bool isSImm19Lsb00()
const {
971 bool isSImm20Lsb000()
const {
975 bool isSImm32Lsb0()
const {
980 SMLoc getStartLoc()
const override {
return StartLoc; }
982 SMLoc getEndLoc()
const override {
return EndLoc; }
984 bool isRV64Imm()
const {
985 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
989 MCRegister
getReg()
const override {
990 assert(Kind == KindTy::Register &&
"Invalid type access!");
994 StringRef getSysReg()
const {
995 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
996 return StringRef(SysReg.Data, SysReg.Length);
999 const MCExpr *
getImm()
const {
1000 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
1004 uint64_t getFPConst()
const {
1005 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1010 assert(Kind == KindTy::Token &&
"Invalid type access!");
1014 unsigned getVType()
const {
1015 assert(Kind == KindTy::VType &&
"Invalid type access!");
1020 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1024 unsigned getFence()
const {
1025 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1029 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1038 case KindTy::Immediate:
1041 OS <<
' ' << (
Imm.IsRV64 ?
"rv64" :
"rv32") <<
'>';
1043 case KindTy::FPImmediate:
1044 OS <<
"<fpimm: " << FPImm.Val <<
">";
1046 case KindTy::Register:
1048 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1053 case KindTy::SystemRegister:
1054 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1063 roundingModeToString(getFRM());
1071 case KindTy::RegList:
1076 case KindTy::StackAdj:
1077 OS <<
"<stackadj: ";
1081 case KindTy::RegReg:
1082 OS <<
"<RegReg: BaseReg " <<
RegName(
RegReg.BaseReg) <<
" OffsetReg "
1088 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1089 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1096 static std::unique_ptr<RISCVOperand>
1097 createReg(MCRegister
Reg, SMLoc S, SMLoc
E,
bool IsGPRAsFPR =
false) {
1098 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1099 Op->Reg.RegNum =
Reg;
1100 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1106 static std::unique_ptr<RISCVOperand> createImm(
const MCExpr *Val, SMLoc S,
1107 SMLoc
E,
bool IsRV64) {
1108 auto Op = std::make_unique<RISCVOperand>(KindTy::Immediate);
1110 Op->Imm.IsRV64 = IsRV64;
1116 static std::unique_ptr<RISCVOperand> createFPImm(uint64_t Val, SMLoc S) {
1117 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1118 Op->FPImm.Val = Val;
1124 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1125 unsigned Encoding) {
1126 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1127 Op->SysReg.Data = Str.data();
1128 Op->SysReg.Length = Str.size();
1135 static std::unique_ptr<RISCVOperand>
1137 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1144 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val, SMLoc S) {
1145 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1146 Op->Fence.Val = Val;
1152 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI, SMLoc S) {
1153 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1154 Op->VType.Val = VTypeI;
1160 static std::unique_ptr<RISCVOperand> createRegList(
unsigned RlistEncode,
1162 auto Op = std::make_unique<RISCVOperand>(KindTy::RegList);
1168 static std::unique_ptr<RISCVOperand>
1169 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {
1170 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1172 Op->RegReg.OffsetReg = OffsetReg;
1178 static std::unique_ptr<RISCVOperand> createStackAdj(
unsigned StackAdj, SMLoc S) {
1179 auto Op = std::make_unique<RISCVOperand>(KindTy::StackAdj);
1180 Op->StackAdj.Val = StackAdj;
1185 static void addExpr(MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1186 assert(Expr &&
"Expr shouldn't be null!");
1188 bool IsConstant = evaluateConstantImm(Expr, Imm);
1198 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1199 assert(
N == 1 &&
"Invalid number of operands!");
1203 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1204 assert(
N == 1 &&
"Invalid number of operands!");
1205 addExpr(Inst,
getImm(), isRV64Imm());
1208 void addSImm8UnsignedOperands(MCInst &Inst,
unsigned N)
const {
1209 assert(
N == 1 &&
"Invalid number of operands!");
1216 void addSImm10UnsignedOperands(MCInst &Inst,
unsigned N)
const {
1217 assert(
N == 1 &&
"Invalid number of operands!");
1224 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
1225 assert(
N == 1 &&
"Invalid number of operands!");
1227 addExpr(Inst,
getImm(), isRV64Imm());
1232 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1236 void addFenceArgOperands(MCInst &Inst,
unsigned N)
const {
1237 assert(
N == 1 &&
"Invalid number of operands!");
1241 void addCSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
1242 assert(
N == 1 &&
"Invalid number of operands!");
1249 void addVTypeIOperands(MCInst &Inst,
unsigned N)
const {
1250 assert(
N == 1 &&
"Invalid number of operands!");
1252 if (Kind == KindTy::Immediate) {
1253 [[maybe_unused]]
bool IsConstantImm = evaluateConstantImm(
getImm(), Imm);
1254 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1261 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1262 assert(
N == 1 &&
"Invalid number of operands!");
1266 void addRegRegOperands(MCInst &Inst,
unsigned N)
const {
1267 assert(
N == 2 &&
"Invalid number of operands!");
1272 void addStackAdjOperands(MCInst &Inst,
unsigned N)
const {
1273 assert(
N == 1 &&
"Invalid number of operands!");
1277 void addFRMArgOperands(MCInst &Inst,
unsigned N)
const {
1278 assert(
N == 1 &&
"Invalid number of operands!");
1284#define GET_REGISTER_MATCHER
1285#define GET_SUBTARGET_FEATURE_NAME
1286#define GET_MATCHER_IMPLEMENTATION
1287#define GET_MNEMONIC_SPELL_CHECKER
1288#include "RISCVGenAsmMatcher.inc"
1291 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1292 return Reg - RISCV::F0_D + RISCV::F0_H;
1296 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1297 return Reg - RISCV::F0_D + RISCV::F0_F;
1301 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1302 return Reg - RISCV::F0_D + RISCV::F0_Q;
1307 unsigned RegClassID;
1308 if (Kind == MCK_VRM2)
1309 RegClassID = RISCV::VRM2RegClassID;
1310 else if (Kind == MCK_VRM4)
1311 RegClassID = RISCV::VRM4RegClassID;
1312 else if (Kind == MCK_VRM8)
1313 RegClassID = RISCV::VRM8RegClassID;
1317 &RISCVMCRegisterClasses[RegClassID]);
1322 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1324 return Match_InvalidOperand;
1326 MCRegister
Reg =
Op.getReg();
1328 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg);
1330 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg);
1331 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg);
1333 if (IsRegFPR64 && Kind == MCK_FPR128) {
1335 return Match_Success;
1339 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1340 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1342 return Match_Success;
1346 if (IsRegFPR64 && Kind == MCK_FPR16) {
1348 return Match_Success;
1350 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1351 Op.Reg.RegNum =
Reg - RISCV::X0 + RISCV::X0_H;
1352 return Match_Success;
1354 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1355 Op.Reg.RegNum =
Reg - RISCV::X0 + RISCV::X0_W;
1356 return Match_Success;
1363 if (RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg) &&
1364 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1366 return Match_Success;
1370 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1373 return Match_InvalidOperand;
1374 return Match_Success;
1376 return Match_InvalidOperand;
1379bool RISCVAsmParser::generateImmOutOfRangeError(
1380 SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
1381 const Twine &Msg =
"immediate must be an integer in the range") {
1382 return Error(ErrorLoc, Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]");
1385bool RISCVAsmParser::generateImmOutOfRangeError(
1387 const Twine &Msg =
"immediate must be an integer in the range") {
1388 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[ErrorInfo]).getStartLoc();
1389 return generateImmOutOfRangeError(ErrorLoc,
Lower,
Upper, Msg);
1392bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1395 uint64_t &ErrorInfo,
1396 bool MatchingInlineAsm) {
1398 FeatureBitset MissingFeatures;
1400 auto Result = MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
1406 if (validateInstruction(Inst,
Operands))
1408 return processInstruction(Inst, IDLoc,
Operands, Out);
1409 case Match_MissingFeature: {
1410 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1411 bool FirstFeature =
true;
1412 std::string Msg =
"instruction requires the following:";
1413 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1414 if (MissingFeatures[i]) {
1415 Msg += FirstFeature ?
" " :
", ";
1417 FirstFeature =
false;
1420 return Error(IDLoc, Msg);
1422 case Match_MnemonicFail: {
1423 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1424 std::string Suggestion = RISCVMnemonicSpellCheck(
1426 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1428 case Match_InvalidOperand: {
1429 SMLoc ErrorLoc = IDLoc;
1430 if (ErrorInfo != ~0ULL) {
1432 return Error(ErrorLoc,
"too few operands for instruction");
1434 ErrorLoc = ((RISCVOperand &)*
Operands[ErrorInfo]).getStartLoc();
1435 if (ErrorLoc == SMLoc())
1438 return Error(ErrorLoc,
"invalid operand for instruction");
1445 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1446 SMLoc ErrorLoc = IDLoc;
1447 if (ErrorInfo != ~0ULL && ErrorInfo >=
Operands.size())
1448 return Error(ErrorLoc,
"too few operands for instruction");
1454 case Match_InvalidImmXLenLI:
1456 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[ErrorInfo]).getStartLoc();
1457 return Error(ErrorLoc,
"operand must be a constant 64-bit integer");
1459 return generateImmOutOfRangeError(
Operands, ErrorInfo,
1460 std::numeric_limits<int32_t>::min(),
1461 std::numeric_limits<uint32_t>::max());
1462 case Match_InvalidImmXLenLI_Restricted:
1464 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[ErrorInfo]).getStartLoc();
1465 return Error(ErrorLoc,
"operand either must be a constant 64-bit integer "
1466 "or a bare symbol name");
1468 return generateImmOutOfRangeError(
1469 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1470 std::numeric_limits<uint32_t>::max(),
1471 "operand either must be a bare symbol name or an immediate integer in "
1473 case Match_InvalidUImmLog2XLen:
1475 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 6) - 1);
1476 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 5) - 1);
1477 case Match_InvalidUImmLog2XLenNonZero:
1479 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 6) - 1);
1480 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 5) - 1);
1481 case Match_InvalidUImm1:
1482 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 1) - 1);
1483 case Match_InvalidUImm2:
1484 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 2) - 1);
1485 case Match_InvalidUImm2Lsb0:
1486 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, 2,
1487 "immediate must be one of");
1488 case Match_InvalidUImm3:
1489 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 3) - 1);
1490 case Match_InvalidUImm4:
1491 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 4) - 1);
1492 case Match_InvalidUImm5:
1493 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 5) - 1);
1494 case Match_InvalidUImm5NonZero:
1495 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 5) - 1);
1496 case Match_InvalidUImm5GT3:
1497 return generateImmOutOfRangeError(
Operands, ErrorInfo, 4, (1 << 5) - 1);
1498 case Match_InvalidUImm5Plus1:
1499 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 5));
1500 case Match_InvalidUImm5GE6Plus1:
1501 return generateImmOutOfRangeError(
Operands, ErrorInfo, 6, (1 << 5));
1502 case Match_InvalidUImm5Slist: {
1503 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[ErrorInfo]).getStartLoc();
1504 return Error(ErrorLoc,
1505 "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31");
1507 case Match_InvalidUImm6:
1508 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 6) - 1);
1509 case Match_InvalidUImm7:
1510 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 7) - 1);
1511 case Match_InvalidUImm8:
1512 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 8) - 1);
1513 case Match_InvalidUImm8GE32:
1514 return generateImmOutOfRangeError(
Operands, ErrorInfo, 32, (1 << 8) - 1);
1515 case Match_InvalidSImm5:
1516 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 4),
1518 case Match_InvalidSImm5NonZero:
1519 return generateImmOutOfRangeError(
1520 Operands, ErrorInfo, -(1 << 4), (1 << 4) - 1,
1521 "immediate must be non-zero in the range");
1522 case Match_InvalidSImm6:
1523 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 5),
1525 case Match_InvalidSImm6NonZero:
1526 return generateImmOutOfRangeError(
1527 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
1528 "immediate must be non-zero in the range");
1529 case Match_InvalidCLUIImm:
1530 return generateImmOutOfRangeError(
1531 Operands, ErrorInfo, 1, (1 << 5) - 1,
1532 "immediate must be in [0xfffe0, 0xfffff] or");
1533 case Match_InvalidUImm5Lsb0:
1534 return generateImmOutOfRangeError(
1535 Operands, ErrorInfo, 0, (1 << 5) - 2,
1536 "immediate must be a multiple of 2 bytes in the range");
1537 case Match_InvalidUImm6Lsb0:
1538 return generateImmOutOfRangeError(
1539 Operands, ErrorInfo, 0, (1 << 6) - 2,
1540 "immediate must be a multiple of 2 bytes in the range");
1541 case Match_InvalidUImm7Lsb00:
1542 return generateImmOutOfRangeError(
1543 Operands, ErrorInfo, 0, (1 << 7) - 4,
1544 "immediate must be a multiple of 4 bytes in the range");
1545 case Match_InvalidUImm8Lsb00:
1546 return generateImmOutOfRangeError(
1547 Operands, ErrorInfo, 0, (1 << 8) - 4,
1548 "immediate must be a multiple of 4 bytes in the range");
1549 case Match_InvalidUImm8Lsb000:
1550 return generateImmOutOfRangeError(
1551 Operands, ErrorInfo, 0, (1 << 8) - 8,
1552 "immediate must be a multiple of 8 bytes in the range");
1553 case Match_InvalidUImm9:
1554 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 9) - 1,
1555 "immediate offset must be in the range");
1556 case Match_InvalidBareSImm9Lsb0:
1557 return generateImmOutOfRangeError(
1558 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
1559 "immediate must be a multiple of 2 bytes in the range");
1560 case Match_InvalidUImm9Lsb000:
1561 return generateImmOutOfRangeError(
1562 Operands, ErrorInfo, 0, (1 << 9) - 8,
1563 "immediate must be a multiple of 8 bytes in the range");
1564 case Match_InvalidSImm8Unsigned:
1565 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 7),
1567 case Match_InvalidSImm10:
1568 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 9),
1570 case Match_InvalidSImm10Unsigned:
1571 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 9),
1573 case Match_InvalidUImm10Lsb00NonZero:
1574 return generateImmOutOfRangeError(
1575 Operands, ErrorInfo, 4, (1 << 10) - 4,
1576 "immediate must be a multiple of 4 bytes in the range");
1577 case Match_InvalidSImm10Lsb0000NonZero:
1578 return generateImmOutOfRangeError(
1579 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
1580 "immediate must be a multiple of 16 bytes and non-zero in the range");
1581 case Match_InvalidSImm11:
1582 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 10),
1584 case Match_InvalidBareSImm11Lsb0:
1585 return generateImmOutOfRangeError(
1586 Operands, ErrorInfo, -(1 << 10), (1 << 10) - 2,
1587 "immediate must be a multiple of 2 bytes in the range");
1588 case Match_InvalidUImm10:
1589 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 10) - 1);
1590 case Match_InvalidUImm11:
1591 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 11) - 1);
1592 case Match_InvalidUImm14Lsb00:
1593 return generateImmOutOfRangeError(
1594 Operands, ErrorInfo, 0, (1 << 14) - 4,
1595 "immediate must be a multiple of 4 bytes in the range");
1596 case Match_InvalidUImm16NonZero:
1597 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 16) - 1);
1598 case Match_InvalidSImm12:
1599 return generateImmOutOfRangeError(
1600 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
1601 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo specifier or an "
1602 "integer in the range");
1603 case Match_InvalidBareSImm12Lsb0:
1604 return generateImmOutOfRangeError(
1605 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
1606 "immediate must be a multiple of 2 bytes in the range");
1607 case Match_InvalidSImm12Lsb00000:
1608 return generateImmOutOfRangeError(
1609 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 32,
1610 "immediate must be a multiple of 32 bytes in the range");
1611 case Match_InvalidBareSImm13Lsb0:
1612 return generateImmOutOfRangeError(
1613 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
1614 "immediate must be a multiple of 2 bytes in the range");
1615 case Match_InvalidSImm16:
1616 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 15),
1618 case Match_InvalidSImm16NonZero:
1619 return generateImmOutOfRangeError(
1620 Operands, ErrorInfo, -(1 << 15), (1 << 15) - 1,
1621 "immediate must be non-zero in the range");
1622 case Match_InvalidSImm20LI:
1623 return generateImmOutOfRangeError(
1624 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 1,
1625 "operand must be a symbol with a %qc.abs20 specifier or an integer "
1627 case Match_InvalidUImm20LUI:
1628 return generateImmOutOfRangeError(
1629 Operands, ErrorInfo, 0, (1 << 20) - 1,
1630 "operand must be a symbol with "
1631 "%hi/%tprel_hi specifier or an integer in "
1633 case Match_InvalidUImm20:
1634 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 20) - 1);
1635 case Match_InvalidUImm20AUIPC:
1636 return generateImmOutOfRangeError(
1637 Operands, ErrorInfo, 0, (1 << 20) - 1,
1638 "operand must be a symbol with a "
1639 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
1641 "an integer in the range");
1642 case Match_InvalidBareSImm21Lsb0:
1643 return generateImmOutOfRangeError(
1644 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
1645 "immediate must be a multiple of 2 bytes in the range");
1646 case Match_InvalidCSRSystemRegister: {
1647 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 12) - 1,
1648 "operand must be a valid system register "
1649 "name or an integer in the range");
1651 case Match_InvalidImm5Zibi:
1652 return generateImmOutOfRangeError(
1653 Operands, ErrorInfo, -1, (1 << 5) - 1,
1654 "immediate must be non-zero in the range");
1655 case Match_InvalidVTypeI: {
1656 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[ErrorInfo]).getStartLoc();
1657 return generateVTypeError(ErrorLoc);
1659 case Match_InvalidSImm5Plus1: {
1660 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 4) + 1,
1662 "immediate must be in the range");
1664 case Match_InvalidSImm18:
1665 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 17),
1667 case Match_InvalidSImm18Lsb0:
1668 return generateImmOutOfRangeError(
1669 Operands, ErrorInfo, -(1 << 17), (1 << 17) - 2,
1670 "immediate must be a multiple of 2 bytes in the range");
1671 case Match_InvalidSImm19Lsb00:
1672 return generateImmOutOfRangeError(
1673 Operands, ErrorInfo, -(1 << 18), (1 << 18) - 4,
1674 "immediate must be a multiple of 4 bytes in the range");
1675 case Match_InvalidSImm20Lsb000:
1676 return generateImmOutOfRangeError(
1677 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 8,
1678 "immediate must be a multiple of 8 bytes in the range");
1679 case Match_InvalidSImm26:
1680 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 25),
1683 case Match_InvalidBareSymbolQC_E_LI:
1686 case Match_InvalidBareSImm32:
1687 return generateImmOutOfRangeError(
Operands, ErrorInfo,
1688 std::numeric_limits<int32_t>::min(),
1689 std::numeric_limits<uint32_t>::max());
1690 case Match_InvalidBareSImm32Lsb0:
1691 return generateImmOutOfRangeError(
1692 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1693 std::numeric_limits<int32_t>::max() - 1,
1694 "operand must be a multiple of 2 bytes in the range");
1695 case Match_InvalidRnumArg: {
1696 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, 10);
1698 case Match_InvalidStackAdj: {
1699 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[ErrorInfo]).getStartLoc();
1702 "stack adjustment is invalid for this instruction and register list");
1706 if (
const char *MatchDiag = getMatchKindDiag((RISCVMatchResultTy)Result)) {
1707 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[ErrorInfo]).getStartLoc();
1708 return Error(ErrorLoc, MatchDiag);
1718MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name)
const {
1727 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1728 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1729 static_assert(RISCV::F0_D < RISCV::F0_Q,
"FPR matching must be updated");
1732 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1737bool RISCVAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1739 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1740 return Error(StartLoc,
"invalid register name");
1744ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1746 const AsmToken &Tok = getParser().getTok();
1749 StringRef
Name = getLexer().getTok().getIdentifier();
1761 SMLoc FirstS = getLoc();
1762 bool HadParens =
false;
1769 size_t ReadCount = getLexer().peekTokens(Buf);
1772 LParen = getParser().getTok();
1777 switch (getLexer().getKind()) {
1780 getLexer().UnLex(LParen);
1783 StringRef
Name = getLexer().getTok().getIdentifier();
1788 getLexer().UnLex(LParen);
1792 Operands.push_back(RISCVOperand::createToken(
"(", FirstS));
1794 SMLoc
E = getTok().getEndLoc();
1796 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
1801 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
1812 switch (getLexer().getKind()) {
1822 if (getParser().parseExpression(Res,
E))
1827 int64_t
Imm =
CE->getValue();
1829 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1838 if (getParser().parseIdentifier(Identifier))
1841 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1844 "Unexpected opcode");
1847 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1857 return generateImmOutOfRangeError(
1859 "opcode must be a valid opcode name or an immediate in the range");
1867 switch (getLexer().getKind()) {
1877 if (getParser().parseExpression(Res,
E))
1882 int64_t
Imm =
CE->getValue();
1883 if (Imm >= 0 && Imm <= 2) {
1884 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1893 if (getParser().parseIdentifier(Identifier))
1897 if (Identifier ==
"C0")
1899 else if (Identifier ==
"C1")
1901 else if (Identifier ==
"C2")
1908 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1917 return generateImmOutOfRangeError(
1919 "opcode must be a valid opcode name or an immediate in the range");
1926 auto SysRegFromConstantInt = [
this](
const MCExpr *
E, SMLoc S) {
1928 int64_t
Imm =
CE->getValue();
1930 auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
1934 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
1937 return RISCVOperand::createSysReg(
Reg.Name, S, Imm);
1941 return RISCVOperand::createSysReg(
"", S, Imm);
1944 return std::unique_ptr<RISCVOperand>();
1947 switch (getLexer().getKind()) {
1957 if (getParser().parseExpression(Res))
1960 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
1961 Operands.push_back(std::move(SysOpnd));
1965 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1969 if (getParser().parseIdentifier(Identifier))
1972 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1975 if (SysReg->IsDeprecatedName) {
1977 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
1979 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
1981 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
1987 const auto &FeatureBits = getSTI().getFeatureBits();
1988 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
1990 return SysReg->FeaturesRequired[Feature.Value];
1992 auto ErrorMsg = std::string(
"system register '") + SysReg->Name +
"' ";
1993 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
1994 ErrorMsg +=
"is RV32 only";
1996 ErrorMsg +=
" and ";
2000 "requires '" + std::string(Feature->Key) +
"' to be enabled";
2003 return Error(S, ErrorMsg);
2006 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
2016 Operands.push_back(std::move(SysOpnd));
2021 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2022 "operand must be a valid system register "
2023 "name or an integer in the range");
2027 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2039 StringRef
Identifier = getTok().getIdentifier();
2040 if (
Identifier.compare_insensitive(
"inf") == 0) {
2043 getTok().getEndLoc(), isRV64()));
2044 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2047 getTok().getEndLoc(), isRV64()));
2048 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2051 getTok().getEndLoc(), isRV64()));
2053 return TokError(
"invalid floating point literal");
2064 const AsmToken &Tok = getTok();
2066 return TokError(
"invalid floating point immediate");
2069 APFloat RealVal(APFloat::IEEEdouble());
2071 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2073 return TokError(
"invalid floating point representation");
2076 RealVal.changeSign();
2078 Operands.push_back(RISCVOperand::createFPImm(
2079 RealVal.bitcastToAPInt().getZExtValue(), S));
2091 switch (getLexer().getKind()) {
2103 if (getParser().parseExpression(Res,
E))
2107 return parseOperandWithSpecifier(
Operands);
2110 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2120 const MCExpr *Expr =
nullptr;
2121 bool Failed = parseExprWithSpecifier(Expr,
E);
2123 Operands.push_back(RISCVOperand::createImm(Expr, S,
E, isRV64()));
2127bool RISCVAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
2128 SMLoc Loc = getLoc();
2130 return TokError(
"expected '%' relocation specifier");
2131 StringRef
Identifier = getParser().getTok().getIdentifier();
2134 return TokError(
"invalid relocation specifier");
2140 const MCExpr *SubExpr;
2141 if (getParser().parseParenExpression(SubExpr,
E))
2148bool RISCVAsmParser::parseDataExpr(
const MCExpr *&Res) {
2151 return parseExprWithSpecifier(Res,
E);
2152 return getParser().parseExpression(Res);
2163 AsmToken Tok = getLexer().getTok();
2165 if (getParser().parseIdentifier(Identifier))
2175 getLexer().UnLex(Tok);
2183 switch (getLexer().getKind()) {
2185 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2198 if (getParser().parseExpression(Expr,
E))
2201 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2211 std::string
Identifier(getTok().getIdentifier());
2217 SMLoc Loc = getLoc();
2218 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2219 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2233 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2242 if (getParser().parseExpression(Res,
E))
2245 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef)
2246 return Error(S,
"operand must be a valid jump target");
2249 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2270bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2271 unsigned &Sew,
unsigned &Lmul,
2272 bool &Fractional,
bool &TailAgnostic,
2273 bool &MaskAgnostic,
bool &AltFmt) {
2278 if (State < VTypeState::SeenSew &&
Identifier.consume_front(
"e")) {
2280 if (Identifier ==
"16alt") {
2283 }
else if (Identifier ==
"8alt") {
2293 State = VTypeState::SeenSew;
2297 if (State < VTypeState::SeenLmul &&
Identifier.consume_front(
"m")) {
2300 if (Identifier ==
"a" || Identifier ==
"u") {
2302 State = VTypeState::SeenMaskPolicy;
2313 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2314 unsigned MinLMUL = ELEN / 8;
2317 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2318 Twine(MinLMUL) +
" is reserved");
2321 State = VTypeState::SeenLmul;
2325 if (State < VTypeState::SeenTailPolicy &&
Identifier.starts_with(
"t")) {
2326 if (Identifier ==
"ta")
2327 TailAgnostic =
true;
2328 else if (Identifier ==
"tu")
2329 TailAgnostic =
false;
2333 State = VTypeState::SeenTailPolicy;
2337 if (State < VTypeState::SeenMaskPolicy &&
Identifier.starts_with(
"m")) {
2338 if (Identifier ==
"ma")
2339 MaskAgnostic =
true;
2340 else if (Identifier ==
"mu")
2341 MaskAgnostic =
false;
2345 State = VTypeState::SeenMaskPolicy;
2358 bool Fractional =
false;
2359 bool TailAgnostic =
false;
2360 bool MaskAgnostic =
false;
2361 bool AltFmt =
false;
2363 VTypeState State = VTypeState::SeenNothingYet;
2365 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2366 MaskAgnostic, AltFmt)) {
2368 if (State == VTypeState::SeenNothingYet)
2377 State == VTypeState::SeenNothingYet)
2378 return generateVTypeError(S);
2382 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2383 unsigned MaxSEW = ELEN / Lmul;
2385 if (MaxSEW >= 8 && Sew > MaxSEW)
2386 Warning(S,
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2387 " and LMUL == mf" + Twine(Lmul) +
2388 " may not be compatible with all RVV implementations");
2393 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2397bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2398 if (STI->
hasFeature(RISCV::FeatureStdExtZvfbfa))
2402 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2406 "e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2414 bool AltFmt =
false;
2426 if (Identifier !=
"16alt")
2455 Operands.push_back(RISCVOperand::createVType(
2461 return generateXSfmmVTypeError(S);
2464bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
2465 return Error(ErrorLoc,
"operand must be e[8|16|16alt|32|64],w[1|2|4]");
2472 StringRef
Name = getLexer().getTok().getIdentifier();
2473 if (!
Name.consume_back(
".t"))
2474 return Error(getLoc(),
"expected '.t' suffix");
2479 if (
Reg != RISCV::V0)
2482 SMLoc
E = getTok().getEndLoc();
2484 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2489 if (!isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2499 StringRef
Name = getLexer().getTok().getIdentifier();
2505 SMLoc
E = getTok().getEndLoc();
2507 Operands.push_back(RISCVOperand::createReg(
2508 Reg, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2513 if (isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2519 StringRef
Name = getLexer().getTok().getIdentifier();
2525 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2528 if ((
Reg - RISCV::X0) & 1) {
2531 if (getSTI().hasFeature(RISCV::FeatureStdExtZfinx))
2532 return TokError(
"double precision floating point operands must use even "
2533 "numbered X register");
2538 SMLoc
E = getTok().getEndLoc();
2541 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2543 Reg, RISCV::sub_gpr_even,
2544 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2545 Operands.push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2549template <
bool IsRV64>
2551 return parseGPRPair(
Operands, IsRV64);
2561 if (!IsRV64Inst && isRV64())
2567 StringRef
Name = getLexer().getTok().getIdentifier();
2573 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2576 if ((
Reg - RISCV::X0) & 1)
2577 return TokError(
"register must be even");
2580 SMLoc
E = getTok().getEndLoc();
2583 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2585 Reg, RISCV::sub_gpr_even,
2586 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2587 Operands.push_back(RISCVOperand::createReg(Pair, S,
E));
2594 "operand must be a valid floating point rounding mode mnemonic");
2596 StringRef Str = getLexer().getTok().getIdentifier();
2601 "operand must be a valid floating point rounding mode mnemonic");
2603 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2609 const AsmToken &Tok = getLexer().getTok();
2615 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2629 for (
char c : Str) {
2658 Operands.push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2664 return TokError(
"operand must be formed of letters selected in-order from "
2671 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
2673 if (!parseRegister(
Operands).isSuccess())
2674 return Error(getLoc(),
"expected register");
2678 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2702 std::unique_ptr<RISCVOperand> OptionalImmOp;
2709 SMLoc ImmStart = getLoc();
2710 if (getParser().parseIntToken(ImmVal,
2711 "expected '(' or optional integer offset"))
2716 SMLoc ImmEnd = getLoc();
2719 ImmStart, ImmEnd, isRV64());
2723 OptionalImmOp ?
"expected '(' after optional integer offset"
2724 :
"expected '(' or optional integer offset"))
2727 if (!parseRegister(
Operands).isSuccess())
2728 return Error(getLoc(),
"expected register");
2734 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2736 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2737 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2748 StringRef OffsetRegName = getLexer().getTok().getIdentifier();
2751 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(OffsetReg))
2752 return Error(getLoc(),
"expected GPR register");
2759 return Error(getLoc(),
"expected GPR register");
2761 StringRef BaseRegName = getLexer().getTok().getIdentifier();
2764 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(BaseReg))
2765 return Error(getLoc(),
"expected GPR register");
2771 Operands.push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));
2784 bool MustIncludeS0) {
2796 return Error(getLoc(),
"invalid register");
2798 StringRef
RegName = getTok().getIdentifier();
2801 return Error(getLoc(),
"invalid register");
2804 UsesXRegs =
RegName[0] ==
'x';
2805 if (
Reg != RISCV::X1)
2806 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2807 }
else if (RegEnd == RISCV::X1) {
2808 if (
Reg != RISCV::X8 || (UsesXRegs != (
RegName[0] ==
'x')))
2809 return Error(getLoc(), Twine(
"register must be '") +
2810 (UsesXRegs ?
"x8" :
"s0") +
"'");
2811 }
else if (RegEnd == RISCV::X9 && UsesXRegs) {
2812 if (
Reg != RISCV::X18 || (
RegName[0] !=
'x'))
2813 return Error(getLoc(),
"register must be 'x18'");
2815 return Error(getLoc(),
"too many register ranges");
2822 SMLoc MinusLoc = getLoc();
2824 if (RegEnd == RISCV::X1)
2825 return Error(MinusLoc, Twine(
"register '") + (UsesXRegs ?
"x1" :
"ra") +
2826 "' cannot start a multiple register range");
2829 return Error(getLoc(),
"invalid register");
2831 StringRef
RegName = getTok().getIdentifier();
2834 return Error(getLoc(),
"invalid register");
2836 if (RegEnd == RISCV::X8) {
2837 if ((
Reg != RISCV::X9 &&
2839 (UsesXRegs != (
RegName[0] ==
'x'))) {
2841 return Error(getLoc(),
"register must be 'x9'");
2842 return Error(getLoc(),
"register must be in the range 's1' to 's11'");
2844 }
else if (RegEnd == RISCV::X18) {
2846 return Error(getLoc(),
2847 "register must be in the range 'x19' to 'x27'");
2860 if (RegEnd == RISCV::X26)
2861 return Error(S,
"invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "
2862 "x18-x26}' is not supported");
2868 return Error(S,
"register list must include 's0' or 'x8'");
2870 Operands.push_back(RISCVOperand::createRegList(Encode, S));
2876 bool ExpectNegative) {
2885 auto *RegListOp =
static_cast<RISCVOperand *
>(
Operands.back().
get());
2886 if (!RegListOp->isRegList())
2889 unsigned RlistEncode = RegListOp->RegList.Encoding;
2893 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||
2894 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {
2895 int64_t
Lower = StackAdjBase;
2896 int64_t
Upper = StackAdjBase + 48;
2897 if (ExpectNegative) {
2902 return generateImmOutOfRangeError(S,
Lower,
Upper,
2903 "stack adjustment for register list must "
2904 "be a multiple of 16 bytes in the range");
2908 Operands.push_back(RISCVOperand::createStackAdj(StackAdj, S));
2920 MatchOperandParserImpl(
Operands, Mnemonic,
true);
2927 if (parseRegister(
Operands,
true).isSuccess())
2934 return !parseMemOpBaseReg(
Operands).isSuccess();
2939 Error(getLoc(),
"unknown operand");
2943bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &
Info,
2944 StringRef Name, SMLoc NameLoc,
2950 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
2954 Operands.push_back(RISCVOperand::createToken(Name, NameLoc));
2973 if (getParser().parseEOL(
"unexpected token")) {
2974 getParser().eatToEndOfStatement();
2980bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
2984 Kind = RE->getSpecifier();
2985 Expr = RE->getSubExpr();
2994bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
3003ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
3004 StringRef IDVal = DirectiveID.
getString();
3006 if (IDVal ==
".option")
3007 return parseDirectiveOption();
3008 if (IDVal ==
".attribute")
3009 return parseDirectiveAttribute();
3010 if (IDVal ==
".insn")
3011 return parseDirectiveInsn(DirectiveID.
getLoc());
3012 if (IDVal ==
".variant_cc")
3013 return parseDirectiveVariantCC();
3018bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
3019 bool FromOptionDirective) {
3022 clearFeatureBits(Feature.Value, Feature.Key);
3029 raw_string_ostream OutputErrMsg(Buffer);
3030 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3031 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
3032 << ErrMsg.getMessage();
3035 return Error(Loc, OutputErrMsg.str());
3037 auto &ISAInfo = *ParseResult;
3040 if (ISAInfo->hasExtension(Feature.Key))
3041 setFeatureBits(Feature.Value, Feature.Key);
3043 if (FromOptionDirective) {
3044 if (ISAInfo->getXLen() == 32 && isRV64())
3045 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3046 else if (ISAInfo->getXLen() == 64 && !isRV64())
3047 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3050 if (ISAInfo->getXLen() == 32)
3051 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
3052 else if (ISAInfo->getXLen() == 64)
3053 setFeatureBits(RISCV::Feature64Bit,
"64bit");
3055 return Error(Loc,
"bad arch string " + Arch);
3057 Result = ISAInfo->toString();
3061bool RISCVAsmParser::parseDirectiveOption() {
3062 MCAsmParser &Parser = getParser();
3064 AsmToken Tok = Parser.
getTok();
3072 if (Option ==
"push") {
3076 getTargetStreamer().emitDirectiveOptionPush();
3081 if (Option ==
"pop") {
3086 getTargetStreamer().emitDirectiveOptionPop();
3087 if (popFeatureBits())
3088 return Error(StartLoc,
".option pop with no .option push");
3093 if (Option ==
"arch") {
3101 Type = RISCVOptionArchArgType::Plus;
3103 Type = RISCVOptionArchArgType::Minus;
3104 else if (!
Args.empty())
3106 "unexpected token, expected + or -");
3108 Type = RISCVOptionArchArgType::Full;
3112 "unexpected token, expected identifier");
3118 if (
Type == RISCVOptionArchArgType::Full) {
3120 if (resetToArch(Arch, Loc, Result,
true))
3129 Loc,
"extension version number parsing not currently implemented");
3132 if (!enableExperimentalExtension() &&
3134 return Error(Loc,
"unexpected experimental extensions");
3137 return Error(Loc,
"unknown extension feature");
3141 if (
Type == RISCVOptionArchArgType::Plus) {
3144 setFeatureBits(
Ext->Value,
Ext->Key);
3147 copySTI().setFeatureBits(OldFeatureBits);
3148 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3151 raw_string_ostream OutputErrMsg(Buffer);
3152 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3153 OutputErrMsg << ErrMsg.getMessage();
3156 return Error(Loc, OutputErrMsg.str());
3159 assert(
Type == RISCVOptionArchArgType::Minus);
3164 if (getSTI().hasFeature(Feature.Value) &&
3165 Feature.Implies.test(
Ext->Value))
3166 return Error(Loc, Twine(
"can't disable ") +
Ext->Key +
3167 " extension; " + Feature.Key +
3168 " extension requires " +
Ext->Key +
3172 clearFeatureBits(
Ext->Value,
Ext->Key);
3179 getTargetStreamer().emitDirectiveOptionArch(Args);
3183 if (Option ==
"exact") {
3187 getTargetStreamer().emitDirectiveOptionExact();
3188 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3189 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3193 if (Option ==
"noexact") {
3197 getTargetStreamer().emitDirectiveOptionNoExact();
3198 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3199 setFeatureBits(RISCV::FeatureRelax,
"relax");
3203 if (Option ==
"rvc") {
3207 getTargetStreamer().emitDirectiveOptionRVC();
3208 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3212 if (Option ==
"norvc") {
3216 getTargetStreamer().emitDirectiveOptionNoRVC();
3217 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3218 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3222 if (Option ==
"pic") {
3226 getTargetStreamer().emitDirectiveOptionPIC();
3227 ParserOptions.IsPicEnabled =
true;
3231 if (Option ==
"nopic") {
3235 getTargetStreamer().emitDirectiveOptionNoPIC();
3236 ParserOptions.IsPicEnabled =
false;
3240 if (Option ==
"relax") {
3244 getTargetStreamer().emitDirectiveOptionRelax();
3245 setFeatureBits(RISCV::FeatureRelax,
"relax");
3249 if (Option ==
"norelax") {
3253 getTargetStreamer().emitDirectiveOptionNoRelax();
3254 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3260 "unknown option, expected 'push', 'pop', "
3261 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3262 "'exact', or 'noexact'");
3270bool RISCVAsmParser::parseDirectiveAttribute() {
3271 MCAsmParser &Parser = getParser();
3277 std::optional<unsigned>
Ret =
3280 return Error(TagLoc,
"attribute name not recognised: " + Name);
3284 const MCExpr *AttrExpr;
3291 if (check(!CE, TagLoc,
"expected numeric constant"))
3294 Tag =
CE->getValue();
3300 StringRef StringValue;
3301 int64_t IntegerValue = 0;
3302 bool IsIntegerValue =
true;
3307 IsIntegerValue =
false;
3310 if (IsIntegerValue) {
3311 const MCExpr *ValueExpr;
3317 return Error(ValueExprLoc,
"expected numeric constant");
3318 IntegerValue =
CE->getValue();
3331 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3333 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3336 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3340 getTargetStreamer().emitTextAttribute(
Tag, Result);
3348 .
Cases(
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s",
true)
3349 .
Cases(
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj",
3351 .
Cases(
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es",
3360bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3361 MCAsmParser &Parser = getParser();
3368 std::optional<int64_t>
Length;
3378 return Error(ErrorLoc,
3379 "instruction lengths must be a non-zero multiple of two");
3383 return Error(ErrorLoc,
3384 "instruction lengths over 64 bits are not supported");
3390 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3395 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3396 return Error(ErrorLoc,
3397 "instruction length does not match the encoding");
3400 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3403 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3406 if (!getSTI().hasFeature(RISCV::FeatureStdExtZca) &&
3407 (EncodingDerivedLength == 2))
3408 return Error(ErrorLoc,
"compressed instructions are not allowed");
3410 if (getParser().parseEOL(
"invalid operand for instruction")) {
3411 getParser().eatToEndOfStatement();
3419 Opcode = RISCV::Insn16;
3422 Opcode = RISCV::Insn32;
3425 Opcode = RISCV::Insn48;
3428 Opcode = RISCV::Insn64;
3434 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3436 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3441 return Error(ErrorLoc,
"invalid instruction format");
3443 std::string FormatName = (
".insn_" +
Format).str();
3445 ParseInstructionInfo
Info;
3460bool RISCVAsmParser::parseDirectiveVariantCC() {
3462 if (getParser().parseIdentifier(Name))
3463 return TokError(
"expected symbol name");
3466 getTargetStreamer().emitDirectiveVariantCC(
3471void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3474 const MCSubtargetInfo &STI = getSTI();
3475 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3478 ++RISCVNumInstrsCompressed;
3482void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3487 for (MCInst &Inst : Seq) {
3488 emitToStreamer(Out, Inst);
3492void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3493 const MCExpr *Symbol,
3495 unsigned SecondOpcode, SMLoc IDLoc,
3507 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3512 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3515 .addExpr(RefToLinkTmpLabel));
3518void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3528 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_PCREL_HI20,
3529 RISCV::ADDI, IDLoc, Out);
3532void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3542 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3543 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_GOT_HI20,
3544 SecondOpcode, IDLoc, Out);
3547void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3556 if (ParserOptions.IsPicEnabled)
3557 emitLoadGlobalAddress(Inst, IDLoc, Out);
3559 emitLoadLocalAddress(Inst, IDLoc, Out);
3562void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3572 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3573 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3574 SecondOpcode, IDLoc, Out);
3577void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3587 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3588 RISCV::ADDI, IDLoc, Out);
3591void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3592 SMLoc IDLoc, MCStreamer &Out,
3601 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3603 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3607 if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].
contains(TmpReg)) {
3608 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3609 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3613 emitAuipcInstPair(DestReg, TmpReg, Symbol, ELF::R_RISCV_PCREL_HI20, Opcode,
3617void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3618 int64_t Width, SMLoc IDLoc,
3627 const MCOperand &DestReg = Inst.
getOperand(0);
3628 const MCOperand &SourceReg = Inst.
getOperand(1);
3630 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3631 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3633 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3635 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3640 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3646void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
3653 emitToStreamer(Out, MCInstBuilder(Opcode)
3657 .addReg(MCRegister())
3659 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
3670 "The destination register should not be V0.");
3671 emitToStreamer(Out, MCInstBuilder(Opcode)
3677 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
3689 "The destination register should be V0.");
3691 "The temporary vector register should not be V0.");
3692 emitToStreamer(Out, MCInstBuilder(Opcode)
3696 .addReg(MCRegister())
3698 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3710 "The temporary vector register should not be V0.");
3711 emitToStreamer(Out, MCInstBuilder(Opcode)
3715 .addReg(MCRegister())
3717 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3722 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3727 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
3735bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
3737 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3740 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3741 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3742 "%tprel_add specifier");
3748bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
3750 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
3753 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3754 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
3755 "%tlsdesc_call specifier");
3761std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3762 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
3765std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3766 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3770std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3771 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3775bool RISCVAsmParser::validateInstruction(MCInst &Inst,
3779 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3780 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3783 if (DestReg == TempReg) {
3784 SMLoc Loc =
Operands.back()->getStartLoc();
3785 return Error(Loc,
"the temporary vector register cannot be the same as "
3786 "the destination register");
3790 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3791 Opcode == RISCV::TH_LWD) {
3796 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
3797 SMLoc Loc =
Operands[1]->getStartLoc();
3798 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
3802 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
3806 SMLoc Loc =
Operands[1]->getStartLoc();
3807 return Error(Loc,
"rs1 and rs2 must be different");
3811 const MCInstrDesc &MCID = MII.
get(Opcode);
3815 if (Opcode == RISCV::SF_VC_V_XVW || Opcode == RISCV::SF_VC_V_IVW ||
3816 Opcode == RISCV::SF_VC_V_FVW || Opcode == RISCV::SF_VC_V_VVW) {
3819 SMLoc VCIXDstLoc =
Operands[2]->getStartLoc();
3822 if (VCIXDst == VCIXRs1)
3823 return Error(VCIXDstLoc,
"the destination vector register group cannot"
3824 " overlap the source vector register group");
3828 if (VCIXDst == VCIXRs2)
3829 return Error(VCIXDstLoc,
"the destination vector register group cannot"
3830 " overlap the source vector register group");
3842 SMLoc Loc =
Operands[1]->getStartLoc();
3845 if (DestReg == CheckReg)
3846 return Error(Loc,
"the destination vector register group cannot overlap"
3847 " the source vector register group");
3851 if (DestReg == CheckReg)
3852 return Error(Loc,
"the destination vector register group cannot overlap"
3853 " the source vector register group");
3858 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM ||
3859 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM ||
3860 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM ||
3861 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM ||
3862 Opcode == RISCV::VMERGE_VXM)
3863 return Error(Loc,
"the destination vector register group cannot be V0");
3870 assert((CheckReg == RISCV::V0 || !CheckReg) &&
3871 "Unexpected register for mask operand");
3873 if (DestReg == CheckReg)
3874 return Error(Loc,
"the destination vector register group cannot overlap"
3875 " the mask register");
3880bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
3888 case RISCV::PseudoC_ADDI_NOP: {
3890 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
3896 case RISCV::PseudoLLAImm:
3897 case RISCV::PseudoLAImm:
3898 case RISCV::PseudoLI: {
3904 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
3916 emitLoadImm(
Reg, Imm, Out);
3919 case RISCV::PseudoLLA:
3920 emitLoadLocalAddress(Inst, IDLoc, Out);
3922 case RISCV::PseudoLGA:
3923 emitLoadGlobalAddress(Inst, IDLoc, Out);
3925 case RISCV::PseudoLA:
3926 emitLoadAddress(Inst, IDLoc, Out);
3928 case RISCV::PseudoLA_TLS_IE:
3929 emitLoadTLSIEAddress(Inst, IDLoc, Out);
3931 case RISCV::PseudoLA_TLS_GD:
3932 emitLoadTLSGDAddress(Inst, IDLoc, Out);
3934 case RISCV::PseudoLB:
3935 case RISCV::PseudoQC_E_LB:
3936 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
3938 case RISCV::PseudoLBU:
3939 case RISCV::PseudoQC_E_LBU:
3940 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
3942 case RISCV::PseudoLH:
3943 case RISCV::PseudoQC_E_LH:
3944 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
3946 case RISCV::PseudoLHU:
3947 case RISCV::PseudoQC_E_LHU:
3948 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
3950 case RISCV::PseudoLW:
3951 case RISCV::PseudoQC_E_LW:
3952 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
3954 case RISCV::PseudoLWU:
3955 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
3957 case RISCV::PseudoLD:
3958 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
3960 case RISCV::PseudoLD_RV32:
3961 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
3963 case RISCV::PseudoFLH:
3964 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
3966 case RISCV::PseudoFLW:
3967 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
3969 case RISCV::PseudoFLD:
3970 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
3972 case RISCV::PseudoFLQ:
3973 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
3975 case RISCV::PseudoSB:
3976 case RISCV::PseudoQC_E_SB:
3977 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
3979 case RISCV::PseudoSH:
3980 case RISCV::PseudoQC_E_SH:
3981 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
3983 case RISCV::PseudoSW:
3984 case RISCV::PseudoQC_E_SW:
3985 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
3987 case RISCV::PseudoSD:
3988 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
3990 case RISCV::PseudoSD_RV32:
3991 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
3993 case RISCV::PseudoFSH:
3994 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
3996 case RISCV::PseudoFSW:
3997 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
3999 case RISCV::PseudoFSD:
4000 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4002 case RISCV::PseudoFSQ:
4003 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4005 case RISCV::PseudoAddTPRel:
4006 if (checkPseudoAddTPRel(Inst,
Operands))
4009 case RISCV::PseudoTLSDESCCall:
4010 if (checkPseudoTLSDESCCall(Inst,
Operands))
4013 case RISCV::PseudoSEXT_B:
4014 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4016 case RISCV::PseudoSEXT_H:
4017 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4019 case RISCV::PseudoZEXT_H:
4020 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4022 case RISCV::PseudoZEXT_W:
4023 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4025 case RISCV::PseudoVMSGEU_VX:
4026 case RISCV::PseudoVMSGEU_VX_M:
4027 case RISCV::PseudoVMSGEU_VX_M_T:
4028 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4030 case RISCV::PseudoVMSGE_VX:
4031 case RISCV::PseudoVMSGE_VX_M:
4032 case RISCV::PseudoVMSGE_VX_M_T:
4033 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4035 case RISCV::PseudoVMSGE_VI:
4036 case RISCV::PseudoVMSLT_VI: {
4040 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4042 emitToStreamer(Out, MCInstBuilder(
Opc)
4050 case RISCV::PseudoVMSGEU_VI:
4051 case RISCV::PseudoVMSLTU_VI: {
4058 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4061 emitToStreamer(Out, MCInstBuilder(
Opc)
4069 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4072 emitToStreamer(Out, MCInstBuilder(
Opc)
4084 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")
Analysis containing CSE Info
static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, MCRegister &Reg, StringRef Name)
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
#define LLVM_EXTERNAL_VISIBILITY
mir Rename Register Operands
Promote Memory to Register
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
bool isValidInsnFormat(StringRef Format, const MCSubtargetInfo &STI)
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 convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg, unsigned Kind)
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")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
bool parseImmediate(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes)
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 MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
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
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specified operand constraint if it is present.
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.
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.
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.
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
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
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
char back() const
back - Get the last character in the string.
A switch()-like statement whose cases are string literals.
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, 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)
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)
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
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
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
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.