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"
220 return parseRegList(Operands,
true);
226 bool ExpectNegative =
false);
228 return parseZcmpStackAdj(Operands,
true);
231 bool parseOperand(
OperandVector &Operands, StringRef Mnemonic);
232 bool parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
233 bool parseDataExpr(
const MCExpr *&Res)
override;
235 bool parseDirectiveOption();
236 bool parseDirectiveAttribute();
237 bool parseDirectiveInsn(SMLoc L);
238 bool parseDirectiveVariantCC();
243 bool resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
244 bool FromOptionDirective);
246 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
247 if (!(getSTI().hasFeature(Feature))) {
248 MCSubtargetInfo &STI = copySTI();
254 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
258 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
259 if (getSTI().hasFeature(Feature)) {
260 MCSubtargetInfo &STI = copySTI();
261 setAvailableFeatures(
266 void pushFeatureBits() {
267 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
268 "These two stacks must be kept synchronized");
269 FeatureBitStack.push_back(getSTI().getFeatureBits());
270 ParserOptionsStack.push_back(ParserOptions);
273 bool popFeatureBits() {
274 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
275 "These two stacks must be kept synchronized");
276 if (FeatureBitStack.empty())
279 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
280 copySTI().setFeatureBits(FeatureBits);
281 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
283 ParserOptions = ParserOptionsStack.pop_back_val();
288 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
289 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
290 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
293 enum RISCVMatchResultTy :
unsigned {
294 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
295#define GET_OPERAND_DIAGNOSTIC_TYPES
296#include "RISCVGenAsmMatcher.inc"
297#undef GET_OPERAND_DIAGNOSTIC_TYPES
301 static bool isSymbolDiff(
const MCExpr *Expr);
303 RISCVAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
304 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
305 : MCTargetAsmParser(
Options, STI, MII) {
312 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
314 auto ABIName = StringRef(
Options.ABIName);
315 if (ABIName.ends_with(
"f") && !getSTI().hasFeature(RISCV::FeatureStdExtF)) {
316 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
317 "doesn't support the F instruction set extension (ignoring "
319 }
else if (ABIName.ends_with(
"d") &&
320 !getSTI().hasFeature(RISCV::FeatureStdExtD)) {
321 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
322 "doesn't support the D instruction set extension (ignoring "
335 getTargetStreamer().emitTargetAttributes(STI,
false);
401 MCRegister OffsetReg;
404 SMLoc StartLoc, EndLoc;
419 RISCVOperand(KindTy K) : Kind(
K) {}
422 RISCVOperand(
const RISCVOperand &o) : MCParsedAsmOperand() {
424 StartLoc =
o.StartLoc;
427 case KindTy::Register:
430 case KindTy::Expression:
433 case KindTy::FPImmediate:
439 case KindTy::SystemRegister:
451 case KindTy::RegList:
454 case KindTy::StackAdj:
455 StackAdj =
o.StackAdj;
463 bool isToken()
const override {
return Kind == KindTy::Token; }
464 bool isReg()
const override {
return Kind == KindTy::Register; }
465 bool isExpr()
const {
return Kind == KindTy::Expression; }
466 bool isV0Reg()
const {
467 return Kind == KindTy::Register &&
Reg.Reg == RISCV::V0;
469 bool isAnyReg()
const {
470 return Kind == KindTy::Register &&
471 (RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.Reg) ||
472 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg.Reg) ||
473 RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg.Reg));
475 bool isAnyRegC()
const {
476 return Kind == KindTy::Register &&
477 (RISCVMCRegisterClasses[RISCV::GPRCRegClassID].contains(
Reg.Reg) ||
478 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg.Reg));
480 bool isImm()
const override {
return isExpr(); }
481 bool isMem()
const override {
return false; }
482 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
483 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
484 bool isRegList()
const {
return Kind == KindTy::RegList; }
485 bool isRegListS0()
const {
486 return Kind == KindTy::RegList && RegList.Encoding !=
RISCVZC::RA;
488 bool isStackAdj()
const {
return Kind == KindTy::StackAdj; }
491 return Kind == KindTy::Register &&
492 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.Reg);
495 bool isGPRPair()
const {
496 return Kind == KindTy::Register &&
497 RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(
Reg.Reg);
500 bool isGPRPairC()
const {
501 return Kind == KindTy::Register &&
502 RISCVMCRegisterClasses[RISCV::GPRPairCRegClassID].contains(
Reg.Reg);
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.Reg);
516 bool isGPRF32()
const {
517 return Kind == KindTy::Register &&
518 RISCVMCRegisterClasses[RISCV::GPRF32RegClassID].contains(
Reg.Reg);
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 evaluateConstantExpr(
const MCExpr *Expr, int64_t &Imm) {
528 Imm =
CE->getValue();
537 template <
int N>
bool isBareSimmNLsb0()
const {
542 if (evaluateConstantExpr(
getExpr(), Imm))
543 return isShiftedInt<
N - 1, 1>(fixImmediateForRV32(Imm, isRV64Expr()));
546 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
552 template <
int N>
bool isBareSimmN()
const {
557 if (evaluateConstantExpr(
getExpr(), Imm))
558 return isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
561 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
567 bool isBareSymbol()
const {
570 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
574 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
578 bool isCallSymbol()
const {
581 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
585 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
589 bool isPseudoJumpSymbol()
const {
592 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
596 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
600 bool isTPRelAddSymbol()
const {
603 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
607 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
608 VK == ELF::R_RISCV_TPREL_ADD;
611 bool isTLSDESCCallSymbol()
const {
614 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
618 return RISCVAsmParser::classifySymbolRef(
getExpr(), 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 (evaluateConstantExpr(
getExpr(), Imm))
672 return RISCVAsmParser::isSymbolDiff(
getExpr());
675 bool isImmXLenLI_Restricted()
const {
679 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
681 return IsConstantImm &&
685 template <
unsigned N>
bool isUImm()
const {
689 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
693 template <
unsigned N,
unsigned S>
bool isUImmShifted()
const {
697 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
701 template <
class Pred>
bool isUImmPred(Pred p)
const {
705 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
706 return IsConstantImm &&
p(Imm);
709 bool isUImmLog2XLen()
const {
710 if (isExpr() && isRV64Expr())
715 bool isUImmLog2XLenNonZero()
const {
716 if (isExpr() && isRV64Expr())
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 (isExpr() && isRV64Expr())
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 = evaluateConstantExpr(
getExpr(), Imm);
798 return IsConstantImm &&
isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
801 template <
class Pred>
bool isSImmPred(Pred p)
const {
805 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
806 return IsConstantImm &&
p(fixImmediateForRV32(Imm, isRV64Expr()));
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 isSImm12()
const {
return isSImm<12>(); }
814 bool isSImm16()
const {
return isSImm<16>(); }
815 bool isSImm26()
const {
return isSImm<26>(); }
817 bool isSImm5NonZero()
const {
818 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<5>(Imm); });
821 bool isSImm6NonZero()
const {
822 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<6>(Imm); });
825 bool isCLUIImm()
const {
826 return isUImmPred([](int64_t Imm) {
827 return (
isUInt<5>(Imm) && Imm != 0) || (
Imm >= 0xfffe0 &&
Imm <= 0xfffff);
831 bool isUImm2Lsb0()
const {
return isUImmShifted<1, 1>(); }
833 bool isUImm5Lsb0()
const {
return isUImmShifted<4, 1>(); }
835 bool isUImm6Lsb0()
const {
return isUImmShifted<5, 1>(); }
837 bool isUImm7Lsb00()
const {
return isUImmShifted<5, 2>(); }
839 bool isUImm7Lsb000()
const {
return isUImmShifted<4, 3>(); }
841 bool isUImm8Lsb00()
const {
return isUImmShifted<6, 2>(); }
843 bool isUImm8Lsb000()
const {
return isUImmShifted<5, 3>(); }
845 bool isUImm9Lsb000()
const {
return isUImmShifted<6, 3>(); }
847 bool isUImm14Lsb00()
const {
return isUImmShifted<12, 2>(); }
849 bool isUImm10Lsb00NonZero()
const {
856 static int64_t fixImmediateForRV32(int64_t Imm,
bool IsRV64Imm) {
862 bool isSImm12LO()
const {
867 if (evaluateConstantExpr(
getExpr(), Imm))
868 return isInt<12>(fixImmediateForRV32(Imm, isRV64Expr()));
871 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
874 VK == ELF::R_RISCV_TLSDESC_ADD_LO12);
877 bool isSImm12Lsb00000()
const {
881 bool isSImm10Lsb0000NonZero()
const {
886 bool isSImm16NonZero()
const {
887 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<16>(Imm); });
890 bool isUImm16NonZero()
const {
891 return isUImmPred([](int64_t Imm) {
return isUInt<16>(Imm) &&
Imm != 0; });
894 bool isSImm20LI()
const {
899 if (evaluateConstantExpr(
getExpr(), Imm))
900 return isInt<20>(fixImmediateForRV32(Imm, isRV64Expr()));
903 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
907 bool isSImm8Unsigned()
const {
return isSImm<8>() || isUImm<8>(); }
908 bool isSImm10Unsigned()
const {
return isSImm<10>() || isUImm<10>(); }
910 bool isUImm20LUI()
const {
915 if (evaluateConstantExpr(
getExpr(), Imm))
919 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
920 (VK == ELF::R_RISCV_HI20 || VK == ELF::R_RISCV_TPREL_HI20);
923 bool isUImm20AUIPC()
const {
928 if (evaluateConstantExpr(
getExpr(), Imm))
932 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
934 VK == ELF::R_RISCV_TLS_GOT_HI20 || VK == ELF::R_RISCV_TLS_GD_HI20 ||
935 VK == ELF::R_RISCV_TLSDESC_HI20);
938 bool isImmZero()
const {
939 return isUImmPred([](int64_t Imm) {
return 0 ==
Imm; });
942 bool isImmThree()
const {
943 return isUImmPred([](int64_t Imm) {
return 3 ==
Imm; });
946 bool isImmFour()
const {
947 return isUImmPred([](int64_t Imm) {
return 4 ==
Imm; });
950 bool isImm5Zibi()
const {
952 [](int64_t Imm) {
return (Imm != 0 &&
isUInt<5>(Imm)) ||
Imm == -1; });
955 bool isSImm5Plus1()
const {
960 bool isSImm18()
const {
961 return isSImmPred([](int64_t Imm) {
return isInt<18>(Imm); });
964 bool isSImm18Lsb0()
const {
968 bool isSImm19Lsb00()
const {
972 bool isSImm20Lsb000()
const {
976 bool isSImm32Lsb0()
const {
981 SMLoc getStartLoc()
const override {
return StartLoc; }
983 SMLoc getEndLoc()
const override {
return EndLoc; }
986 bool isRV64Expr()
const {
987 assert(Kind == KindTy::Expression &&
"Invalid type access!");
991 MCRegister
getReg()
const override {
992 assert(Kind == KindTy::Register &&
"Invalid type access!");
996 StringRef getSysReg()
const {
997 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
998 return StringRef(SysReg.Data, SysReg.Length);
1001 const MCExpr *
getExpr()
const {
1002 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1006 uint64_t getFPConst()
const {
1007 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1012 assert(Kind == KindTy::Token &&
"Invalid type access!");
1016 unsigned getVType()
const {
1017 assert(Kind == KindTy::VType &&
"Invalid type access!");
1022 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1026 unsigned getFence()
const {
1027 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1031 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1040 case KindTy::Expression:
1043 OS <<
' ' << (Expr.IsRV64 ?
"rv64" :
"rv32") <<
'>';
1045 case KindTy::FPImmediate:
1046 OS <<
"<fpimm: " << FPImm.Val <<
">";
1048 case KindTy::Register:
1050 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1055 case KindTy::SystemRegister:
1056 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1065 roundingModeToString(getFRM());
1073 case KindTy::RegList:
1078 case KindTy::StackAdj:
1079 OS <<
"<stackadj: ";
1083 case KindTy::RegReg:
1084 OS <<
"<RegReg: BaseReg " <<
RegName(
RegReg.BaseReg) <<
" OffsetReg "
1090 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1091 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1098 static std::unique_ptr<RISCVOperand>
1099 createReg(MCRegister
Reg, SMLoc S, SMLoc
E,
bool IsGPRAsFPR =
false) {
1100 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1102 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1108 static std::unique_ptr<RISCVOperand> createExpr(
const MCExpr *Val, SMLoc S,
1109 SMLoc
E,
bool IsRV64) {
1110 auto Op = std::make_unique<RISCVOperand>(KindTy::Expression);
1111 Op->Expr.Expr = Val;
1112 Op->Expr.IsRV64 = IsRV64;
1118 static std::unique_ptr<RISCVOperand> createFPImm(uint64_t Val, SMLoc S) {
1119 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1120 Op->FPImm.Val = Val;
1126 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1127 unsigned Encoding) {
1128 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1129 Op->SysReg.Data = Str.data();
1130 Op->SysReg.Length = Str.size();
1137 static std::unique_ptr<RISCVOperand>
1139 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1146 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val, SMLoc S) {
1147 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1148 Op->Fence.Val = Val;
1154 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI, SMLoc S) {
1155 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1156 Op->VType.Val = VTypeI;
1162 static std::unique_ptr<RISCVOperand> createRegList(
unsigned RlistEncode,
1164 auto Op = std::make_unique<RISCVOperand>(KindTy::RegList);
1170 static std::unique_ptr<RISCVOperand>
1171 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {
1172 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1174 Op->RegReg.OffsetReg = OffsetReg;
1180 static std::unique_ptr<RISCVOperand> createStackAdj(
unsigned StackAdj, SMLoc S) {
1181 auto Op = std::make_unique<RISCVOperand>(KindTy::StackAdj);
1182 Op->StackAdj.Val = StackAdj;
1187 static void addExpr(MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1188 assert(Expr &&
"Expr shouldn't be null!");
1190 bool IsConstant = evaluateConstantExpr(Expr, Imm);
1200 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1201 assert(
N == 1 &&
"Invalid number of operands!");
1205 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1206 assert(
N == 1 &&
"Invalid number of operands!");
1207 addExpr(Inst,
getExpr(), isRV64Expr());
1210 void addSImm8UnsignedOperands(MCInst &Inst,
unsigned N)
const {
1211 assert(
N == 1 &&
"Invalid number of operands!");
1218 void addSImm10UnsignedOperands(MCInst &Inst,
unsigned N)
const {
1219 assert(
N == 1 &&
"Invalid number of operands!");
1226 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
1227 assert(
N == 1 &&
"Invalid number of operands!");
1229 addExpr(Inst,
getExpr(), isRV64Expr());
1234 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1238 void addFenceArgOperands(MCInst &Inst,
unsigned N)
const {
1239 assert(
N == 1 &&
"Invalid number of operands!");
1243 void addCSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
1244 assert(
N == 1 &&
"Invalid number of operands!");
1251 void addVTypeIOperands(MCInst &Inst,
unsigned N)
const {
1252 assert(
N == 1 &&
"Invalid number of operands!");
1254 if (Kind == KindTy::Expression) {
1255 [[maybe_unused]]
bool IsConstantImm =
1256 evaluateConstantExpr(
getExpr(), Imm);
1257 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1264 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1265 assert(
N == 1 &&
"Invalid number of operands!");
1269 void addRegRegOperands(MCInst &Inst,
unsigned N)
const {
1270 assert(
N == 2 &&
"Invalid number of operands!");
1275 void addStackAdjOperands(MCInst &Inst,
unsigned N)
const {
1276 assert(
N == 1 &&
"Invalid number of operands!");
1280 void addFRMArgOperands(MCInst &Inst,
unsigned N)
const {
1281 assert(
N == 1 &&
"Invalid number of operands!");
1287#define GET_REGISTER_MATCHER
1288#define GET_SUBTARGET_FEATURE_NAME
1289#define GET_MATCHER_IMPLEMENTATION
1290#define GET_MNEMONIC_SPELL_CHECKER
1291#include "RISCVGenAsmMatcher.inc"
1294 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1295 return Reg - RISCV::F0_D + RISCV::F0_H;
1299 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1300 return Reg - RISCV::F0_D + RISCV::F0_F;
1304 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1305 return Reg - RISCV::F0_D + RISCV::F0_Q;
1310 unsigned RegClassID;
1311 if (Kind == MCK_VRM2)
1312 RegClassID = RISCV::VRM2RegClassID;
1313 else if (Kind == MCK_VRM4)
1314 RegClassID = RISCV::VRM4RegClassID;
1315 else if (Kind == MCK_VRM8)
1316 RegClassID = RISCV::VRM8RegClassID;
1320 &RISCVMCRegisterClasses[RegClassID]);
1324 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1325 return Reg - RISCV::F0_D + RISCV::F0_Q2;
1330 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1332 return Match_InvalidOperand;
1334 MCRegister
Reg =
Op.getReg();
1336 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg);
1338 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg);
1339 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg);
1341 if (IsRegFPR64 && Kind == MCK_FPR256) {
1343 return Match_Success;
1345 if (IsRegFPR64 && Kind == MCK_FPR128) {
1347 return Match_Success;
1351 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1352 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1354 return Match_Success;
1358 if (IsRegFPR64 && Kind == MCK_FPR16) {
1360 return Match_Success;
1362 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1363 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_H;
1364 return Match_Success;
1366 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1367 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_W;
1368 return Match_Success;
1375 if (RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg) &&
1376 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1378 return Match_Success;
1382 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1385 return Match_InvalidOperand;
1386 return Match_Success;
1388 return Match_InvalidOperand;
1391bool RISCVAsmParser::generateImmOutOfRangeError(
1392 SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
1393 const Twine &Msg =
"immediate must be an integer in the range") {
1394 return Error(ErrorLoc, Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]");
1397bool RISCVAsmParser::generateImmOutOfRangeError(
1399 const Twine &Msg =
"immediate must be an integer in the range") {
1400 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1401 return generateImmOutOfRangeError(ErrorLoc,
Lower,
Upper, Msg);
1404bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1407 uint64_t &ErrorInfo,
1408 bool MatchingInlineAsm) {
1410 FeatureBitset MissingFeatures;
1412 auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
1418 if (validateInstruction(Inst, Operands))
1420 return processInstruction(Inst, IDLoc, Operands, Out);
1421 case Match_MissingFeature: {
1422 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1423 bool FirstFeature =
true;
1424 std::string Msg =
"instruction requires the following:";
1425 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1426 if (MissingFeatures[i]) {
1427 Msg += FirstFeature ?
" " :
", ";
1429 FirstFeature =
false;
1432 return Error(IDLoc, Msg);
1434 case Match_MnemonicFail: {
1435 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1436 std::string Suggestion = RISCVMnemonicSpellCheck(
1437 ((RISCVOperand &)*Operands[0]).
getToken(), FBS, 0);
1438 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1440 case Match_InvalidOperand: {
1441 SMLoc ErrorLoc = IDLoc;
1442 if (ErrorInfo != ~0ULL) {
1443 if (ErrorInfo >= Operands.
size())
1444 return Error(ErrorLoc,
"too few operands for instruction");
1446 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1447 if (ErrorLoc == SMLoc())
1450 return Error(ErrorLoc,
"invalid operand for instruction");
1457 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1458 SMLoc ErrorLoc = IDLoc;
1459 if (ErrorInfo != ~0ULL && ErrorInfo >= Operands.
size())
1460 return Error(ErrorLoc,
"too few operands for instruction");
1466 case Match_InvalidImmXLenLI:
1468 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1469 return Error(ErrorLoc,
"operand must be a constant 64-bit integer");
1471 return generateImmOutOfRangeError(Operands, ErrorInfo,
1472 std::numeric_limits<int32_t>::min(),
1473 std::numeric_limits<uint32_t>::max());
1474 case Match_InvalidImmXLenLI_Restricted:
1476 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1477 return Error(ErrorLoc,
"operand either must be a constant 64-bit integer "
1478 "or a bare symbol name");
1480 return generateImmOutOfRangeError(
1481 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1482 std::numeric_limits<uint32_t>::max(),
1483 "operand either must be a bare symbol name or an immediate integer in "
1485 case Match_InvalidUImmLog2XLen:
1487 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1488 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1489 case Match_InvalidUImmLog2XLenNonZero:
1491 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
1492 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1493 case Match_InvalidUImm1:
1494 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
1495 case Match_InvalidUImm2:
1496 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
1497 case Match_InvalidUImm2Lsb0:
1498 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 2,
1499 "immediate must be one of");
1500 case Match_InvalidUImm3:
1501 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
1502 case Match_InvalidUImm4:
1503 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
1504 case Match_InvalidUImm5:
1505 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1506 case Match_InvalidUImm5NonZero:
1507 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1508 case Match_InvalidUImm5GT3:
1509 return generateImmOutOfRangeError(Operands, ErrorInfo, 4, (1 << 5) - 1);
1510 case Match_InvalidUImm5Plus1:
1511 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));
1512 case Match_InvalidUImm5GE6Plus1:
1513 return generateImmOutOfRangeError(Operands, ErrorInfo, 6, (1 << 5));
1514 case Match_InvalidUImm5Slist: {
1515 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1516 return Error(ErrorLoc,
1517 "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31");
1519 case Match_InvalidUImm6:
1520 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1521 case Match_InvalidUImm7:
1522 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
1523 case Match_InvalidUImm8:
1524 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
1525 case Match_InvalidUImm8GE32:
1526 return generateImmOutOfRangeError(Operands, ErrorInfo, 32, (1 << 8) - 1);
1527 case Match_InvalidSImm5:
1528 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4),
1530 case Match_InvalidSImm5NonZero:
1531 return generateImmOutOfRangeError(
1532 Operands, ErrorInfo, -(1 << 4), (1 << 4) - 1,
1533 "immediate must be non-zero in the range");
1534 case Match_InvalidSImm6:
1535 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
1537 case Match_InvalidSImm6NonZero:
1538 return generateImmOutOfRangeError(
1539 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
1540 "immediate must be non-zero in the range");
1541 case Match_InvalidCLUIImm:
1542 return generateImmOutOfRangeError(
1543 Operands, ErrorInfo, 1, (1 << 5) - 1,
1544 "immediate must be in [0xfffe0, 0xfffff] or");
1545 case Match_InvalidUImm5Lsb0:
1546 return generateImmOutOfRangeError(
1547 Operands, ErrorInfo, 0, (1 << 5) - 2,
1548 "immediate must be a multiple of 2 bytes in the range");
1549 case Match_InvalidUImm6Lsb0:
1550 return generateImmOutOfRangeError(
1551 Operands, ErrorInfo, 0, (1 << 6) - 2,
1552 "immediate must be a multiple of 2 bytes in the range");
1553 case Match_InvalidUImm7Lsb00:
1554 return generateImmOutOfRangeError(
1555 Operands, ErrorInfo, 0, (1 << 7) - 4,
1556 "immediate must be a multiple of 4 bytes in the range");
1557 case Match_InvalidUImm8Lsb00:
1558 return generateImmOutOfRangeError(
1559 Operands, ErrorInfo, 0, (1 << 8) - 4,
1560 "immediate must be a multiple of 4 bytes in the range");
1561 case Match_InvalidUImm8Lsb000:
1562 return generateImmOutOfRangeError(
1563 Operands, ErrorInfo, 0, (1 << 8) - 8,
1564 "immediate must be a multiple of 8 bytes in the range");
1565 case Match_InvalidUImm9:
1566 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 9) - 1,
1567 "immediate offset must be in the range");
1568 case Match_InvalidBareSImm9Lsb0:
1569 return generateImmOutOfRangeError(
1570 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
1571 "immediate must be a multiple of 2 bytes in the range");
1572 case Match_InvalidUImm9Lsb000:
1573 return generateImmOutOfRangeError(
1574 Operands, ErrorInfo, 0, (1 << 9) - 8,
1575 "immediate must be a multiple of 8 bytes in the range");
1576 case Match_InvalidSImm8Unsigned:
1577 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
1579 case Match_InvalidSImm10:
1580 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
1582 case Match_InvalidSImm10Unsigned:
1583 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
1585 case Match_InvalidUImm10Lsb00NonZero:
1586 return generateImmOutOfRangeError(
1587 Operands, ErrorInfo, 4, (1 << 10) - 4,
1588 "immediate must be a multiple of 4 bytes in the range");
1589 case Match_InvalidSImm10Lsb0000NonZero:
1590 return generateImmOutOfRangeError(
1591 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
1592 "immediate must be a multiple of 16 bytes and non-zero in the range");
1593 case Match_InvalidSImm11:
1594 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 10),
1596 case Match_InvalidBareSImm11Lsb0:
1597 return generateImmOutOfRangeError(
1598 Operands, ErrorInfo, -(1 << 10), (1 << 10) - 2,
1599 "immediate must be a multiple of 2 bytes in the range");
1600 case Match_InvalidUImm10:
1601 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 10) - 1);
1602 case Match_InvalidUImm11:
1603 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
1604 case Match_InvalidUImm14Lsb00:
1605 return generateImmOutOfRangeError(
1606 Operands, ErrorInfo, 0, (1 << 14) - 4,
1607 "immediate must be a multiple of 4 bytes in the range");
1608 case Match_InvalidUImm16NonZero:
1609 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16) - 1);
1610 case Match_InvalidSImm12:
1611 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11),
1613 case Match_InvalidSImm12LO:
1614 return generateImmOutOfRangeError(
1615 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
1616 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo specifier or an "
1617 "integer in the range");
1618 case Match_InvalidBareSImm12Lsb0:
1619 return generateImmOutOfRangeError(
1620 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
1621 "immediate must be a multiple of 2 bytes in the range");
1622 case Match_InvalidSImm12Lsb00000:
1623 return generateImmOutOfRangeError(
1624 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 32,
1625 "immediate must be a multiple of 32 bytes in the range");
1626 case Match_InvalidBareSImm13Lsb0:
1627 return generateImmOutOfRangeError(
1628 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
1629 "immediate must be a multiple of 2 bytes in the range");
1630 case Match_InvalidSImm16:
1631 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 15),
1633 case Match_InvalidSImm16NonZero:
1634 return generateImmOutOfRangeError(
1635 Operands, ErrorInfo, -(1 << 15), (1 << 15) - 1,
1636 "immediate must be non-zero in the range");
1637 case Match_InvalidSImm20LI:
1638 return generateImmOutOfRangeError(
1639 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 1,
1640 "operand must be a symbol with a %qc.abs20 specifier or an integer "
1642 case Match_InvalidUImm20LUI:
1643 return generateImmOutOfRangeError(
1644 Operands, ErrorInfo, 0, (1 << 20) - 1,
1645 "operand must be a symbol with "
1646 "%hi/%tprel_hi specifier or an integer in "
1648 case Match_InvalidUImm20:
1649 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1);
1650 case Match_InvalidUImm20AUIPC:
1651 return generateImmOutOfRangeError(
1652 Operands, ErrorInfo, 0, (1 << 20) - 1,
1653 "operand must be a symbol with a "
1654 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
1656 "an integer in the range");
1657 case Match_InvalidBareSImm21Lsb0:
1658 return generateImmOutOfRangeError(
1659 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
1660 "immediate must be a multiple of 2 bytes in the range");
1661 case Match_InvalidCSRSystemRegister: {
1662 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1,
1663 "operand must be a valid system register "
1664 "name or an integer in the range");
1666 case Match_InvalidImm5Zibi:
1667 return generateImmOutOfRangeError(
1668 Operands, ErrorInfo, -1, (1 << 5) - 1,
1669 "immediate must be non-zero in the range");
1670 case Match_InvalidVTypeI: {
1671 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1672 return generateVTypeError(ErrorLoc);
1674 case Match_InvalidSImm5Plus1: {
1675 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1,
1677 "immediate must be in the range");
1679 case Match_InvalidSImm18:
1680 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 17),
1682 case Match_InvalidSImm18Lsb0:
1683 return generateImmOutOfRangeError(
1684 Operands, ErrorInfo, -(1 << 17), (1 << 17) - 2,
1685 "immediate must be a multiple of 2 bytes in the range");
1686 case Match_InvalidSImm19Lsb00:
1687 return generateImmOutOfRangeError(
1688 Operands, ErrorInfo, -(1 << 18), (1 << 18) - 4,
1689 "immediate must be a multiple of 4 bytes in the range");
1690 case Match_InvalidSImm20Lsb000:
1691 return generateImmOutOfRangeError(
1692 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 8,
1693 "immediate must be a multiple of 8 bytes in the range");
1694 case Match_InvalidSImm26:
1695 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 25),
1698 case Match_InvalidBareSymbolQC_E_LI:
1701 case Match_InvalidBareSImm32:
1702 return generateImmOutOfRangeError(Operands, ErrorInfo,
1703 std::numeric_limits<int32_t>::min(),
1704 std::numeric_limits<uint32_t>::max());
1705 case Match_InvalidBareSImm32Lsb0:
1706 return generateImmOutOfRangeError(
1707 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1708 std::numeric_limits<int32_t>::max() - 1,
1709 "operand must be a multiple of 2 bytes in the range");
1710 case Match_InvalidRnumArg: {
1711 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10);
1713 case Match_InvalidStackAdj: {
1714 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1717 "stack adjustment is invalid for this instruction and register list");
1721 if (
const char *MatchDiag = getMatchKindDiag((RISCVMatchResultTy)Result)) {
1722 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1723 return Error(ErrorLoc, MatchDiag);
1733MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name)
const {
1742 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1743 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1744 static_assert(RISCV::F0_D < RISCV::F0_Q,
"FPR matching must be updated");
1747 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1752bool RISCVAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1754 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1755 return Error(StartLoc,
"invalid register name");
1759ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1761 const AsmToken &Tok = getParser().getTok();
1764 StringRef
Name = getLexer().getTok().getIdentifier();
1774ParseStatus RISCVAsmParser::parseRegister(
OperandVector &Operands,
1776 SMLoc FirstS = getLoc();
1777 bool HadParens =
false;
1784 size_t ReadCount = getLexer().peekTokens(Buf);
1787 LParen = getParser().getTok();
1792 switch (getLexer().getKind()) {
1795 getLexer().UnLex(LParen);
1798 StringRef
Name = getLexer().getTok().getIdentifier();
1803 getLexer().UnLex(LParen);
1807 Operands.
push_back(RISCVOperand::createToken(
"(", FirstS));
1809 SMLoc
E = getTok().getEndLoc();
1816 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
1822ParseStatus RISCVAsmParser::parseInsnDirectiveOpcode(
OperandVector &Operands) {
1827 switch (getLexer().getKind()) {
1837 if (getParser().parseExpression(Res,
E))
1842 int64_t
Imm =
CE->getValue();
1844 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1853 if (getParser().parseIdentifier(Identifier))
1856 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1859 "Unexpected opcode");
1862 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1872 return generateImmOutOfRangeError(
1874 "opcode must be a valid opcode name or an immediate in the range");
1877ParseStatus RISCVAsmParser::parseInsnCDirectiveOpcode(
OperandVector &Operands) {
1882 switch (getLexer().getKind()) {
1892 if (getParser().parseExpression(Res,
E))
1897 int64_t
Imm =
CE->getValue();
1898 if (Imm >= 0 && Imm <= 2) {
1899 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1908 if (getParser().parseIdentifier(Identifier))
1912 if (Identifier ==
"C0")
1914 else if (Identifier ==
"C1")
1916 else if (Identifier ==
"C2")
1923 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1932 return generateImmOutOfRangeError(
1934 "opcode must be a valid opcode name or an immediate in the range");
1937ParseStatus RISCVAsmParser::parseCSRSystemRegister(
OperandVector &Operands) {
1941 auto SysRegFromConstantInt = [
this](
const MCExpr *
E, SMLoc S) {
1943 int64_t
Imm =
CE->getValue();
1945 auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
1949 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
1952 return RISCVOperand::createSysReg(
Reg.Name, S, Imm);
1956 return RISCVOperand::createSysReg(
"", S, Imm);
1959 return std::unique_ptr<RISCVOperand>();
1962 switch (getLexer().getKind()) {
1972 if (getParser().parseExpression(Res))
1975 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
1980 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1984 if (getParser().parseIdentifier(Identifier))
1987 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1990 if (SysReg->IsDeprecatedName) {
1992 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
1994 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
1996 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
2002 const auto &FeatureBits = getSTI().getFeatureBits();
2003 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
2005 return SysReg->FeaturesRequired[Feature.Value];
2007 auto ErrorMsg = std::string(
"system register '") + SysReg->Name +
"' ";
2008 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
2009 ErrorMsg +=
"is RV32 only";
2011 ErrorMsg +=
" and ";
2015 "requires '" + std::string(Feature->Key) +
"' to be enabled";
2018 return Error(S, ErrorMsg);
2021 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
2036 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2037 "operand must be a valid system register "
2038 "name or an integer in the range");
2042 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2049ParseStatus RISCVAsmParser::parseFPImm(
OperandVector &Operands) {
2054 StringRef
Identifier = getTok().getIdentifier();
2055 if (
Identifier.compare_insensitive(
"inf") == 0) {
2058 getTok().getEndLoc(), isRV64()));
2059 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2062 getTok().getEndLoc(), isRV64()));
2063 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2066 getTok().getEndLoc(), isRV64()));
2068 return TokError(
"invalid floating point literal");
2079 const AsmToken &Tok = getTok();
2081 return TokError(
"invalid floating point immediate");
2084 APFloat RealVal(APFloat::IEEEdouble());
2086 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2088 return TokError(
"invalid floating point representation");
2091 RealVal.changeSign();
2093 Operands.
push_back(RISCVOperand::createFPImm(
2094 RealVal.bitcastToAPInt().getZExtValue(), S));
2101ParseStatus RISCVAsmParser::parseExpression(
OperandVector &Operands) {
2106 switch (getLexer().getKind()) {
2118 if (getParser().parseExpression(Res,
E))
2122 return parseOperandWithSpecifier(Operands);
2125 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2129ParseStatus RISCVAsmParser::parseOperandWithSpecifier(
OperandVector &Operands) {
2135 const MCExpr *Expr =
nullptr;
2136 bool Failed = parseExprWithSpecifier(Expr,
E);
2138 Operands.
push_back(RISCVOperand::createExpr(Expr, S,
E, isRV64()));
2142bool RISCVAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
2143 SMLoc Loc = getLoc();
2145 return TokError(
"expected '%' relocation specifier");
2146 StringRef
Identifier = getParser().getTok().getIdentifier();
2149 return TokError(
"invalid relocation specifier");
2155 const MCExpr *SubExpr;
2156 if (getParser().parseParenExpression(SubExpr,
E))
2163bool RISCVAsmParser::parseDataExpr(
const MCExpr *&Res) {
2166 return parseExprWithSpecifier(Res,
E);
2167 return getParser().parseExpression(Res);
2170ParseStatus RISCVAsmParser::parseBareSymbol(
OperandVector &Operands) {
2178 AsmToken Tok = getLexer().getTok();
2180 if (getParser().parseIdentifier(Identifier))
2190 getLexer().UnLex(Tok);
2198 switch (getLexer().getKind()) {
2200 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2213 if (getParser().parseExpression(Expr,
E))
2216 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2220ParseStatus RISCVAsmParser::parseCallSymbol(
OperandVector &Operands) {
2226 std::string
Identifier(getTok().getIdentifier());
2232 SMLoc Loc = getLoc();
2233 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2234 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2248 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2252ParseStatus RISCVAsmParser::parsePseudoJumpSymbol(
OperandVector &Operands) {
2257 if (getParser().parseExpression(Res,
E))
2260 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef)
2261 return Error(S,
"operand must be a valid jump target");
2264 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2268ParseStatus RISCVAsmParser::parseJALOffset(
OperandVector &Operands) {
2282 return parseExpression(Operands);
2285bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2286 unsigned &Sew,
unsigned &Lmul,
2287 bool &Fractional,
bool &TailAgnostic,
2288 bool &MaskAgnostic,
bool &AltFmt) {
2293 if (State < VTypeState::SeenSew &&
Identifier.consume_front(
"e")) {
2295 if (Identifier ==
"16alt") {
2298 }
else if (Identifier ==
"8alt") {
2308 State = VTypeState::SeenSew;
2312 if (State < VTypeState::SeenLmul &&
Identifier.consume_front(
"m")) {
2315 if (Identifier ==
"a" || Identifier ==
"u") {
2317 State = VTypeState::SeenMaskPolicy;
2328 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2329 unsigned MinLMUL = ELEN / 8;
2332 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2333 Twine(MinLMUL) +
" is reserved");
2336 State = VTypeState::SeenLmul;
2340 if (State < VTypeState::SeenTailPolicy &&
Identifier.starts_with(
"t")) {
2341 if (Identifier ==
"ta")
2342 TailAgnostic =
true;
2343 else if (Identifier ==
"tu")
2344 TailAgnostic =
false;
2348 State = VTypeState::SeenTailPolicy;
2352 if (State < VTypeState::SeenMaskPolicy &&
Identifier.starts_with(
"m")) {
2353 if (Identifier ==
"ma")
2354 MaskAgnostic =
true;
2355 else if (Identifier ==
"mu")
2356 MaskAgnostic =
false;
2360 State = VTypeState::SeenMaskPolicy;
2367ParseStatus RISCVAsmParser::parseVTypeI(
OperandVector &Operands) {
2373 bool Fractional =
false;
2374 bool TailAgnostic =
false;
2375 bool MaskAgnostic =
false;
2378 VTypeState State = VTypeState::SeenNothingYet;
2380 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2381 MaskAgnostic, AltFmt)) {
2383 if (State == VTypeState::SeenNothingYet)
2392 State == VTypeState::SeenNothingYet)
2393 return generateVTypeError(S);
2397 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2398 unsigned MaxSEW = ELEN / Lmul;
2400 if (MaxSEW >= 8 && Sew > MaxSEW)
2401 Warning(S,
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2402 " and LMUL == mf" + Twine(Lmul) +
2403 " may not be compatible with all RVV implementations");
2408 Operands.
push_back(RISCVOperand::createVType(VTypeI, S));
2412bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2413 if (STI->
hasFeature(RISCV::FeatureStdExtZvfbfa) ||
2414 STI->
hasFeature(RISCV::FeatureStdExtZvfofp8min) ||
2415 STI->
hasFeature(RISCV::FeatureVendorXSfvfbfexp16e))
2419 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2423 "e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2426ParseStatus RISCVAsmParser::parseXSfmmVType(
OperandVector &Operands) {
2443 if (Identifier !=
"16alt")
2472 Operands.
push_back(RISCVOperand::createVType(
2478 return generateXSfmmVTypeError(S);
2481bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
2482 return Error(ErrorLoc,
"operand must be e[8|16|16alt|32|64],w[1|2|4]");
2485ParseStatus RISCVAsmParser::parseMaskReg(
OperandVector &Operands) {
2489 StringRef
Name = getLexer().getTok().getIdentifier();
2490 if (!
Name.consume_back(
".t"))
2491 return Error(getLoc(),
"expected '.t' suffix");
2496 if (
Reg != RISCV::V0)
2499 SMLoc
E = getTok().getEndLoc();
2505ParseStatus RISCVAsmParser::parseGPRAsFPR64(
OperandVector &Operands) {
2506 if (!isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2509 return parseGPRAsFPR(Operands);
2512ParseStatus RISCVAsmParser::parseGPRAsFPR(
OperandVector &Operands) {
2516 StringRef
Name = getLexer().getTok().getIdentifier();
2522 SMLoc
E = getTok().getEndLoc();
2524 Operands.
push_back(RISCVOperand::createReg(
2525 Reg, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2529ParseStatus RISCVAsmParser::parseGPRPairAsFPR64(
OperandVector &Operands) {
2530 if (isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2536 StringRef
Name = getLexer().getTok().getIdentifier();
2542 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2545 if ((
Reg - RISCV::X0) & 1) {
2548 if (getSTI().hasFeature(RISCV::FeatureStdExtZfinx))
2549 return TokError(
"double precision floating point operands must use even "
2550 "numbered X register");
2555 SMLoc
E = getTok().getEndLoc();
2558 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2560 Reg, RISCV::sub_gpr_even,
2561 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2562 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2566template <
bool IsRV64>
2567ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands) {
2568 return parseGPRPair(Operands, IsRV64);
2571ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands,
2578 if (!IsRV64Inst && isRV64())
2584 StringRef
Name = getLexer().getTok().getIdentifier();
2590 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2593 if ((
Reg - RISCV::X0) & 1)
2594 return TokError(
"register must be even");
2597 SMLoc
E = getTok().getEndLoc();
2600 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2602 Reg, RISCV::sub_gpr_even,
2603 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2604 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E));
2608ParseStatus RISCVAsmParser::parseFRMArg(
OperandVector &Operands) {
2611 "operand must be a valid floating point rounding mode mnemonic");
2613 StringRef Str = getLexer().getTok().getIdentifier();
2618 "operand must be a valid floating point rounding mode mnemonic");
2620 Operands.
push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2625ParseStatus RISCVAsmParser::parseFenceArg(
OperandVector &Operands) {
2626 const AsmToken &Tok = getLexer().getTok();
2632 Operands.
push_back(RISCVOperand::createFenceArg(0, getLoc()));
2646 for (
char c : Str) {
2675 Operands.
push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2681 return TokError(
"operand must be formed of letters selected in-order from "
2685ParseStatus RISCVAsmParser::parseMemOpBaseReg(
OperandVector &Operands) {
2688 Operands.
push_back(RISCVOperand::createToken(
"(", getLoc()));
2690 if (!parseRegister(Operands).isSuccess())
2691 return Error(getLoc(),
"expected register");
2695 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
2700ParseStatus RISCVAsmParser::parseZeroOffsetMemOp(
OperandVector &Operands) {
2719 std::unique_ptr<RISCVOperand> OptionalImmOp;
2726 SMLoc ImmStart = getLoc();
2727 if (getParser().parseIntToken(ImmVal,
2728 "expected '(' or optional integer offset"))
2733 SMLoc ImmEnd = getLoc();
2736 ImmStart, ImmEnd, isRV64());
2740 OptionalImmOp ?
"expected '(' after optional integer offset"
2741 :
"expected '(' or optional integer offset"))
2744 if (!parseRegister(Operands).isSuccess())
2745 return Error(getLoc(),
"expected register");
2751 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2753 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2754 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2759ParseStatus RISCVAsmParser::parseRegReg(
OperandVector &Operands) {
2765 StringRef OffsetRegName = getLexer().getTok().getIdentifier();
2768 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(OffsetReg))
2769 return Error(getLoc(),
"expected GPR register");
2776 return Error(getLoc(),
"expected GPR register");
2778 StringRef BaseRegName = getLexer().getTok().getIdentifier();
2781 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(BaseReg))
2782 return Error(getLoc(),
"expected GPR register");
2788 Operands.
push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));
2800ParseStatus RISCVAsmParser::parseRegList(
OperandVector &Operands,
2801 bool MustIncludeS0) {
2813 return Error(getLoc(),
"invalid register");
2815 StringRef
RegName = getTok().getIdentifier();
2818 return Error(getLoc(),
"invalid register");
2821 UsesXRegs =
RegName[0] ==
'x';
2822 if (
Reg != RISCV::X1)
2823 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2824 }
else if (RegEnd == RISCV::X1) {
2825 if (
Reg != RISCV::X8 || (UsesXRegs != (
RegName[0] ==
'x')))
2826 return Error(getLoc(), Twine(
"register must be '") +
2827 (UsesXRegs ?
"x8" :
"s0") +
"'");
2828 }
else if (RegEnd == RISCV::X9 && UsesXRegs) {
2829 if (
Reg != RISCV::X18 || (
RegName[0] !=
'x'))
2830 return Error(getLoc(),
"register must be 'x18'");
2832 return Error(getLoc(),
"too many register ranges");
2839 SMLoc MinusLoc = getLoc();
2841 if (RegEnd == RISCV::X1)
2842 return Error(MinusLoc, Twine(
"register '") + (UsesXRegs ?
"x1" :
"ra") +
2843 "' cannot start a multiple register range");
2846 return Error(getLoc(),
"invalid register");
2848 StringRef
RegName = getTok().getIdentifier();
2851 return Error(getLoc(),
"invalid register");
2853 if (RegEnd == RISCV::X8) {
2854 if ((
Reg != RISCV::X9 &&
2856 (UsesXRegs != (
RegName[0] ==
'x'))) {
2858 return Error(getLoc(),
"register must be 'x9'");
2859 return Error(getLoc(),
"register must be in the range 's1' to 's11'");
2861 }
else if (RegEnd == RISCV::X18) {
2863 return Error(getLoc(),
2864 "register must be in the range 'x19' to 'x27'");
2877 if (RegEnd == RISCV::X26)
2878 return Error(S,
"invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "
2879 "x18-x26}' is not supported");
2885 return Error(S,
"register list must include 's0' or 'x8'");
2887 Operands.
push_back(RISCVOperand::createRegList(Encode, S));
2892ParseStatus RISCVAsmParser::parseZcmpStackAdj(
OperandVector &Operands,
2893 bool ExpectNegative) {
2902 auto *RegListOp =
static_cast<RISCVOperand *
>(Operands.
back().
get());
2903 if (!RegListOp->isRegList())
2906 unsigned RlistEncode = RegListOp->RegList.Encoding;
2910 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||
2911 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {
2912 int64_t
Lower = StackAdjBase;
2913 int64_t
Upper = StackAdjBase + 48;
2914 if (ExpectNegative) {
2919 return generateImmOutOfRangeError(S,
Lower,
Upper,
2920 "stack adjustment for register list must "
2921 "be a multiple of 16 bytes in the range");
2925 Operands.
push_back(RISCVOperand::createStackAdj(StackAdj, S));
2933bool RISCVAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
2937 MatchOperandParserImpl(Operands, Mnemonic,
true);
2944 if (parseRegister(Operands,
true).isSuccess())
2948 if (parseExpression(Operands).isSuccess()) {
2951 return !parseMemOpBaseReg(Operands).isSuccess();
2956 Error(getLoc(),
"unknown operand");
2960bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &Info,
2961 StringRef Name, SMLoc NameLoc,
2967 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
2971 Operands.
push_back(RISCVOperand::createToken(Name, NameLoc));
2980 if (parseOperand(Operands, Name))
2986 if (parseOperand(Operands, Name))
2990 if (getParser().parseEOL(
"unexpected token")) {
2991 getParser().eatToEndOfStatement();
2997bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
3001 Kind = RE->getSpecifier();
3002 Expr = RE->getSubExpr();
3011bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
3020ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
3021 StringRef IDVal = DirectiveID.
getString();
3023 if (IDVal ==
".option")
3024 return parseDirectiveOption();
3025 if (IDVal ==
".attribute")
3026 return parseDirectiveAttribute();
3027 if (IDVal ==
".insn")
3028 return parseDirectiveInsn(DirectiveID.
getLoc());
3029 if (IDVal ==
".variant_cc")
3030 return parseDirectiveVariantCC();
3035bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
3036 bool FromOptionDirective) {
3039 clearFeatureBits(Feature.Value, Feature.Key);
3046 raw_string_ostream OutputErrMsg(Buffer);
3047 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3048 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
3049 << ErrMsg.getMessage();
3052 return Error(Loc, OutputErrMsg.str());
3054 auto &ISAInfo = *ParseResult;
3057 if (ISAInfo->hasExtension(Feature.Key))
3058 setFeatureBits(Feature.Value, Feature.Key);
3060 if (FromOptionDirective) {
3061 if (ISAInfo->getXLen() == 32 && isRV64())
3062 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3063 else if (ISAInfo->getXLen() == 64 && !isRV64())
3064 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3067 if (ISAInfo->getXLen() == 32)
3068 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
3069 else if (ISAInfo->getXLen() == 64)
3070 setFeatureBits(RISCV::Feature64Bit,
"64bit");
3072 return Error(Loc,
"bad arch string " + Arch);
3074 Result = ISAInfo->toString();
3078bool RISCVAsmParser::parseDirectiveOption() {
3079 MCAsmParser &Parser = getParser();
3081 AsmToken Tok = Parser.
getTok();
3089 if (Option ==
"push") {
3093 getTargetStreamer().emitDirectiveOptionPush();
3098 if (Option ==
"pop") {
3103 getTargetStreamer().emitDirectiveOptionPop();
3104 if (popFeatureBits())
3105 return Error(StartLoc,
".option pop with no .option push");
3110 if (Option ==
"arch") {
3118 Type = RISCVOptionArchArgType::Plus;
3120 Type = RISCVOptionArchArgType::Minus;
3121 else if (!
Args.empty())
3123 "unexpected token, expected + or -");
3125 Type = RISCVOptionArchArgType::Full;
3129 "unexpected token, expected identifier");
3135 if (
Type == RISCVOptionArchArgType::Full) {
3137 if (resetToArch(Arch, Loc, Result,
true))
3146 Loc,
"extension version number parsing not currently implemented");
3149 if (!enableExperimentalExtension() &&
3151 return Error(Loc,
"unexpected experimental extensions");
3153 if (Ext == std::end(
RISCVFeatureKV) || StringRef(Ext->Key) != Feature)
3154 return Error(Loc,
"unknown extension feature");
3158 if (
Type == RISCVOptionArchArgType::Plus) {
3161 setFeatureBits(Ext->Value, Ext->Key);
3164 copySTI().setFeatureBits(OldFeatureBits);
3165 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3168 raw_string_ostream OutputErrMsg(Buffer);
3169 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3170 OutputErrMsg << ErrMsg.getMessage();
3173 return Error(Loc, OutputErrMsg.str());
3176 assert(
Type == RISCVOptionArchArgType::Minus);
3181 if (getSTI().hasFeature(Feature.Value) &&
3182 Feature.Implies.test(Ext->Value))
3183 return Error(Loc, Twine(
"can't disable ") + Ext->Key +
3184 " extension; " + Feature.Key +
3185 " extension requires " + Ext->Key +
3189 clearFeatureBits(Ext->Value, Ext->Key);
3196 getTargetStreamer().emitDirectiveOptionArch(Args);
3200 if (Option ==
"exact") {
3204 getTargetStreamer().emitDirectiveOptionExact();
3205 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3206 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3210 if (Option ==
"noexact") {
3214 getTargetStreamer().emitDirectiveOptionNoExact();
3215 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3216 setFeatureBits(RISCV::FeatureRelax,
"relax");
3220 if (Option ==
"rvc") {
3224 getTargetStreamer().emitDirectiveOptionRVC();
3225 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3229 if (Option ==
"norvc") {
3233 getTargetStreamer().emitDirectiveOptionNoRVC();
3234 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3235 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3239 if (Option ==
"pic") {
3243 getTargetStreamer().emitDirectiveOptionPIC();
3244 ParserOptions.IsPicEnabled =
true;
3248 if (Option ==
"nopic") {
3252 getTargetStreamer().emitDirectiveOptionNoPIC();
3253 ParserOptions.IsPicEnabled =
false;
3257 if (Option ==
"relax") {
3261 getTargetStreamer().emitDirectiveOptionRelax();
3262 setFeatureBits(RISCV::FeatureRelax,
"relax");
3266 if (Option ==
"norelax") {
3270 getTargetStreamer().emitDirectiveOptionNoRelax();
3271 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3277 "unknown option, expected 'push', 'pop', "
3278 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3279 "'exact', or 'noexact'");
3287bool RISCVAsmParser::parseDirectiveAttribute() {
3288 MCAsmParser &Parser = getParser();
3294 std::optional<unsigned> Ret =
3297 return Error(TagLoc,
"attribute name not recognised: " + Name);
3301 const MCExpr *AttrExpr;
3308 if (check(!CE, TagLoc,
"expected numeric constant"))
3311 Tag =
CE->getValue();
3317 StringRef StringValue;
3318 int64_t IntegerValue = 0;
3319 bool IsIntegerValue =
true;
3324 IsIntegerValue =
false;
3327 if (IsIntegerValue) {
3328 const MCExpr *ValueExpr;
3334 return Error(ValueExprLoc,
"expected numeric constant");
3335 IntegerValue =
CE->getValue();
3348 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3350 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3353 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3357 getTargetStreamer().emitTextAttribute(
Tag, Result);
3365 .
Cases({
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s"},
true)
3366 .Cases({
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj"},
3368 .
Cases({
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es"},
3377bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3378 MCAsmParser &Parser = getParser();
3385 std::optional<int64_t>
Length;
3395 return Error(ErrorLoc,
3396 "instruction lengths must be a non-zero multiple of two");
3400 return Error(ErrorLoc,
3401 "instruction lengths over 64 bits are not supported");
3407 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3412 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3413 return Error(ErrorLoc,
3414 "instruction length does not match the encoding");
3417 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3420 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3423 if (!getSTI().hasFeature(RISCV::FeatureStdExtZca) &&
3424 (EncodingDerivedLength == 2))
3425 return Error(ErrorLoc,
"compressed instructions are not allowed");
3427 if (getParser().parseEOL(
"invalid operand for instruction")) {
3428 getParser().eatToEndOfStatement();
3436 Opcode = RISCV::Insn16;
3439 Opcode = RISCV::Insn32;
3442 Opcode = RISCV::Insn48;
3445 Opcode = RISCV::Insn64;
3451 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3453 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3458 return Error(ErrorLoc,
"invalid instruction format");
3460 std::string FormatName = (
".insn_" +
Format).str();
3462 ParseInstructionInfo
Info;
3465 if (parseInstruction(Info, FormatName, L, Operands))
3470 return matchAndEmitInstruction(L, Opcode, Operands, Parser.
getStreamer(),
3477bool RISCVAsmParser::parseDirectiveVariantCC() {
3479 if (getParser().parseIdentifier(Name))
3480 return TokError(
"expected symbol name");
3483 getTargetStreamer().emitDirectiveVariantCC(
3488void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3491 const MCSubtargetInfo &STI = getSTI();
3492 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3495 ++RISCVNumInstrsCompressed;
3499void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3504 for (MCInst &Inst : Seq) {
3505 emitToStreamer(Out, Inst);
3509void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3510 const MCExpr *Symbol,
3512 unsigned SecondOpcode, SMLoc IDLoc,
3524 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3529 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3532 .addExpr(RefToLinkTmpLabel));
3535void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3549void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3559 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3560 emitAuipcInstPair(DestReg, DestReg, Symbol,
RISCV::S_GOT_HI, SecondOpcode,
3564void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3573 if (ParserOptions.IsPicEnabled)
3574 emitLoadGlobalAddress(Inst, IDLoc, Out);
3576 emitLoadLocalAddress(Inst, IDLoc, Out);
3579void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3589 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3590 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3591 SecondOpcode, IDLoc, Out);
3594void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3604 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3605 RISCV::ADDI, IDLoc, Out);
3608void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3609 SMLoc IDLoc, MCStreamer &Out,
3618 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3620 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3624 if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].
contains(TmpReg)) {
3625 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3626 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3634void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3635 int64_t Width, SMLoc IDLoc,
3644 const MCOperand &DestReg = Inst.
getOperand(0);
3645 const MCOperand &SourceReg = Inst.
getOperand(1);
3647 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3648 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3650 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3652 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3657 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3663void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
3670 emitToStreamer(Out, MCInstBuilder(Opcode)
3674 .addReg(MCRegister())
3676 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
3687 "The destination register should not be V0.");
3688 emitToStreamer(Out, MCInstBuilder(Opcode)
3694 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
3706 "The destination register should be V0.");
3708 "The temporary vector register should not be V0.");
3709 emitToStreamer(Out, MCInstBuilder(Opcode)
3713 .addReg(MCRegister())
3715 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3727 "The temporary vector register should not be V0.");
3728 emitToStreamer(Out, MCInstBuilder(Opcode)
3732 .addReg(MCRegister())
3734 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3739 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3744 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
3752bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
3754 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3757 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
3758 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3759 "%tprel_add specifier");
3765bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
3767 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
3770 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
3771 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
3772 "%tlsdesc_call specifier");
3778std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3779 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
3782std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3783 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3787std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3788 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3792bool RISCVAsmParser::validateInstruction(MCInst &Inst,
3796 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3797 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3800 if (DestReg == TempReg) {
3801 SMLoc Loc = Operands.
back()->getStartLoc();
3802 return Error(Loc,
"the temporary vector register cannot be the same as "
3803 "the destination register");
3807 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3808 Opcode == RISCV::TH_LWD) {
3813 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
3814 SMLoc Loc = Operands[1]->getStartLoc();
3815 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
3819 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
3823 SMLoc Loc = Operands[1]->getStartLoc();
3824 return Error(Loc,
"rs1 and rs2 must be different");
3828 const MCInstrDesc &MCID = MII.
get(Opcode);
3832 int DestIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
3836 const MCParsedAsmOperand *ParsedOp = Operands[1].get();
3837 if (!ParsedOp->
isReg()) {
3840 ParsedOp = Operands[2].get();
3842 assert(ParsedOp->
getReg() == DestReg &&
"Can't find parsed dest operand");
3847 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
3848 assert(VS2Idx >= 0 &&
"No vs2 operand?");
3850 if (DestReg == CheckReg)
3851 return Error(Loc,
"the destination vector register group cannot overlap"
3852 " the source vector register group");
3856 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
3861 if (DestReg == CheckReg)
3862 return Error(Loc,
"the destination vector register group cannot overlap"
3863 " the source vector register group");
3868 int VMIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vm);
3869 assert(VMIdx >= 0 &&
"No vm operand?");
3871 if (DestReg == RISCV::V0) {
3874 return Error(Loc,
"the destination vector register group cannot be V0");
3882 "Unexpected mask operand register");
3884 return Error(Loc,
"the destination vector register group cannot overlap"
3885 " the mask register");
3892bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
3900 case RISCV::PseudoC_ADDI_NOP: {
3902 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
3912 if (getSTI().hasFeature(RISCV::Feature64Bit))
3914 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV32)
3919 case RISCV::PACKW: {
3923 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV64)
3928 case RISCV::PseudoLLAImm:
3929 case RISCV::PseudoLAImm:
3930 case RISCV::PseudoLI: {
3936 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
3948 emitLoadImm(
Reg, Imm, Out);
3951 case RISCV::PseudoLLA:
3952 emitLoadLocalAddress(Inst, IDLoc, Out);
3954 case RISCV::PseudoLGA:
3955 emitLoadGlobalAddress(Inst, IDLoc, Out);
3957 case RISCV::PseudoLA:
3958 emitLoadAddress(Inst, IDLoc, Out);
3960 case RISCV::PseudoLA_TLS_IE:
3961 emitLoadTLSIEAddress(Inst, IDLoc, Out);
3963 case RISCV::PseudoLA_TLS_GD:
3964 emitLoadTLSGDAddress(Inst, IDLoc, Out);
3966 case RISCV::PseudoLB:
3967 case RISCV::PseudoQC_E_LB:
3968 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
3970 case RISCV::PseudoLBU:
3971 case RISCV::PseudoQC_E_LBU:
3972 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
3974 case RISCV::PseudoLH:
3975 case RISCV::PseudoQC_E_LH:
3976 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
3978 case RISCV::PseudoLHU:
3979 case RISCV::PseudoQC_E_LHU:
3980 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
3982 case RISCV::PseudoLW:
3983 case RISCV::PseudoQC_E_LW:
3984 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
3986 case RISCV::PseudoLWU:
3987 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
3989 case RISCV::PseudoLD:
3990 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
3992 case RISCV::PseudoLD_RV32:
3993 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
3995 case RISCV::PseudoFLH:
3996 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
3998 case RISCV::PseudoFLW:
3999 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
4001 case RISCV::PseudoFLD:
4002 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
4004 case RISCV::PseudoFLQ:
4005 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
4007 case RISCV::PseudoSB:
4008 case RISCV::PseudoQC_E_SB:
4009 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
4011 case RISCV::PseudoSH:
4012 case RISCV::PseudoQC_E_SH:
4013 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
4015 case RISCV::PseudoSW:
4016 case RISCV::PseudoQC_E_SW:
4017 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
4019 case RISCV::PseudoSD:
4020 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
4022 case RISCV::PseudoSD_RV32:
4023 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
4025 case RISCV::PseudoFSH:
4026 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
4028 case RISCV::PseudoFSW:
4029 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
4031 case RISCV::PseudoFSD:
4032 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4034 case RISCV::PseudoFSQ:
4035 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4037 case RISCV::PseudoAddTPRel:
4038 if (checkPseudoAddTPRel(Inst, Operands))
4041 case RISCV::PseudoTLSDESCCall:
4042 if (checkPseudoTLSDESCCall(Inst, Operands))
4045 case RISCV::PseudoSEXT_B:
4046 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4048 case RISCV::PseudoSEXT_H:
4049 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4051 case RISCV::PseudoZEXT_H:
4052 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4054 case RISCV::PseudoZEXT_W:
4055 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4057 case RISCV::PseudoVMSGEU_VX:
4058 case RISCV::PseudoVMSGEU_VX_M:
4059 case RISCV::PseudoVMSGEU_VX_M_T:
4060 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4062 case RISCV::PseudoVMSGE_VX:
4063 case RISCV::PseudoVMSGE_VX_M:
4064 case RISCV::PseudoVMSGE_VX_M_T:
4065 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4067 case RISCV::PseudoVMSGE_VI:
4068 case RISCV::PseudoVMSLT_VI: {
4072 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4074 emitToStreamer(Out, MCInstBuilder(
Opc)
4082 case RISCV::PseudoVMSGEU_VI:
4083 case RISCV::PseudoVMSLTU_VI: {
4090 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4093 emitToStreamer(Out, MCInstBuilder(
Opc)
4101 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4104 emitToStreamer(Out, MCInstBuilder(
Opc)
4114 case RISCV::PseudoCV_ELW:
4115 emitLoadStoreSymbol(Inst, RISCV::CV_ELW, IDLoc, Out,
false);
4119 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))
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 convertFPR64ToFPR256(MCRegister Reg)
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")
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
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.
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)
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(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)
@ CE
Windows NT (Windows on ARM)
@ Valid
The data is already valid.
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
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.