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 isSImm10PLI_H()
const {
911 return isSImm<10>() || isUImmPred([](int64_t Imm) {
915 bool isSImm10PLI_W()
const {
916 return isSImm<10>() || isUImmPred([](int64_t Imm) {
921 bool isUImm20LUI()
const {
926 if (evaluateConstantExpr(
getExpr(), Imm))
930 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
931 (VK == ELF::R_RISCV_HI20 || VK == ELF::R_RISCV_TPREL_HI20);
934 bool isUImm20AUIPC()
const {
939 if (evaluateConstantExpr(
getExpr(), Imm))
943 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
945 VK == ELF::R_RISCV_TLS_GOT_HI20 || VK == ELF::R_RISCV_TLS_GD_HI20 ||
946 VK == ELF::R_RISCV_TLSDESC_HI20);
949 bool isImmZero()
const {
950 return isUImmPred([](int64_t Imm) {
return 0 ==
Imm; });
953 bool isImmThree()
const {
954 return isUImmPred([](int64_t Imm) {
return 3 ==
Imm; });
957 bool isImmFour()
const {
958 return isUImmPred([](int64_t Imm) {
return 4 ==
Imm; });
961 bool isImm5Zibi()
const {
963 [](int64_t Imm) {
return (Imm != 0 &&
isUInt<5>(Imm)) ||
Imm == -1; });
966 bool isSImm5Plus1()
const {
971 bool isSImm18()
const {
972 return isSImmPred([](int64_t Imm) {
return isInt<18>(Imm); });
975 bool isSImm18Lsb0()
const {
979 bool isSImm19Lsb00()
const {
983 bool isSImm20Lsb000()
const {
987 bool isSImm32Lsb0()
const {
992 SMLoc getStartLoc()
const override {
return StartLoc; }
994 SMLoc getEndLoc()
const override {
return EndLoc; }
997 bool isRV64Expr()
const {
998 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1002 MCRegister
getReg()
const override {
1003 assert(Kind == KindTy::Register &&
"Invalid type access!");
1007 StringRef getSysReg()
const {
1008 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
1009 return StringRef(SysReg.Data, SysReg.Length);
1012 const MCExpr *
getExpr()
const {
1013 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1017 uint64_t getFPConst()
const {
1018 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1023 assert(Kind == KindTy::Token &&
"Invalid type access!");
1027 unsigned getVType()
const {
1028 assert(Kind == KindTy::VType &&
"Invalid type access!");
1033 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1037 unsigned getFence()
const {
1038 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1042 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1051 case KindTy::Expression:
1054 OS <<
' ' << (Expr.IsRV64 ?
"rv64" :
"rv32") <<
'>';
1056 case KindTy::FPImmediate:
1057 OS <<
"<fpimm: " << FPImm.Val <<
">";
1059 case KindTy::Register:
1061 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1066 case KindTy::SystemRegister:
1067 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1076 roundingModeToString(getFRM());
1084 case KindTy::RegList:
1089 case KindTy::StackAdj:
1090 OS <<
"<stackadj: ";
1094 case KindTy::RegReg:
1095 OS <<
"<RegReg: BaseReg " <<
RegName(
RegReg.BaseReg) <<
" OffsetReg "
1101 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1102 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1109 static std::unique_ptr<RISCVOperand>
1110 createReg(MCRegister
Reg, SMLoc S, SMLoc
E,
bool IsGPRAsFPR =
false) {
1111 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1113 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1119 static std::unique_ptr<RISCVOperand> createExpr(
const MCExpr *Val, SMLoc S,
1120 SMLoc
E,
bool IsRV64) {
1121 auto Op = std::make_unique<RISCVOperand>(KindTy::Expression);
1122 Op->Expr.Expr = Val;
1123 Op->Expr.IsRV64 = IsRV64;
1129 static std::unique_ptr<RISCVOperand> createFPImm(uint64_t Val, SMLoc S) {
1130 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1131 Op->FPImm.Val = Val;
1137 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1138 unsigned Encoding) {
1139 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1140 Op->SysReg.Data = Str.data();
1141 Op->SysReg.Length = Str.size();
1148 static std::unique_ptr<RISCVOperand>
1150 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1157 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val, SMLoc S) {
1158 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1159 Op->Fence.Val = Val;
1165 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI, SMLoc S) {
1166 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1167 Op->VType.Val = VTypeI;
1173 static std::unique_ptr<RISCVOperand> createRegList(
unsigned RlistEncode,
1175 auto Op = std::make_unique<RISCVOperand>(KindTy::RegList);
1181 static std::unique_ptr<RISCVOperand>
1182 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {
1183 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1185 Op->RegReg.OffsetReg = OffsetReg;
1191 static std::unique_ptr<RISCVOperand> createStackAdj(
unsigned StackAdj, SMLoc S) {
1192 auto Op = std::make_unique<RISCVOperand>(KindTy::StackAdj);
1193 Op->StackAdj.Val = StackAdj;
1198 static void addExpr(MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1199 assert(Expr &&
"Expr shouldn't be null!");
1201 bool IsConstant = evaluateConstantExpr(Expr, Imm);
1211 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1212 assert(
N == 1 &&
"Invalid number of operands!");
1216 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1217 assert(
N == 1 &&
"Invalid number of operands!");
1218 addExpr(Inst,
getExpr(), isRV64Expr());
1221 void addSImm8UnsignedOperands(MCInst &Inst,
unsigned N)
const {
1222 assert(
N == 1 &&
"Invalid number of operands!");
1229 void addSImm10UnsignedOperands(MCInst &Inst,
unsigned N)
const {
1230 assert(
N == 1 &&
"Invalid number of operands!");
1237 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
1238 assert(
N == 1 &&
"Invalid number of operands!");
1240 addExpr(Inst,
getExpr(), isRV64Expr());
1245 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1249 void addFenceArgOperands(MCInst &Inst,
unsigned N)
const {
1250 assert(
N == 1 &&
"Invalid number of operands!");
1254 void addCSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
1255 assert(
N == 1 &&
"Invalid number of operands!");
1262 void addVTypeIOperands(MCInst &Inst,
unsigned N)
const {
1263 assert(
N == 1 &&
"Invalid number of operands!");
1265 if (Kind == KindTy::Expression) {
1266 [[maybe_unused]]
bool IsConstantImm =
1267 evaluateConstantExpr(
getExpr(), Imm);
1268 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1275 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1276 assert(
N == 1 &&
"Invalid number of operands!");
1280 void addRegRegOperands(MCInst &Inst,
unsigned N)
const {
1281 assert(
N == 2 &&
"Invalid number of operands!");
1286 void addStackAdjOperands(MCInst &Inst,
unsigned N)
const {
1287 assert(
N == 1 &&
"Invalid number of operands!");
1291 void addFRMArgOperands(MCInst &Inst,
unsigned N)
const {
1292 assert(
N == 1 &&
"Invalid number of operands!");
1298#define GET_REGISTER_MATCHER
1299#define GET_SUBTARGET_FEATURE_NAME
1300#define GET_MATCHER_IMPLEMENTATION
1301#define GET_MNEMONIC_SPELL_CHECKER
1302#include "RISCVGenAsmMatcher.inc"
1305 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1306 return Reg - RISCV::F0_D + RISCV::F0_H;
1310 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1311 return Reg - RISCV::F0_D + RISCV::F0_F;
1315 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1316 return Reg - RISCV::F0_D + RISCV::F0_Q;
1321 unsigned RegClassID;
1322 if (Kind == MCK_VRM2)
1323 RegClassID = RISCV::VRM2RegClassID;
1324 else if (Kind == MCK_VRM4)
1325 RegClassID = RISCV::VRM4RegClassID;
1326 else if (Kind == MCK_VRM8)
1327 RegClassID = RISCV::VRM8RegClassID;
1331 &RISCVMCRegisterClasses[RegClassID]);
1335 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1336 return Reg - RISCV::F0_D + RISCV::F0_Q2;
1341 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1343 return Match_InvalidOperand;
1345 MCRegister
Reg =
Op.getReg();
1347 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg);
1349 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg);
1350 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg);
1352 if (IsRegFPR64 && Kind == MCK_FPR256) {
1354 return Match_Success;
1356 if (IsRegFPR64 && Kind == MCK_FPR128) {
1358 return Match_Success;
1362 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1363 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1365 return Match_Success;
1369 if (IsRegFPR64 && Kind == MCK_FPR16) {
1371 return Match_Success;
1373 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1374 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_H;
1375 return Match_Success;
1377 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1378 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_W;
1379 return Match_Success;
1386 if (RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg) &&
1387 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1389 return Match_Success;
1393 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1396 return Match_InvalidOperand;
1397 return Match_Success;
1399 return Match_InvalidOperand;
1402bool RISCVAsmParser::generateImmOutOfRangeError(
1403 SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
1404 const Twine &Msg =
"immediate must be an integer in the range") {
1405 return Error(ErrorLoc, Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]");
1408bool RISCVAsmParser::generateImmOutOfRangeError(
1410 const Twine &Msg =
"immediate must be an integer in the range") {
1411 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1412 return generateImmOutOfRangeError(ErrorLoc,
Lower,
Upper, Msg);
1415bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1418 uint64_t &ErrorInfo,
1419 bool MatchingInlineAsm) {
1421 FeatureBitset MissingFeatures;
1423 auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
1429 if (validateInstruction(Inst, Operands))
1431 return processInstruction(Inst, IDLoc, Operands, Out);
1432 case Match_MissingFeature: {
1433 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1434 bool FirstFeature =
true;
1435 std::string Msg =
"instruction requires the following:";
1436 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1437 if (MissingFeatures[i]) {
1438 Msg += FirstFeature ?
" " :
", ";
1440 FirstFeature =
false;
1443 return Error(IDLoc, Msg);
1445 case Match_MnemonicFail: {
1446 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1447 std::string Suggestion = RISCVMnemonicSpellCheck(
1448 ((RISCVOperand &)*Operands[0]).
getToken(), FBS, 0);
1449 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1451 case Match_InvalidOperand: {
1452 SMLoc ErrorLoc = IDLoc;
1453 if (ErrorInfo != ~0ULL) {
1454 if (ErrorInfo >= Operands.
size())
1455 return Error(ErrorLoc,
"too few operands for instruction");
1457 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1458 if (ErrorLoc == SMLoc())
1461 return Error(ErrorLoc,
"invalid operand for instruction");
1468 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1469 SMLoc ErrorLoc = IDLoc;
1470 if (ErrorInfo != ~0ULL && ErrorInfo >= Operands.
size())
1471 return Error(ErrorLoc,
"too few operands for instruction");
1477 case Match_InvalidImmXLenLI:
1479 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1480 return Error(ErrorLoc,
"operand must be a constant 64-bit integer");
1482 return generateImmOutOfRangeError(Operands, ErrorInfo,
1483 std::numeric_limits<int32_t>::min(),
1484 std::numeric_limits<uint32_t>::max());
1485 case Match_InvalidImmXLenLI_Restricted:
1487 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1488 return Error(ErrorLoc,
"operand either must be a constant 64-bit integer "
1489 "or a bare symbol name");
1491 return generateImmOutOfRangeError(
1492 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1493 std::numeric_limits<uint32_t>::max(),
1494 "operand either must be a bare symbol name or an immediate integer in "
1496 case Match_InvalidUImmLog2XLen:
1498 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1499 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1500 case Match_InvalidUImmLog2XLenNonZero:
1502 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
1503 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1504 case Match_InvalidUImm1:
1505 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
1506 case Match_InvalidUImm2:
1507 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
1508 case Match_InvalidUImm2Lsb0:
1509 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 2,
1510 "immediate must be one of");
1511 case Match_InvalidUImm3:
1512 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
1513 case Match_InvalidUImm4:
1514 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
1515 case Match_InvalidUImm5:
1516 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1517 case Match_InvalidUImm5NonZero:
1518 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1519 case Match_InvalidUImm5GT3:
1520 return generateImmOutOfRangeError(Operands, ErrorInfo, 4, (1 << 5) - 1);
1521 case Match_InvalidUImm5Plus1:
1522 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));
1523 case Match_InvalidUImm5GE6Plus1:
1524 return generateImmOutOfRangeError(Operands, ErrorInfo, 6, (1 << 5));
1525 case Match_InvalidUImm5Slist: {
1526 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1527 return Error(ErrorLoc,
1528 "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31");
1530 case Match_InvalidUImm6:
1531 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1532 case Match_InvalidUImm7:
1533 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
1534 case Match_InvalidUImm8:
1535 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
1536 case Match_InvalidUImm8GE32:
1537 return generateImmOutOfRangeError(Operands, ErrorInfo, 32, (1 << 8) - 1);
1538 case Match_InvalidSImm5:
1539 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4),
1541 case Match_InvalidSImm5NonZero:
1542 return generateImmOutOfRangeError(
1543 Operands, ErrorInfo, -(1 << 4), (1 << 4) - 1,
1544 "immediate must be non-zero in the range");
1545 case Match_InvalidSImm6:
1546 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
1548 case Match_InvalidSImm6NonZero:
1549 return generateImmOutOfRangeError(
1550 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
1551 "immediate must be non-zero in the range");
1552 case Match_InvalidCLUIImm:
1553 return generateImmOutOfRangeError(
1554 Operands, ErrorInfo, 1, (1 << 5) - 1,
1555 "immediate must be in [0xfffe0, 0xfffff] or");
1556 case Match_InvalidUImm5Lsb0:
1557 return generateImmOutOfRangeError(
1558 Operands, ErrorInfo, 0, (1 << 5) - 2,
1559 "immediate must be a multiple of 2 bytes in the range");
1560 case Match_InvalidUImm6Lsb0:
1561 return generateImmOutOfRangeError(
1562 Operands, ErrorInfo, 0, (1 << 6) - 2,
1563 "immediate must be a multiple of 2 bytes in the range");
1564 case Match_InvalidUImm7Lsb00:
1565 return generateImmOutOfRangeError(
1566 Operands, ErrorInfo, 0, (1 << 7) - 4,
1567 "immediate must be a multiple of 4 bytes in the range");
1568 case Match_InvalidUImm8Lsb00:
1569 return generateImmOutOfRangeError(
1570 Operands, ErrorInfo, 0, (1 << 8) - 4,
1571 "immediate must be a multiple of 4 bytes in the range");
1572 case Match_InvalidUImm8Lsb000:
1573 return generateImmOutOfRangeError(
1574 Operands, ErrorInfo, 0, (1 << 8) - 8,
1575 "immediate must be a multiple of 8 bytes in the range");
1576 case Match_InvalidUImm9:
1577 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 9) - 1,
1578 "immediate offset must be in the range");
1579 case Match_InvalidBareSImm9Lsb0:
1580 return generateImmOutOfRangeError(
1581 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
1582 "immediate must be a multiple of 2 bytes in the range");
1583 case Match_InvalidUImm9Lsb000:
1584 return generateImmOutOfRangeError(
1585 Operands, ErrorInfo, 0, (1 << 9) - 8,
1586 "immediate must be a multiple of 8 bytes in the range");
1587 case Match_InvalidSImm8Unsigned:
1588 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
1590 case Match_InvalidSImm10:
1591 case Match_InvalidSImm10PLI_H:
1592 case Match_InvalidSImm10PLI_W:
1593 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
1595 case Match_InvalidSImm10Unsigned:
1596 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
1598 case Match_InvalidUImm10Lsb00NonZero:
1599 return generateImmOutOfRangeError(
1600 Operands, ErrorInfo, 4, (1 << 10) - 4,
1601 "immediate must be a multiple of 4 bytes in the range");
1602 case Match_InvalidSImm10Lsb0000NonZero:
1603 return generateImmOutOfRangeError(
1604 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
1605 "immediate must be a multiple of 16 bytes and non-zero in the range");
1606 case Match_InvalidSImm11:
1607 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 10),
1609 case Match_InvalidBareSImm11Lsb0:
1610 return generateImmOutOfRangeError(
1611 Operands, ErrorInfo, -(1 << 10), (1 << 10) - 2,
1612 "immediate must be a multiple of 2 bytes in the range");
1613 case Match_InvalidUImm10:
1614 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 10) - 1);
1615 case Match_InvalidUImm11:
1616 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
1617 case Match_InvalidUImm14Lsb00:
1618 return generateImmOutOfRangeError(
1619 Operands, ErrorInfo, 0, (1 << 14) - 4,
1620 "immediate must be a multiple of 4 bytes in the range");
1621 case Match_InvalidUImm16NonZero:
1622 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16) - 1);
1623 case Match_InvalidSImm12:
1624 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11),
1626 case Match_InvalidSImm12LO:
1627 return generateImmOutOfRangeError(
1628 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
1629 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo specifier or an "
1630 "integer in the range");
1631 case Match_InvalidBareSImm12Lsb0:
1632 return generateImmOutOfRangeError(
1633 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
1634 "immediate must be a multiple of 2 bytes in the range");
1635 case Match_InvalidSImm12Lsb00000:
1636 return generateImmOutOfRangeError(
1637 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 32,
1638 "immediate must be a multiple of 32 bytes in the range");
1639 case Match_InvalidBareSImm13Lsb0:
1640 return generateImmOutOfRangeError(
1641 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
1642 "immediate must be a multiple of 2 bytes in the range");
1643 case Match_InvalidSImm16:
1644 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 15),
1646 case Match_InvalidSImm16NonZero:
1647 return generateImmOutOfRangeError(
1648 Operands, ErrorInfo, -(1 << 15), (1 << 15) - 1,
1649 "immediate must be non-zero in the range");
1650 case Match_InvalidSImm20LI:
1651 return generateImmOutOfRangeError(
1652 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 1,
1653 "operand must be a symbol with a %qc.abs20 specifier or an integer "
1655 case Match_InvalidUImm20LUI:
1656 return generateImmOutOfRangeError(
1657 Operands, ErrorInfo, 0, (1 << 20) - 1,
1658 "operand must be a symbol with "
1659 "%hi/%tprel_hi specifier or an integer in "
1661 case Match_InvalidUImm20:
1662 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1);
1663 case Match_InvalidUImm20AUIPC:
1664 return generateImmOutOfRangeError(
1665 Operands, ErrorInfo, 0, (1 << 20) - 1,
1666 "operand must be a symbol with a "
1667 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
1669 "an integer in the range");
1670 case Match_InvalidBareSImm21Lsb0:
1671 return generateImmOutOfRangeError(
1672 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
1673 "immediate must be a multiple of 2 bytes in the range");
1674 case Match_InvalidCSRSystemRegister: {
1675 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1,
1676 "operand must be a valid system register "
1677 "name or an integer in the range");
1679 case Match_InvalidImm5Zibi:
1680 return generateImmOutOfRangeError(
1681 Operands, ErrorInfo, -1, (1 << 5) - 1,
1682 "immediate must be non-zero in the range");
1683 case Match_InvalidVTypeI: {
1684 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1685 return generateVTypeError(ErrorLoc);
1687 case Match_InvalidSImm5Plus1: {
1688 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1,
1690 "immediate must be in the range");
1692 case Match_InvalidSImm18:
1693 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 17),
1695 case Match_InvalidSImm18Lsb0:
1696 return generateImmOutOfRangeError(
1697 Operands, ErrorInfo, -(1 << 17), (1 << 17) - 2,
1698 "immediate must be a multiple of 2 bytes in the range");
1699 case Match_InvalidSImm19Lsb00:
1700 return generateImmOutOfRangeError(
1701 Operands, ErrorInfo, -(1 << 18), (1 << 18) - 4,
1702 "immediate must be a multiple of 4 bytes in the range");
1703 case Match_InvalidSImm20Lsb000:
1704 return generateImmOutOfRangeError(
1705 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 8,
1706 "immediate must be a multiple of 8 bytes in the range");
1707 case Match_InvalidSImm26:
1708 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 25),
1711 case Match_InvalidBareSymbolQC_E_LI:
1714 case Match_InvalidBareSImm32:
1715 return generateImmOutOfRangeError(Operands, ErrorInfo,
1716 std::numeric_limits<int32_t>::min(),
1717 std::numeric_limits<uint32_t>::max());
1718 case Match_InvalidBareSImm32Lsb0:
1719 return generateImmOutOfRangeError(
1720 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1721 std::numeric_limits<int32_t>::max() - 1,
1722 "operand must be a multiple of 2 bytes in the range");
1723 case Match_InvalidRnumArg: {
1724 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10);
1726 case Match_InvalidStackAdj: {
1727 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1730 "stack adjustment is invalid for this instruction and register list");
1734 if (
const char *MatchDiag = getMatchKindDiag((RISCVMatchResultTy)Result)) {
1735 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1736 return Error(ErrorLoc, MatchDiag);
1746MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name)
const {
1755 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1756 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1757 static_assert(RISCV::F0_D < RISCV::F0_Q,
"FPR matching must be updated");
1760 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1765bool RISCVAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1767 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1768 return Error(StartLoc,
"invalid register name");
1772ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1774 const AsmToken &Tok = getParser().getTok();
1777 StringRef
Name = getLexer().getTok().getIdentifier();
1787ParseStatus RISCVAsmParser::parseRegister(
OperandVector &Operands,
1789 SMLoc FirstS = getLoc();
1790 bool HadParens =
false;
1797 size_t ReadCount = getLexer().peekTokens(Buf);
1800 LParen = getParser().getTok();
1805 switch (getLexer().getKind()) {
1808 getLexer().UnLex(LParen);
1811 StringRef
Name = getLexer().getTok().getIdentifier();
1816 getLexer().UnLex(LParen);
1820 Operands.
push_back(RISCVOperand::createToken(
"(", FirstS));
1822 SMLoc
E = getTok().getEndLoc();
1829 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
1835ParseStatus RISCVAsmParser::parseInsnDirectiveOpcode(
OperandVector &Operands) {
1840 switch (getLexer().getKind()) {
1850 if (getParser().parseExpression(Res,
E))
1855 int64_t
Imm =
CE->getValue();
1857 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1866 if (getParser().parseIdentifier(Identifier))
1869 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1872 "Unexpected opcode");
1875 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1885 return generateImmOutOfRangeError(
1887 "opcode must be a valid opcode name or an immediate in the range");
1890ParseStatus RISCVAsmParser::parseInsnCDirectiveOpcode(
OperandVector &Operands) {
1895 switch (getLexer().getKind()) {
1905 if (getParser().parseExpression(Res,
E))
1910 int64_t
Imm =
CE->getValue();
1911 if (Imm >= 0 && Imm <= 2) {
1912 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1921 if (getParser().parseIdentifier(Identifier))
1925 if (Identifier ==
"C0")
1927 else if (Identifier ==
"C1")
1929 else if (Identifier ==
"C2")
1936 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1945 return generateImmOutOfRangeError(
1947 "opcode must be a valid opcode name or an immediate in the range");
1950ParseStatus RISCVAsmParser::parseCSRSystemRegister(
OperandVector &Operands) {
1954 auto SysRegFromConstantInt = [
this](
const MCExpr *
E, SMLoc S) {
1956 int64_t
Imm =
CE->getValue();
1958 auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
1962 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
1965 return RISCVOperand::createSysReg(
Reg.Name, S, Imm);
1969 return RISCVOperand::createSysReg(
"", S, Imm);
1972 return std::unique_ptr<RISCVOperand>();
1975 switch (getLexer().getKind()) {
1985 if (getParser().parseExpression(Res))
1988 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
1993 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1997 if (getParser().parseIdentifier(Identifier))
2000 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
2003 if (SysReg->IsDeprecatedName) {
2005 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
2007 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2009 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
2015 const auto &FeatureBits = getSTI().getFeatureBits();
2016 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
2018 return SysReg->FeaturesRequired[Feature.Value];
2020 auto ErrorMsg = std::string(
"system register '") + SysReg->Name +
"' ";
2021 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
2022 ErrorMsg +=
"is RV32 only";
2024 ErrorMsg +=
" and ";
2028 "requires '" + std::string(Feature->Key) +
"' to be enabled";
2031 return Error(S, ErrorMsg);
2034 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
2049 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2050 "operand must be a valid system register "
2051 "name or an integer in the range");
2055 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2062ParseStatus RISCVAsmParser::parseFPImm(
OperandVector &Operands) {
2067 StringRef
Identifier = getTok().getIdentifier();
2068 if (
Identifier.compare_insensitive(
"inf") == 0) {
2071 getTok().getEndLoc(), isRV64()));
2072 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2075 getTok().getEndLoc(), isRV64()));
2076 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2079 getTok().getEndLoc(), isRV64()));
2081 return TokError(
"invalid floating point literal");
2092 const AsmToken &Tok = getTok();
2094 return TokError(
"invalid floating point immediate");
2097 APFloat RealVal(APFloat::IEEEdouble());
2099 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2101 return TokError(
"invalid floating point representation");
2104 RealVal.changeSign();
2106 Operands.
push_back(RISCVOperand::createFPImm(
2107 RealVal.bitcastToAPInt().getZExtValue(), S));
2114ParseStatus RISCVAsmParser::parseExpression(
OperandVector &Operands) {
2119 switch (getLexer().getKind()) {
2131 if (getParser().parseExpression(Res,
E))
2135 return parseOperandWithSpecifier(Operands);
2138 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2142ParseStatus RISCVAsmParser::parseOperandWithSpecifier(
OperandVector &Operands) {
2148 const MCExpr *Expr =
nullptr;
2149 bool Failed = parseExprWithSpecifier(Expr,
E);
2151 Operands.
push_back(RISCVOperand::createExpr(Expr, S,
E, isRV64()));
2155bool RISCVAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
2156 SMLoc Loc = getLoc();
2158 return TokError(
"expected '%' relocation specifier");
2159 StringRef
Identifier = getParser().getTok().getIdentifier();
2162 return TokError(
"invalid relocation specifier");
2168 const MCExpr *SubExpr;
2169 if (getParser().parseParenExpression(SubExpr,
E))
2176bool RISCVAsmParser::parseDataExpr(
const MCExpr *&Res) {
2179 return parseExprWithSpecifier(Res,
E);
2180 return getParser().parseExpression(Res);
2183ParseStatus RISCVAsmParser::parseBareSymbol(
OperandVector &Operands) {
2191 AsmToken Tok = getLexer().getTok();
2193 if (getParser().parseIdentifier(Identifier))
2203 getLexer().UnLex(Tok);
2211 switch (getLexer().getKind()) {
2213 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2226 if (getParser().parseExpression(Expr,
E))
2229 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2233ParseStatus RISCVAsmParser::parseCallSymbol(
OperandVector &Operands) {
2239 std::string
Identifier(getTok().getIdentifier());
2245 SMLoc Loc = getLoc();
2246 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2247 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2261 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2265ParseStatus RISCVAsmParser::parsePseudoJumpSymbol(
OperandVector &Operands) {
2270 if (getParser().parseExpression(Res,
E))
2273 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef)
2274 return Error(S,
"operand must be a valid jump target");
2277 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2281ParseStatus RISCVAsmParser::parseJALOffset(
OperandVector &Operands) {
2295 return parseExpression(Operands);
2298bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2299 unsigned &Sew,
unsigned &Lmul,
2300 bool &Fractional,
bool &TailAgnostic,
2301 bool &MaskAgnostic,
bool &AltFmt) {
2306 if (State < VTypeState::SeenSew &&
Identifier.consume_front(
"e")) {
2308 if (Identifier ==
"16alt") {
2311 }
else if (Identifier ==
"8alt") {
2321 State = VTypeState::SeenSew;
2325 if (State < VTypeState::SeenLmul &&
Identifier.consume_front(
"m")) {
2328 if (Identifier ==
"a" || Identifier ==
"u") {
2330 State = VTypeState::SeenMaskPolicy;
2341 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2342 unsigned MinLMUL = ELEN / 8;
2345 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2346 Twine(MinLMUL) +
" is reserved");
2349 State = VTypeState::SeenLmul;
2353 if (State < VTypeState::SeenTailPolicy &&
Identifier.starts_with(
"t")) {
2354 if (Identifier ==
"ta")
2355 TailAgnostic =
true;
2356 else if (Identifier ==
"tu")
2357 TailAgnostic =
false;
2361 State = VTypeState::SeenTailPolicy;
2365 if (State < VTypeState::SeenMaskPolicy &&
Identifier.starts_with(
"m")) {
2366 if (Identifier ==
"ma")
2367 MaskAgnostic =
true;
2368 else if (Identifier ==
"mu")
2369 MaskAgnostic =
false;
2373 State = VTypeState::SeenMaskPolicy;
2380ParseStatus RISCVAsmParser::parseVTypeI(
OperandVector &Operands) {
2386 bool Fractional =
false;
2387 bool TailAgnostic =
false;
2388 bool MaskAgnostic =
false;
2391 VTypeState State = VTypeState::SeenNothingYet;
2393 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2394 MaskAgnostic, AltFmt)) {
2396 if (State == VTypeState::SeenNothingYet)
2405 State == VTypeState::SeenNothingYet)
2406 return generateVTypeError(S);
2410 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2411 unsigned MaxSEW = ELEN / Lmul;
2413 if (MaxSEW >= 8 && Sew > MaxSEW)
2414 Warning(S,
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2415 " and LMUL == mf" + Twine(Lmul) +
2416 " may not be compatible with all RVV implementations");
2421 Operands.
push_back(RISCVOperand::createVType(VTypeI, S));
2425bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2426 if (STI->
hasFeature(RISCV::FeatureStdExtZvfbfa) ||
2427 STI->
hasFeature(RISCV::FeatureStdExtZvfofp8min) ||
2428 STI->
hasFeature(RISCV::FeatureVendorXSfvfbfexp16e))
2432 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2436 "e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2439ParseStatus RISCVAsmParser::parseXSfmmVType(
OperandVector &Operands) {
2456 if (Identifier !=
"16alt")
2485 Operands.
push_back(RISCVOperand::createVType(
2491 return generateXSfmmVTypeError(S);
2494bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
2495 return Error(ErrorLoc,
"operand must be e[8|16|16alt|32|64],w[1|2|4]");
2498ParseStatus RISCVAsmParser::parseMaskReg(
OperandVector &Operands) {
2502 StringRef
Name = getLexer().getTok().getIdentifier();
2503 if (!
Name.consume_back(
".t"))
2504 return Error(getLoc(),
"expected '.t' suffix");
2509 if (
Reg != RISCV::V0)
2512 SMLoc
E = getTok().getEndLoc();
2518ParseStatus RISCVAsmParser::parseGPRAsFPR64(
OperandVector &Operands) {
2519 if (!isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2522 return parseGPRAsFPR(Operands);
2525ParseStatus RISCVAsmParser::parseGPRAsFPR(
OperandVector &Operands) {
2529 StringRef
Name = getLexer().getTok().getIdentifier();
2535 SMLoc
E = getTok().getEndLoc();
2537 Operands.
push_back(RISCVOperand::createReg(
2538 Reg, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2542ParseStatus RISCVAsmParser::parseGPRPairAsFPR64(
OperandVector &Operands) {
2543 if (isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2549 StringRef
Name = getLexer().getTok().getIdentifier();
2555 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2558 if ((
Reg - RISCV::X0) & 1) {
2561 if (getSTI().hasFeature(RISCV::FeatureStdExtZfinx))
2562 return TokError(
"double precision floating point operands must use even "
2563 "numbered X register");
2568 SMLoc
E = getTok().getEndLoc();
2571 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2573 Reg, RISCV::sub_gpr_even,
2574 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2575 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2579template <
bool IsRV64>
2580ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands) {
2581 return parseGPRPair(Operands, IsRV64);
2584ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands,
2591 if (!IsRV64Inst && isRV64())
2597 StringRef
Name = getLexer().getTok().getIdentifier();
2603 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2606 if ((
Reg - RISCV::X0) & 1)
2607 return TokError(
"register must be even");
2610 SMLoc
E = getTok().getEndLoc();
2613 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2615 Reg, RISCV::sub_gpr_even,
2616 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2617 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E));
2621ParseStatus RISCVAsmParser::parseFRMArg(
OperandVector &Operands) {
2624 "operand must be a valid floating point rounding mode mnemonic");
2626 StringRef Str = getLexer().getTok().getIdentifier();
2631 "operand must be a valid floating point rounding mode mnemonic");
2633 Operands.
push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2638ParseStatus RISCVAsmParser::parseFenceArg(
OperandVector &Operands) {
2639 const AsmToken &Tok = getLexer().getTok();
2645 Operands.
push_back(RISCVOperand::createFenceArg(0, getLoc()));
2659 for (
char c : Str) {
2688 Operands.
push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2694 return TokError(
"operand must be formed of letters selected in-order from "
2698ParseStatus RISCVAsmParser::parseMemOpBaseReg(
OperandVector &Operands) {
2701 Operands.
push_back(RISCVOperand::createToken(
"(", getLoc()));
2703 if (!parseRegister(Operands).isSuccess())
2704 return Error(getLoc(),
"expected register");
2708 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
2713ParseStatus RISCVAsmParser::parseZeroOffsetMemOp(
OperandVector &Operands) {
2732 std::unique_ptr<RISCVOperand> OptionalImmOp;
2739 SMLoc ImmStart = getLoc();
2740 if (getParser().parseIntToken(ImmVal,
2741 "expected '(' or optional integer offset"))
2746 SMLoc ImmEnd = getLoc();
2749 ImmStart, ImmEnd, isRV64());
2753 OptionalImmOp ?
"expected '(' after optional integer offset"
2754 :
"expected '(' or optional integer offset"))
2757 if (!parseRegister(Operands).isSuccess())
2758 return Error(getLoc(),
"expected register");
2764 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2766 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2767 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2772ParseStatus RISCVAsmParser::parseRegReg(
OperandVector &Operands) {
2778 StringRef OffsetRegName = getLexer().getTok().getIdentifier();
2781 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(OffsetReg))
2782 return Error(getLoc(),
"expected GPR register");
2789 return Error(getLoc(),
"expected GPR register");
2791 StringRef BaseRegName = getLexer().getTok().getIdentifier();
2794 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(BaseReg))
2795 return Error(getLoc(),
"expected GPR register");
2801 Operands.
push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));
2813ParseStatus RISCVAsmParser::parseRegList(
OperandVector &Operands,
2814 bool MustIncludeS0) {
2826 return Error(getLoc(),
"invalid register");
2828 StringRef
RegName = getTok().getIdentifier();
2831 return Error(getLoc(),
"invalid register");
2834 UsesXRegs =
RegName[0] ==
'x';
2835 if (
Reg != RISCV::X1)
2836 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2837 }
else if (RegEnd == RISCV::X1) {
2838 if (
Reg != RISCV::X8 || (UsesXRegs != (
RegName[0] ==
'x')))
2839 return Error(getLoc(), Twine(
"register must be '") +
2840 (UsesXRegs ?
"x8" :
"s0") +
"'");
2841 }
else if (RegEnd == RISCV::X9 && UsesXRegs) {
2842 if (
Reg != RISCV::X18 || (
RegName[0] !=
'x'))
2843 return Error(getLoc(),
"register must be 'x18'");
2845 return Error(getLoc(),
"too many register ranges");
2852 SMLoc MinusLoc = getLoc();
2854 if (RegEnd == RISCV::X1)
2855 return Error(MinusLoc, Twine(
"register '") + (UsesXRegs ?
"x1" :
"ra") +
2856 "' cannot start a multiple register range");
2859 return Error(getLoc(),
"invalid register");
2861 StringRef
RegName = getTok().getIdentifier();
2864 return Error(getLoc(),
"invalid register");
2866 if (RegEnd == RISCV::X8) {
2867 if ((
Reg != RISCV::X9 &&
2869 (UsesXRegs != (
RegName[0] ==
'x'))) {
2871 return Error(getLoc(),
"register must be 'x9'");
2872 return Error(getLoc(),
"register must be in the range 's1' to 's11'");
2874 }
else if (RegEnd == RISCV::X18) {
2876 return Error(getLoc(),
2877 "register must be in the range 'x19' to 'x27'");
2890 if (RegEnd == RISCV::X26)
2891 return Error(S,
"invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "
2892 "x18-x26}' is not supported");
2898 return Error(S,
"register list must include 's0' or 'x8'");
2900 Operands.
push_back(RISCVOperand::createRegList(Encode, S));
2905ParseStatus RISCVAsmParser::parseZcmpStackAdj(
OperandVector &Operands,
2906 bool ExpectNegative) {
2915 auto *RegListOp =
static_cast<RISCVOperand *
>(Operands.
back().
get());
2916 if (!RegListOp->isRegList())
2919 unsigned RlistEncode = RegListOp->RegList.Encoding;
2923 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||
2924 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {
2925 int64_t
Lower = StackAdjBase;
2926 int64_t
Upper = StackAdjBase + 48;
2927 if (ExpectNegative) {
2932 return generateImmOutOfRangeError(S,
Lower,
Upper,
2933 "stack adjustment for register list must "
2934 "be a multiple of 16 bytes in the range");
2938 Operands.
push_back(RISCVOperand::createStackAdj(StackAdj, S));
2946bool RISCVAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
2950 MatchOperandParserImpl(Operands, Mnemonic,
true);
2957 if (parseRegister(Operands,
true).isSuccess())
2961 if (parseExpression(Operands).isSuccess()) {
2964 return !parseMemOpBaseReg(Operands).isSuccess();
2969 Error(getLoc(),
"unknown operand");
2973bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &Info,
2974 StringRef Name, SMLoc NameLoc,
2980 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
2984 Operands.
push_back(RISCVOperand::createToken(Name, NameLoc));
2993 if (parseOperand(Operands, Name))
2999 if (parseOperand(Operands, Name))
3003 if (getParser().parseEOL(
"unexpected token")) {
3004 getParser().eatToEndOfStatement();
3010bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
3014 Kind = RE->getSpecifier();
3015 Expr = RE->getSubExpr();
3024bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
3033ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
3034 StringRef IDVal = DirectiveID.
getString();
3036 if (IDVal ==
".option")
3037 return parseDirectiveOption();
3038 if (IDVal ==
".attribute")
3039 return parseDirectiveAttribute();
3040 if (IDVal ==
".insn")
3041 return parseDirectiveInsn(DirectiveID.
getLoc());
3042 if (IDVal ==
".variant_cc")
3043 return parseDirectiveVariantCC();
3048bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
3049 bool FromOptionDirective) {
3052 clearFeatureBits(Feature.Value, Feature.Key);
3059 raw_string_ostream OutputErrMsg(Buffer);
3060 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3061 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
3062 << ErrMsg.getMessage();
3065 return Error(Loc, OutputErrMsg.str());
3067 auto &ISAInfo = *ParseResult;
3070 if (ISAInfo->hasExtension(Feature.Key))
3071 setFeatureBits(Feature.Value, Feature.Key);
3073 if (FromOptionDirective) {
3074 if (ISAInfo->getXLen() == 32 && isRV64())
3075 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3076 else if (ISAInfo->getXLen() == 64 && !isRV64())
3077 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3080 if (ISAInfo->getXLen() == 32)
3081 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
3082 else if (ISAInfo->getXLen() == 64)
3083 setFeatureBits(RISCV::Feature64Bit,
"64bit");
3085 return Error(Loc,
"bad arch string " + Arch);
3087 Result = ISAInfo->toString();
3091bool RISCVAsmParser::parseDirectiveOption() {
3092 MCAsmParser &Parser = getParser();
3094 AsmToken Tok = Parser.
getTok();
3102 if (Option ==
"push") {
3106 getTargetStreamer().emitDirectiveOptionPush();
3111 if (Option ==
"pop") {
3116 getTargetStreamer().emitDirectiveOptionPop();
3117 if (popFeatureBits())
3118 return Error(StartLoc,
".option pop with no .option push");
3123 if (Option ==
"arch") {
3131 Type = RISCVOptionArchArgType::Plus;
3133 Type = RISCVOptionArchArgType::Minus;
3134 else if (!
Args.empty())
3136 "unexpected token, expected + or -");
3138 Type = RISCVOptionArchArgType::Full;
3142 "unexpected token, expected identifier");
3148 if (
Type == RISCVOptionArchArgType::Full) {
3150 if (resetToArch(Arch, Loc, Result,
true))
3159 Loc,
"extension version number parsing not currently implemented");
3162 if (!enableExperimentalExtension() &&
3164 return Error(Loc,
"unexpected experimental extensions");
3166 if (Ext == std::end(
RISCVFeatureKV) || StringRef(Ext->Key) != Feature)
3167 return Error(Loc,
"unknown extension feature");
3171 if (
Type == RISCVOptionArchArgType::Plus) {
3174 setFeatureBits(Ext->Value, Ext->Key);
3177 copySTI().setFeatureBits(OldFeatureBits);
3178 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3181 raw_string_ostream OutputErrMsg(Buffer);
3182 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3183 OutputErrMsg << ErrMsg.getMessage();
3186 return Error(Loc, OutputErrMsg.str());
3189 assert(
Type == RISCVOptionArchArgType::Minus);
3194 if (getSTI().hasFeature(Feature.Value) &&
3195 Feature.Implies.test(Ext->Value))
3196 return Error(Loc, Twine(
"can't disable ") + Ext->Key +
3197 " extension; " + Feature.Key +
3198 " extension requires " + Ext->Key +
3202 clearFeatureBits(Ext->Value, Ext->Key);
3209 getTargetStreamer().emitDirectiveOptionArch(Args);
3213 if (Option ==
"exact") {
3217 getTargetStreamer().emitDirectiveOptionExact();
3218 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3219 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3223 if (Option ==
"noexact") {
3227 getTargetStreamer().emitDirectiveOptionNoExact();
3228 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3229 setFeatureBits(RISCV::FeatureRelax,
"relax");
3233 if (Option ==
"rvc") {
3237 getTargetStreamer().emitDirectiveOptionRVC();
3238 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3242 if (Option ==
"norvc") {
3246 getTargetStreamer().emitDirectiveOptionNoRVC();
3247 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3248 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3252 if (Option ==
"pic") {
3256 getTargetStreamer().emitDirectiveOptionPIC();
3257 ParserOptions.IsPicEnabled =
true;
3261 if (Option ==
"nopic") {
3265 getTargetStreamer().emitDirectiveOptionNoPIC();
3266 ParserOptions.IsPicEnabled =
false;
3270 if (Option ==
"relax") {
3274 getTargetStreamer().emitDirectiveOptionRelax();
3275 setFeatureBits(RISCV::FeatureRelax,
"relax");
3279 if (Option ==
"norelax") {
3283 getTargetStreamer().emitDirectiveOptionNoRelax();
3284 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3290 "unknown option, expected 'push', 'pop', "
3291 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3292 "'exact', or 'noexact'");
3300bool RISCVAsmParser::parseDirectiveAttribute() {
3301 MCAsmParser &Parser = getParser();
3307 std::optional<unsigned> Ret =
3310 return Error(TagLoc,
"attribute name not recognised: " + Name);
3314 const MCExpr *AttrExpr;
3321 if (check(!CE, TagLoc,
"expected numeric constant"))
3324 Tag =
CE->getValue();
3330 StringRef StringValue;
3331 int64_t IntegerValue = 0;
3332 bool IsIntegerValue =
true;
3337 IsIntegerValue =
false;
3340 if (IsIntegerValue) {
3341 const MCExpr *ValueExpr;
3347 return Error(ValueExprLoc,
"expected numeric constant");
3348 IntegerValue =
CE->getValue();
3361 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3363 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3366 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3370 getTargetStreamer().emitTextAttribute(
Tag, Result);
3378 .
Cases({
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s"},
true)
3379 .Cases({
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj"},
3381 .
Cases({
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es"},
3390bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3391 MCAsmParser &Parser = getParser();
3398 std::optional<int64_t>
Length;
3408 return Error(ErrorLoc,
3409 "instruction lengths must be a non-zero multiple of two");
3413 return Error(ErrorLoc,
3414 "instruction lengths over 64 bits are not supported");
3420 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3425 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3426 return Error(ErrorLoc,
3427 "instruction length does not match the encoding");
3430 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3433 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3436 if (!getSTI().hasFeature(RISCV::FeatureStdExtZca) &&
3437 (EncodingDerivedLength == 2))
3438 return Error(ErrorLoc,
"compressed instructions are not allowed");
3440 if (getParser().parseEOL(
"invalid operand for instruction")) {
3441 getParser().eatToEndOfStatement();
3449 Opcode = RISCV::Insn16;
3452 Opcode = RISCV::Insn32;
3455 Opcode = RISCV::Insn48;
3458 Opcode = RISCV::Insn64;
3464 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3466 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3471 return Error(ErrorLoc,
"invalid instruction format");
3473 std::string FormatName = (
".insn_" +
Format).str();
3475 ParseInstructionInfo
Info;
3478 if (parseInstruction(Info, FormatName, L, Operands))
3483 return matchAndEmitInstruction(L, Opcode, Operands, Parser.
getStreamer(),
3490bool RISCVAsmParser::parseDirectiveVariantCC() {
3492 if (getParser().parseIdentifier(Name))
3493 return TokError(
"expected symbol name");
3496 getTargetStreamer().emitDirectiveVariantCC(
3501void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3504 const MCSubtargetInfo &STI = getSTI();
3505 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3508 ++RISCVNumInstrsCompressed;
3512void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3517 for (MCInst &Inst : Seq) {
3518 emitToStreamer(Out, Inst);
3522void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3523 const MCExpr *Symbol,
3525 unsigned SecondOpcode, SMLoc IDLoc,
3537 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3542 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3545 .addExpr(RefToLinkTmpLabel));
3548void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3562void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3572 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3573 emitAuipcInstPair(DestReg, DestReg, Symbol,
RISCV::S_GOT_HI, SecondOpcode,
3577void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3586 if (ParserOptions.IsPicEnabled)
3587 emitLoadGlobalAddress(Inst, IDLoc, Out);
3589 emitLoadLocalAddress(Inst, IDLoc, Out);
3592void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3602 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3603 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3604 SecondOpcode, IDLoc, Out);
3607void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3617 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3618 RISCV::ADDI, IDLoc, Out);
3621void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3622 SMLoc IDLoc, MCStreamer &Out,
3631 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3633 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3637 if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].
contains(TmpReg)) {
3638 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3639 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3647void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3648 int64_t Width, SMLoc IDLoc,
3657 const MCOperand &DestReg = Inst.
getOperand(0);
3658 const MCOperand &SourceReg = Inst.
getOperand(1);
3660 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3661 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3663 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3665 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3670 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3676void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
3683 emitToStreamer(Out, MCInstBuilder(Opcode)
3687 .addReg(MCRegister())
3689 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
3700 "The destination register should not be V0.");
3701 emitToStreamer(Out, MCInstBuilder(Opcode)
3707 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
3719 "The destination register should be V0.");
3721 "The temporary vector register should not be V0.");
3722 emitToStreamer(Out, MCInstBuilder(Opcode)
3726 .addReg(MCRegister())
3728 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3740 "The temporary vector register should not be V0.");
3741 emitToStreamer(Out, MCInstBuilder(Opcode)
3745 .addReg(MCRegister())
3747 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3752 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3757 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
3765bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
3767 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3770 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
3771 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3772 "%tprel_add specifier");
3778bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
3780 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
3783 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
3784 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
3785 "%tlsdesc_call specifier");
3791std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3792 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
3795std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3796 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3800std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3801 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3805bool RISCVAsmParser::validateInstruction(MCInst &Inst,
3809 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3810 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3813 if (DestReg == TempReg) {
3814 SMLoc Loc = Operands.
back()->getStartLoc();
3815 return Error(Loc,
"the temporary vector register cannot be the same as "
3816 "the destination register");
3820 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3821 Opcode == RISCV::TH_LWD) {
3826 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
3827 SMLoc Loc = Operands[1]->getStartLoc();
3828 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
3832 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
3836 SMLoc Loc = Operands[1]->getStartLoc();
3837 return Error(Loc,
"rs1 and rs2 must be different");
3841 const MCInstrDesc &MCID = MII.
get(Opcode);
3845 int DestIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
3849 const MCParsedAsmOperand *ParsedOp = Operands[1].get();
3850 if (!ParsedOp->
isReg()) {
3853 ParsedOp = Operands[2].get();
3855 assert(ParsedOp->
getReg() == DestReg &&
"Can't find parsed dest operand");
3860 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
3861 assert(VS2Idx >= 0 &&
"No vs2 operand?");
3863 if (DestReg == CheckReg)
3864 return Error(Loc,
"the destination vector register group cannot overlap"
3865 " the source vector register group");
3869 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
3874 if (DestReg == CheckReg)
3875 return Error(Loc,
"the destination vector register group cannot overlap"
3876 " the source vector register group");
3881 int VMIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vm);
3882 assert(VMIdx >= 0 &&
"No vm operand?");
3884 if (DestReg == RISCV::V0) {
3887 return Error(Loc,
"the destination vector register group cannot be V0");
3895 "Unexpected mask operand register");
3897 return Error(Loc,
"the destination vector register group cannot overlap"
3898 " the mask register");
3905bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
3913 case RISCV::PseudoC_ADDI_NOP: {
3915 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
3925 if (getSTI().hasFeature(RISCV::Feature64Bit))
3927 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV32)
3932 case RISCV::PACKW: {
3936 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV64)
3941 case RISCV::PseudoLLAImm:
3942 case RISCV::PseudoLAImm:
3943 case RISCV::PseudoLI: {
3949 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
3961 emitLoadImm(
Reg, Imm, Out);
3964 case RISCV::PseudoLLA:
3965 emitLoadLocalAddress(Inst, IDLoc, Out);
3967 case RISCV::PseudoLGA:
3968 emitLoadGlobalAddress(Inst, IDLoc, Out);
3970 case RISCV::PseudoLA:
3971 emitLoadAddress(Inst, IDLoc, Out);
3973 case RISCV::PseudoLA_TLS_IE:
3974 emitLoadTLSIEAddress(Inst, IDLoc, Out);
3976 case RISCV::PseudoLA_TLS_GD:
3977 emitLoadTLSGDAddress(Inst, IDLoc, Out);
3979 case RISCV::PseudoLB:
3980 case RISCV::PseudoQC_E_LB:
3981 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
3983 case RISCV::PseudoLBU:
3984 case RISCV::PseudoQC_E_LBU:
3985 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
3987 case RISCV::PseudoLH:
3988 case RISCV::PseudoQC_E_LH:
3989 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
3991 case RISCV::PseudoLHU:
3992 case RISCV::PseudoQC_E_LHU:
3993 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
3995 case RISCV::PseudoLW:
3996 case RISCV::PseudoQC_E_LW:
3997 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
3999 case RISCV::PseudoLWU:
4000 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
4002 case RISCV::PseudoLD:
4003 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
4005 case RISCV::PseudoLD_RV32:
4006 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
4008 case RISCV::PseudoFLH:
4009 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
4011 case RISCV::PseudoFLW:
4012 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
4014 case RISCV::PseudoFLD:
4015 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
4017 case RISCV::PseudoFLQ:
4018 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
4020 case RISCV::PseudoSB:
4021 case RISCV::PseudoQC_E_SB:
4022 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
4024 case RISCV::PseudoSH:
4025 case RISCV::PseudoQC_E_SH:
4026 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
4028 case RISCV::PseudoSW:
4029 case RISCV::PseudoQC_E_SW:
4030 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
4032 case RISCV::PseudoSD:
4033 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
4035 case RISCV::PseudoSD_RV32:
4036 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
4038 case RISCV::PseudoFSH:
4039 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
4041 case RISCV::PseudoFSW:
4042 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
4044 case RISCV::PseudoFSD:
4045 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4047 case RISCV::PseudoFSQ:
4048 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4050 case RISCV::PseudoAddTPRel:
4051 if (checkPseudoAddTPRel(Inst, Operands))
4054 case RISCV::PseudoTLSDESCCall:
4055 if (checkPseudoTLSDESCCall(Inst, Operands))
4058 case RISCV::PseudoSEXT_B:
4059 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4061 case RISCV::PseudoSEXT_H:
4062 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4064 case RISCV::PseudoZEXT_H:
4065 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4067 case RISCV::PseudoZEXT_W:
4068 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4070 case RISCV::PseudoVMSGEU_VX:
4071 case RISCV::PseudoVMSGEU_VX_M:
4072 case RISCV::PseudoVMSGEU_VX_M_T:
4073 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4075 case RISCV::PseudoVMSGE_VX:
4076 case RISCV::PseudoVMSGE_VX_M:
4077 case RISCV::PseudoVMSGE_VX_M_T:
4078 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4080 case RISCV::PseudoVMSGE_VI:
4081 case RISCV::PseudoVMSLT_VI: {
4085 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4087 emitToStreamer(Out, MCInstBuilder(
Opc)
4095 case RISCV::PseudoVMSGEU_VI:
4096 case RISCV::PseudoVMSLTU_VI: {
4103 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4106 emitToStreamer(Out, MCInstBuilder(
Opc)
4114 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4117 emitToStreamer(Out, MCInstBuilder(
Opc)
4127 case RISCV::PseudoCV_ELW:
4128 emitLoadStoreSymbol(Inst, RISCV::CV_ELW, IDLoc, Out,
false);
4132 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.