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 isUImm4Plus1()
const {
754 [](int64_t Imm) {
return Imm > 0 &&
isUInt<4>(Imm - 1); });
757 bool isUImm5Plus1()
const {
759 [](int64_t Imm) {
return Imm > 0 &&
isUInt<5>(Imm - 1); });
762 bool isUImm6Plus1()
const {
764 [](int64_t Imm) {
return Imm > 0 &&
isUInt<6>(Imm - 1); });
767 bool isUImm5GE6Plus1()
const {
769 [](int64_t Imm) {
return Imm >= 6 &&
isUInt<5>(Imm - 1); });
772 bool isUImm5Slist()
const {
773 return isUImmPred([](int64_t Imm) {
774 return (Imm == 0) || (
Imm == 1) || (Imm == 2) || (
Imm == 4) ||
775 (Imm == 8) || (
Imm == 16) || (Imm == 15) || (
Imm == 31);
779 bool isUImm8GE32()
const {
780 return isUImmPred([](int64_t Imm) {
return isUInt<8>(Imm) &&
Imm >= 32; });
783 bool isRnumArg()
const {
785 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(10); });
788 bool isRnumArg_0_7()
const {
790 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(7); });
793 bool isRnumArg_1_10()
const {
795 [](int64_t Imm) {
return Imm >= INT64_C(1) &&
Imm <= INT64_C(10); });
798 bool isRnumArg_2_14()
const {
800 [](int64_t Imm) {
return Imm >= INT64_C(2) &&
Imm <= INT64_C(14); });
803 template <
unsigned N>
bool isSImm()
const {
807 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
808 return IsConstantImm &&
isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
811 template <
class Pred>
bool isSImmPred(Pred p)
const {
815 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
816 return IsConstantImm &&
p(fixImmediateForRV32(Imm, isRV64Expr()));
819 bool isSImm5()
const {
return isSImm<5>(); }
820 bool isSImm6()
const {
return isSImm<6>(); }
821 bool isSImm10()
const {
return isSImm<10>(); }
822 bool isSImm11()
const {
return isSImm<11>(); }
823 bool isSImm12()
const {
return isSImm<12>(); }
824 bool isSImm16()
const {
return isSImm<16>(); }
825 bool isSImm26()
const {
return isSImm<26>(); }
827 bool isSImm5NonZero()
const {
828 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<5>(Imm); });
831 bool isSImm6NonZero()
const {
832 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<6>(Imm); });
835 bool isCLUIImm()
const {
836 return isUImmPred([](int64_t Imm) {
837 return (
isUInt<5>(Imm) && Imm != 0) || (
Imm >= 0xfffe0 &&
Imm <= 0xfffff);
841 bool isUImm2Lsb0()
const {
return isUImmShifted<1, 1>(); }
843 bool isUImm5Lsb0()
const {
return isUImmShifted<4, 1>(); }
845 bool isUImm6Lsb0()
const {
return isUImmShifted<5, 1>(); }
847 bool isUImm7Lsb00()
const {
return isUImmShifted<5, 2>(); }
849 bool isUImm7Lsb000()
const {
return isUImmShifted<4, 3>(); }
851 bool isUImm8Lsb00()
const {
return isUImmShifted<6, 2>(); }
853 bool isUImm8Lsb000()
const {
return isUImmShifted<5, 3>(); }
855 bool isUImm9Lsb000()
const {
return isUImmShifted<6, 3>(); }
857 bool isUImm14Lsb00()
const {
return isUImmShifted<12, 2>(); }
859 bool isUImm10Lsb00NonZero()
const {
866 static int64_t fixImmediateForRV32(int64_t Imm,
bool IsRV64Imm) {
872 bool isSImm12LO()
const {
877 if (evaluateConstantExpr(
getExpr(), Imm))
878 return isInt<12>(fixImmediateForRV32(Imm, isRV64Expr()));
881 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
884 VK == ELF::R_RISCV_TLSDESC_ADD_LO12);
887 bool isSImm12Lsb00000()
const {
891 bool isSImm10Lsb0000NonZero()
const {
896 bool isSImm16NonZero()
const {
897 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<16>(Imm); });
900 bool isUImm16NonZero()
const {
901 return isUImmPred([](int64_t Imm) {
return isUInt<16>(Imm) &&
Imm != 0; });
904 bool isSImm20LI()
const {
909 if (evaluateConstantExpr(
getExpr(), Imm))
910 return isInt<20>(fixImmediateForRV32(Imm, isRV64Expr()));
913 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
917 bool isSImm8PLI_B()
const {
return isSImm<8>() || isUImm<8>(); }
918 bool isSImm10PLUI()
const {
return isSImm<10>() || isUImm<10>(); }
920 bool isSImm10PLI_H()
const {
921 return isSImm<10>() || isUImmPred([](int64_t Imm) {
925 bool isSImm10PLI_W()
const {
926 return isSImm<10>() || isUImmPred([](int64_t Imm) {
931 bool isUImm20LUI()
const {
936 if (evaluateConstantExpr(
getExpr(), Imm))
940 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
941 (VK == ELF::R_RISCV_HI20 || VK == ELF::R_RISCV_TPREL_HI20);
944 bool isUImm20AUIPC()
const {
949 if (evaluateConstantExpr(
getExpr(), Imm))
953 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
955 VK == ELF::R_RISCV_TLS_GOT_HI20 || VK == ELF::R_RISCV_TLS_GD_HI20 ||
956 VK == ELF::R_RISCV_TLSDESC_HI20);
959 bool isImmZero()
const {
960 return isUImmPred([](int64_t Imm) {
return 0 ==
Imm; });
963 bool isImmThree()
const {
964 return isUImmPred([](int64_t Imm) {
return 3 ==
Imm; });
967 bool isImmFour()
const {
968 return isUImmPred([](int64_t Imm) {
return 4 ==
Imm; });
971 bool isImm5Zibi()
const {
973 [](int64_t Imm) {
return (Imm != 0 &&
isUInt<5>(Imm)) ||
Imm == -1; });
976 bool isSImm5Plus1()
const {
981 bool isSImm18()
const {
982 return isSImmPred([](int64_t Imm) {
return isInt<18>(Imm); });
985 bool isSImm18Lsb0()
const {
989 bool isSImm19Lsb00()
const {
993 bool isSImm20Lsb000()
const {
997 bool isSImm32Lsb0()
const {
1002 SMLoc getStartLoc()
const override {
return StartLoc; }
1004 SMLoc getEndLoc()
const override {
return EndLoc; }
1007 bool isRV64Expr()
const {
1008 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1012 MCRegister
getReg()
const override {
1013 assert(Kind == KindTy::Register &&
"Invalid type access!");
1017 StringRef getSysReg()
const {
1018 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
1019 return StringRef(SysReg.Data, SysReg.Length);
1022 const MCExpr *
getExpr()
const {
1023 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1027 uint64_t getFPConst()
const {
1028 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1033 assert(Kind == KindTy::Token &&
"Invalid type access!");
1037 unsigned getVType()
const {
1038 assert(Kind == KindTy::VType &&
"Invalid type access!");
1043 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1047 unsigned getFence()
const {
1048 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1052 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1061 case KindTy::Expression:
1064 OS <<
' ' << (Expr.IsRV64 ?
"rv64" :
"rv32") <<
'>';
1066 case KindTy::FPImmediate:
1067 OS <<
"<fpimm: " << FPImm.Val <<
">";
1069 case KindTy::Register:
1071 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1076 case KindTy::SystemRegister:
1077 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1086 OS << roundingModeToString(getFRM());
1094 case KindTy::RegList:
1099 case KindTy::StackAdj:
1100 OS <<
"<stackadj: ";
1104 case KindTy::RegReg:
1105 OS <<
"<RegReg: BaseReg " <<
RegName(
RegReg.BaseReg) <<
" OffsetReg "
1111 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1112 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1119 static std::unique_ptr<RISCVOperand>
1120 createReg(MCRegister
Reg, SMLoc S, SMLoc
E,
bool IsGPRAsFPR =
false) {
1121 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1123 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1129 static std::unique_ptr<RISCVOperand> createExpr(
const MCExpr *Val, SMLoc S,
1130 SMLoc
E,
bool IsRV64) {
1131 auto Op = std::make_unique<RISCVOperand>(KindTy::Expression);
1132 Op->Expr.Expr = Val;
1133 Op->Expr.IsRV64 = IsRV64;
1139 static std::unique_ptr<RISCVOperand> createFPImm(uint64_t Val, SMLoc S) {
1140 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1141 Op->FPImm.Val = Val;
1147 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1148 unsigned Encoding) {
1149 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1150 Op->SysReg.Data = Str.data();
1151 Op->SysReg.Length = Str.size();
1158 static std::unique_ptr<RISCVOperand>
1160 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1167 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val, SMLoc S) {
1168 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1169 Op->Fence.Val = Val;
1175 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI, SMLoc S) {
1176 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1177 Op->VType.Val = VTypeI;
1183 static std::unique_ptr<RISCVOperand> createRegList(
unsigned RlistEncode,
1185 auto Op = std::make_unique<RISCVOperand>(KindTy::RegList);
1191 static std::unique_ptr<RISCVOperand>
1192 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {
1193 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1195 Op->RegReg.OffsetReg = OffsetReg;
1201 static std::unique_ptr<RISCVOperand> createStackAdj(
unsigned StackAdj, SMLoc S) {
1202 auto Op = std::make_unique<RISCVOperand>(KindTy::StackAdj);
1203 Op->StackAdj.Val = StackAdj;
1208 static void addExpr(MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1209 assert(Expr &&
"Expr shouldn't be null!");
1211 bool IsConstant = evaluateConstantExpr(Expr, Imm);
1221 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1222 assert(
N == 1 &&
"Invalid number of operands!");
1226 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1227 assert(
N == 1 &&
"Invalid number of operands!");
1228 addExpr(Inst,
getExpr(), isRV64Expr());
1231 template <
unsigned Bits>
1232 void addSExtImmOperands(MCInst &Inst,
unsigned N)
const {
1233 assert(
N == 1 &&
"Invalid number of operands!");
1240 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
1241 assert(
N == 1 &&
"Invalid number of operands!");
1243 addExpr(Inst,
getExpr(), isRV64Expr());
1248 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1252 void addFenceArgOperands(MCInst &Inst,
unsigned N)
const {
1253 assert(
N == 1 &&
"Invalid number of operands!");
1257 void addCSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
1258 assert(
N == 1 &&
"Invalid number of operands!");
1265 void addVTypeIOperands(MCInst &Inst,
unsigned N)
const {
1266 assert(
N == 1 &&
"Invalid number of operands!");
1268 if (Kind == KindTy::Expression) {
1269 [[maybe_unused]]
bool IsConstantImm =
1270 evaluateConstantExpr(
getExpr(), Imm);
1271 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1278 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1279 assert(
N == 1 &&
"Invalid number of operands!");
1283 void addRegRegOperands(MCInst &Inst,
unsigned N)
const {
1284 assert(
N == 2 &&
"Invalid number of operands!");
1289 void addStackAdjOperands(MCInst &Inst,
unsigned N)
const {
1290 assert(
N == 1 &&
"Invalid number of operands!");
1294 void addFRMArgOperands(MCInst &Inst,
unsigned N)
const {
1295 assert(
N == 1 &&
"Invalid number of operands!");
1301#define GET_REGISTER_MATCHER
1302#define GET_SUBTARGET_FEATURE_NAME
1303#define GET_MATCHER_IMPLEMENTATION
1304#define GET_MNEMONIC_SPELL_CHECKER
1305#include "RISCVGenAsmMatcher.inc"
1308 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1309 return Reg - RISCV::F0_D + RISCV::F0_H;
1313 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1314 return Reg - RISCV::F0_D + RISCV::F0_F;
1318 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1319 return Reg - RISCV::F0_D + RISCV::F0_Q;
1324 unsigned RegClassID;
1325 if (Kind == MCK_VRM2)
1326 RegClassID = RISCV::VRM2RegClassID;
1327 else if (Kind == MCK_VRM4)
1328 RegClassID = RISCV::VRM4RegClassID;
1329 else if (Kind == MCK_VRM8)
1330 RegClassID = RISCV::VRM8RegClassID;
1334 &RISCVMCRegisterClasses[RegClassID]);
1338 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1339 return Reg - RISCV::F0_D + RISCV::F0_Q2;
1344 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1346 return Match_InvalidOperand;
1348 MCRegister
Reg =
Op.getReg();
1350 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg);
1352 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg);
1353 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg);
1355 if (IsRegFPR64 && Kind == MCK_FPR256) {
1357 return Match_Success;
1359 if (IsRegFPR64 && Kind == MCK_FPR128) {
1361 return Match_Success;
1365 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1366 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1368 return Match_Success;
1372 if (IsRegFPR64 && Kind == MCK_FPR16) {
1374 return Match_Success;
1376 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1377 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_H;
1378 return Match_Success;
1380 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1381 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_W;
1382 return Match_Success;
1389 if (RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg) &&
1390 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1392 return Match_Success;
1396 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1399 return Match_InvalidOperand;
1400 return Match_Success;
1402 return Match_InvalidOperand;
1405bool RISCVAsmParser::generateImmOutOfRangeError(
1406 SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
1407 const Twine &Msg =
"immediate must be an integer in the range") {
1408 return Error(ErrorLoc, Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]");
1411bool RISCVAsmParser::generateImmOutOfRangeError(
1413 const Twine &Msg =
"immediate must be an integer in the range") {
1414 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1415 return generateImmOutOfRangeError(ErrorLoc,
Lower,
Upper, Msg);
1418bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1421 uint64_t &ErrorInfo,
1422 bool MatchingInlineAsm) {
1424 FeatureBitset MissingFeatures;
1426 auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
1432 if (validateInstruction(Inst, Operands))
1434 return processInstruction(Inst, IDLoc, Operands, Out);
1435 case Match_MissingFeature: {
1436 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1437 bool FirstFeature =
true;
1438 std::string Msg =
"instruction requires the following:";
1439 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1440 if (MissingFeatures[i]) {
1441 Msg += FirstFeature ?
" " :
", ";
1443 FirstFeature =
false;
1446 return Error(IDLoc, Msg);
1448 case Match_MnemonicFail: {
1449 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1450 std::string Suggestion = RISCVMnemonicSpellCheck(
1451 ((RISCVOperand &)*Operands[0]).
getToken(), FBS, 0);
1452 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1454 case Match_InvalidOperand: {
1455 SMLoc ErrorLoc = IDLoc;
1456 if (ErrorInfo != ~0ULL) {
1457 if (ErrorInfo >= Operands.
size())
1458 return Error(ErrorLoc,
"too few operands for instruction");
1460 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1461 if (ErrorLoc == SMLoc())
1464 return Error(ErrorLoc,
"invalid operand for instruction");
1471 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1472 SMLoc ErrorLoc = IDLoc;
1473 if (ErrorInfo != ~0ULL && ErrorInfo >= Operands.
size())
1474 return Error(ErrorLoc,
"too few operands for instruction");
1480 case Match_InvalidImmXLenLI:
1482 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1483 return Error(ErrorLoc,
"operand must be a constant 64-bit integer");
1485 return generateImmOutOfRangeError(Operands, ErrorInfo,
1486 std::numeric_limits<int32_t>::min(),
1487 std::numeric_limits<uint32_t>::max());
1488 case Match_InvalidImmXLenLI_Restricted:
1490 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1491 return Error(ErrorLoc,
"operand either must be a constant 64-bit integer "
1492 "or a bare symbol name");
1494 return generateImmOutOfRangeError(
1495 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1496 std::numeric_limits<uint32_t>::max(),
1497 "operand either must be a bare symbol name or an immediate integer in "
1499 case Match_InvalidUImmLog2XLen:
1501 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1502 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1503 case Match_InvalidUImmLog2XLenNonZero:
1505 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
1506 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1507 case Match_InvalidUImm1:
1508 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
1509 case Match_InvalidUImm2:
1510 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
1511 case Match_InvalidUImm2Lsb0:
1512 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 2,
1513 "immediate must be one of");
1514 case Match_InvalidUImm3:
1515 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
1516 case Match_InvalidUImm4:
1517 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
1518 case Match_InvalidUImm4Plus1:
1519 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4));
1520 case Match_InvalidUImm5:
1521 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1522 case Match_InvalidUImm5NonZero:
1523 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1524 case Match_InvalidUImm5GT3:
1525 return generateImmOutOfRangeError(Operands, ErrorInfo, 4, (1 << 5) - 1);
1526 case Match_InvalidUImm5Plus1:
1527 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));
1528 case Match_InvalidUImm5GE6Plus1:
1529 return generateImmOutOfRangeError(Operands, ErrorInfo, 6, (1 << 5));
1530 case Match_InvalidUImm5Slist: {
1531 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1532 return Error(ErrorLoc,
1533 "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31");
1535 case Match_InvalidUImm6:
1536 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1537 case Match_InvalidUImm6Plus1:
1538 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6));
1539 case Match_InvalidUImm7:
1540 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
1541 case Match_InvalidUImm8:
1542 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
1543 case Match_InvalidUImm8GE32:
1544 return generateImmOutOfRangeError(Operands, ErrorInfo, 32, (1 << 8) - 1);
1545 case Match_InvalidSImm5:
1546 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4),
1548 case Match_InvalidSImm5NonZero:
1549 return generateImmOutOfRangeError(
1550 Operands, ErrorInfo, -(1 << 4), (1 << 4) - 1,
1551 "immediate must be non-zero in the range");
1552 case Match_InvalidSImm6:
1553 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
1555 case Match_InvalidSImm6NonZero:
1556 return generateImmOutOfRangeError(
1557 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
1558 "immediate must be non-zero in the range");
1559 case Match_InvalidCLUIImm:
1560 return generateImmOutOfRangeError(
1561 Operands, ErrorInfo, 1, (1 << 5) - 1,
1562 "immediate must be in [0xfffe0, 0xfffff] or");
1563 case Match_InvalidUImm5Lsb0:
1564 return generateImmOutOfRangeError(
1565 Operands, ErrorInfo, 0, (1 << 5) - 2,
1566 "immediate must be a multiple of 2 bytes in the range");
1567 case Match_InvalidUImm6Lsb0:
1568 return generateImmOutOfRangeError(
1569 Operands, ErrorInfo, 0, (1 << 6) - 2,
1570 "immediate must be a multiple of 2 bytes in the range");
1571 case Match_InvalidUImm7Lsb00:
1572 return generateImmOutOfRangeError(
1573 Operands, ErrorInfo, 0, (1 << 7) - 4,
1574 "immediate must be a multiple of 4 bytes in the range");
1575 case Match_InvalidUImm8Lsb00:
1576 return generateImmOutOfRangeError(
1577 Operands, ErrorInfo, 0, (1 << 8) - 4,
1578 "immediate must be a multiple of 4 bytes in the range");
1579 case Match_InvalidUImm8Lsb000:
1580 return generateImmOutOfRangeError(
1581 Operands, ErrorInfo, 0, (1 << 8) - 8,
1582 "immediate must be a multiple of 8 bytes in the range");
1583 case Match_InvalidUImm9:
1584 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 9) - 1,
1585 "immediate offset must be in the range");
1586 case Match_InvalidBareSImm9Lsb0:
1587 return generateImmOutOfRangeError(
1588 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
1589 "immediate must be a multiple of 2 bytes in the range");
1590 case Match_InvalidUImm9Lsb000:
1591 return generateImmOutOfRangeError(
1592 Operands, ErrorInfo, 0, (1 << 9) - 8,
1593 "immediate must be a multiple of 8 bytes in the range");
1594 case Match_InvalidSImm8PLI_B:
1595 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
1597 case Match_InvalidSImm10:
1598 case Match_InvalidSImm10PLI_H:
1599 case Match_InvalidSImm10PLI_W:
1600 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
1602 case Match_InvalidSImm10PLUI:
1603 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
1605 case Match_InvalidUImm10Lsb00NonZero:
1606 return generateImmOutOfRangeError(
1607 Operands, ErrorInfo, 4, (1 << 10) - 4,
1608 "immediate must be a multiple of 4 bytes in the range");
1609 case Match_InvalidSImm10Lsb0000NonZero:
1610 return generateImmOutOfRangeError(
1611 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
1612 "immediate must be a multiple of 16 bytes and non-zero in the range");
1613 case Match_InvalidSImm11:
1614 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 10),
1616 case Match_InvalidBareSImm11Lsb0:
1617 return generateImmOutOfRangeError(
1618 Operands, ErrorInfo, -(1 << 10), (1 << 10) - 2,
1619 "immediate must be a multiple of 2 bytes in the range");
1620 case Match_InvalidUImm10:
1621 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 10) - 1);
1622 case Match_InvalidUImm11:
1623 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
1624 case Match_InvalidUImm14Lsb00:
1625 return generateImmOutOfRangeError(
1626 Operands, ErrorInfo, 0, (1 << 14) - 4,
1627 "immediate must be a multiple of 4 bytes in the range");
1628 case Match_InvalidUImm16NonZero:
1629 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16) - 1);
1630 case Match_InvalidSImm12:
1631 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11),
1633 case Match_InvalidSImm12LO:
1634 return generateImmOutOfRangeError(
1635 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
1636 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo specifier or an "
1637 "integer in the range");
1638 case Match_InvalidBareSImm12Lsb0:
1639 return generateImmOutOfRangeError(
1640 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
1641 "immediate must be a multiple of 2 bytes in the range");
1642 case Match_InvalidSImm12Lsb00000:
1643 return generateImmOutOfRangeError(
1644 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 32,
1645 "immediate must be a multiple of 32 bytes in the range");
1646 case Match_InvalidBareSImm13Lsb0:
1647 return generateImmOutOfRangeError(
1648 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
1649 "immediate must be a multiple of 2 bytes in the range");
1650 case Match_InvalidSImm16:
1651 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 15),
1653 case Match_InvalidSImm16NonZero:
1654 return generateImmOutOfRangeError(
1655 Operands, ErrorInfo, -(1 << 15), (1 << 15) - 1,
1656 "immediate must be non-zero in the range");
1657 case Match_InvalidSImm20LI:
1658 return generateImmOutOfRangeError(
1659 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 1,
1660 "operand must be a symbol with a %qc.abs20 specifier or an integer "
1662 case Match_InvalidUImm20LUI:
1663 return generateImmOutOfRangeError(
1664 Operands, ErrorInfo, 0, (1 << 20) - 1,
1665 "operand must be a symbol with "
1666 "%hi/%tprel_hi specifier or an integer in "
1668 case Match_InvalidUImm20:
1669 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1);
1670 case Match_InvalidUImm20AUIPC:
1671 return generateImmOutOfRangeError(
1672 Operands, ErrorInfo, 0, (1 << 20) - 1,
1673 "operand must be a symbol with a "
1674 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
1676 "an integer in the range");
1677 case Match_InvalidBareSImm21Lsb0:
1678 return generateImmOutOfRangeError(
1679 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
1680 "immediate must be a multiple of 2 bytes in the range");
1681 case Match_InvalidCSRSystemRegister: {
1682 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1,
1683 "operand must be a valid system register "
1684 "name or an integer in the range");
1686 case Match_InvalidImm5Zibi:
1687 return generateImmOutOfRangeError(
1688 Operands, ErrorInfo, -1, (1 << 5) - 1,
1689 "immediate must be non-zero in the range");
1690 case Match_InvalidVTypeI: {
1691 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1692 return generateVTypeError(ErrorLoc);
1694 case Match_InvalidSImm5Plus1: {
1695 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1,
1697 "immediate must be in the range");
1699 case Match_InvalidSImm18:
1700 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 17),
1702 case Match_InvalidSImm18Lsb0:
1703 return generateImmOutOfRangeError(
1704 Operands, ErrorInfo, -(1 << 17), (1 << 17) - 2,
1705 "immediate must be a multiple of 2 bytes in the range");
1706 case Match_InvalidSImm19Lsb00:
1707 return generateImmOutOfRangeError(
1708 Operands, ErrorInfo, -(1 << 18), (1 << 18) - 4,
1709 "immediate must be a multiple of 4 bytes in the range");
1710 case Match_InvalidSImm20Lsb000:
1711 return generateImmOutOfRangeError(
1712 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 8,
1713 "immediate must be a multiple of 8 bytes in the range");
1714 case Match_InvalidSImm26:
1715 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 25),
1718 case Match_InvalidBareSymbolQC_E_LI:
1721 case Match_InvalidBareSImm32:
1722 return generateImmOutOfRangeError(Operands, ErrorInfo,
1723 std::numeric_limits<int32_t>::min(),
1724 std::numeric_limits<uint32_t>::max());
1725 case Match_InvalidBareSImm32Lsb0:
1726 return generateImmOutOfRangeError(
1727 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1728 std::numeric_limits<int32_t>::max() - 1,
1729 "operand must be a multiple of 2 bytes in the range");
1730 case Match_InvalidRnumArg: {
1731 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10);
1733 case Match_InvalidStackAdj: {
1734 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1737 "stack adjustment is invalid for this instruction and register list");
1741 if (
const char *MatchDiag = getMatchKindDiag((RISCVMatchResultTy)Result)) {
1742 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1743 return Error(ErrorLoc, MatchDiag);
1753MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name)
const {
1762 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1763 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1764 static_assert(RISCV::F0_D < RISCV::F0_Q,
"FPR matching must be updated");
1767 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1772bool RISCVAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1774 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1775 return Error(StartLoc,
"invalid register name");
1779ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1781 const AsmToken &Tok = getParser().getTok();
1784 StringRef
Name = getLexer().getTok().getIdentifier();
1794ParseStatus RISCVAsmParser::parseRegister(
OperandVector &Operands,
1796 SMLoc FirstS = getLoc();
1797 bool HadParens =
false;
1804 size_t ReadCount = getLexer().peekTokens(Buf);
1807 LParen = getParser().getTok();
1812 switch (getLexer().getKind()) {
1815 getLexer().UnLex(LParen);
1818 StringRef
Name = getLexer().getTok().getIdentifier();
1823 getLexer().UnLex(LParen);
1827 Operands.
push_back(RISCVOperand::createToken(
"(", FirstS));
1829 SMLoc
E = getTok().getEndLoc();
1836 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
1842ParseStatus RISCVAsmParser::parseInsnDirectiveOpcode(
OperandVector &Operands) {
1847 switch (getLexer().getKind()) {
1857 if (getParser().parseExpression(Res,
E))
1862 int64_t
Imm =
CE->getValue();
1864 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1873 if (getParser().parseIdentifier(Identifier))
1876 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1879 "Unexpected opcode");
1882 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1892 return generateImmOutOfRangeError(
1894 "opcode must be a valid opcode name or an immediate in the range");
1897ParseStatus RISCVAsmParser::parseInsnCDirectiveOpcode(
OperandVector &Operands) {
1902 switch (getLexer().getKind()) {
1912 if (getParser().parseExpression(Res,
E))
1917 int64_t
Imm =
CE->getValue();
1918 if (Imm >= 0 && Imm <= 2) {
1919 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1928 if (getParser().parseIdentifier(Identifier))
1932 if (Identifier ==
"C0")
1934 else if (Identifier ==
"C1")
1936 else if (Identifier ==
"C2")
1943 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1952 return generateImmOutOfRangeError(
1954 "opcode must be a valid opcode name or an immediate in the range");
1957ParseStatus RISCVAsmParser::parseCSRSystemRegister(
OperandVector &Operands) {
1961 auto SysRegFromConstantInt = [
this](
const MCExpr *
E, SMLoc S) {
1963 int64_t
Imm =
CE->getValue();
1965 auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
1969 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
1972 return RISCVOperand::createSysReg(
Reg.Name, S, Imm);
1976 return RISCVOperand::createSysReg(
"", S, Imm);
1979 return std::unique_ptr<RISCVOperand>();
1982 switch (getLexer().getKind()) {
1992 if (getParser().parseExpression(Res))
1995 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
2000 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2004 if (getParser().parseIdentifier(Identifier))
2007 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
2010 if (SysReg->IsDeprecatedName) {
2012 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
2014 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2016 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
2022 const auto &FeatureBits = getSTI().getFeatureBits();
2023 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
2025 return SysReg->FeaturesRequired[Feature.Value];
2027 auto ErrorMsg = std::string(
"system register '") + SysReg->Name +
"' ";
2028 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
2029 ErrorMsg +=
"is RV32 only";
2031 ErrorMsg +=
" and ";
2035 "requires '" + std::string(Feature->Key) +
"' to be enabled";
2038 return Error(S, ErrorMsg);
2041 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
2056 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2057 "operand must be a valid system register "
2058 "name or an integer in the range");
2062 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2069ParseStatus RISCVAsmParser::parseFPImm(
OperandVector &Operands) {
2074 StringRef
Identifier = getTok().getIdentifier();
2075 if (
Identifier.compare_insensitive(
"inf") == 0) {
2078 getTok().getEndLoc(), isRV64()));
2079 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2082 getTok().getEndLoc(), isRV64()));
2083 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2086 getTok().getEndLoc(), isRV64()));
2088 return TokError(
"invalid floating point literal");
2099 const AsmToken &Tok = getTok();
2101 return TokError(
"invalid floating point immediate");
2104 APFloat RealVal(APFloat::IEEEdouble());
2106 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2108 return TokError(
"invalid floating point representation");
2111 RealVal.changeSign();
2113 Operands.
push_back(RISCVOperand::createFPImm(
2114 RealVal.bitcastToAPInt().getZExtValue(), S));
2121ParseStatus RISCVAsmParser::parseExpression(
OperandVector &Operands) {
2126 switch (getLexer().getKind()) {
2138 if (getParser().parseExpression(Res,
E))
2142 return parseOperandWithSpecifier(Operands);
2145 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2149ParseStatus RISCVAsmParser::parseOperandWithSpecifier(
OperandVector &Operands) {
2155 const MCExpr *Expr =
nullptr;
2156 bool Failed = parseExprWithSpecifier(Expr,
E);
2158 Operands.
push_back(RISCVOperand::createExpr(Expr, S,
E, isRV64()));
2162bool RISCVAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
2163 SMLoc Loc = getLoc();
2165 return TokError(
"expected '%' relocation specifier");
2166 StringRef
Identifier = getParser().getTok().getIdentifier();
2169 return TokError(
"invalid relocation specifier");
2175 const MCExpr *SubExpr;
2176 if (getParser().parseParenExpression(SubExpr,
E))
2183bool RISCVAsmParser::parseDataExpr(
const MCExpr *&Res) {
2186 return parseExprWithSpecifier(Res,
E);
2187 return getParser().parseExpression(Res);
2190ParseStatus RISCVAsmParser::parseBareSymbol(
OperandVector &Operands) {
2198 AsmToken Tok = getLexer().getTok();
2200 if (getParser().parseIdentifier(Identifier))
2210 getLexer().UnLex(Tok);
2218 switch (getLexer().getKind()) {
2220 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2233 if (getParser().parseExpression(Expr,
E))
2236 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2240ParseStatus RISCVAsmParser::parseCallSymbol(
OperandVector &Operands) {
2246 std::string
Identifier(getTok().getIdentifier());
2252 SMLoc Loc = getLoc();
2253 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2254 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2268 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2272ParseStatus RISCVAsmParser::parsePseudoJumpSymbol(
OperandVector &Operands) {
2277 if (getParser().parseExpression(Res,
E))
2280 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef)
2281 return Error(S,
"operand must be a valid jump target");
2284 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2288ParseStatus RISCVAsmParser::parseJALOffset(
OperandVector &Operands) {
2302 return parseExpression(Operands);
2305bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2306 unsigned &Sew,
unsigned &Lmul,
2307 bool &Fractional,
bool &TailAgnostic,
2308 bool &MaskAgnostic,
bool &AltFmt) {
2313 if (State < VTypeState::SeenSew &&
Identifier.consume_front(
"e")) {
2315 if (Identifier ==
"16alt") {
2318 }
else if (Identifier ==
"8alt") {
2328 State = VTypeState::SeenSew;
2332 if (State < VTypeState::SeenLmul &&
Identifier.consume_front(
"m")) {
2335 if (Identifier ==
"a" || Identifier ==
"u") {
2337 State = VTypeState::SeenMaskPolicy;
2348 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2349 unsigned MinLMUL = ELEN / 8;
2352 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2353 Twine(MinLMUL) +
" is reserved");
2356 State = VTypeState::SeenLmul;
2360 if (State < VTypeState::SeenTailPolicy &&
Identifier.starts_with(
"t")) {
2361 if (Identifier ==
"ta")
2362 TailAgnostic =
true;
2363 else if (Identifier ==
"tu")
2364 TailAgnostic =
false;
2368 State = VTypeState::SeenTailPolicy;
2372 if (State < VTypeState::SeenMaskPolicy &&
Identifier.starts_with(
"m")) {
2373 if (Identifier ==
"ma")
2374 MaskAgnostic =
true;
2375 else if (Identifier ==
"mu")
2376 MaskAgnostic =
false;
2380 State = VTypeState::SeenMaskPolicy;
2387ParseStatus RISCVAsmParser::parseVTypeI(
OperandVector &Operands) {
2393 bool Fractional =
false;
2394 bool TailAgnostic =
false;
2395 bool MaskAgnostic =
false;
2398 VTypeState State = VTypeState::SeenNothingYet;
2400 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2401 MaskAgnostic, AltFmt)) {
2403 if (State == VTypeState::SeenNothingYet)
2412 State == VTypeState::SeenNothingYet)
2413 return generateVTypeError(S);
2417 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2418 unsigned MaxSEW = ELEN / Lmul;
2420 if (MaxSEW >= 8 && Sew > MaxSEW)
2421 Warning(S,
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2422 " and LMUL == mf" + Twine(Lmul) +
2423 " may not be compatible with all RVV implementations");
2428 Operands.
push_back(RISCVOperand::createVType(VTypeI, S));
2432bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2433 if (STI->
hasFeature(RISCV::FeatureStdExtZvfbfa) ||
2434 STI->
hasFeature(RISCV::FeatureStdExtZvfofp8min) ||
2435 STI->
hasFeature(RISCV::FeatureVendorXSfvfbfexp16e))
2439 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2443 "e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2446ParseStatus RISCVAsmParser::parseXSfmmVType(
OperandVector &Operands) {
2463 if (Identifier !=
"16alt")
2492 Operands.
push_back(RISCVOperand::createVType(
2498 return generateXSfmmVTypeError(S);
2501bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
2502 return Error(ErrorLoc,
"operand must be e[8|16|16alt|32|64],w[1|2|4]");
2505ParseStatus RISCVAsmParser::parseMaskReg(
OperandVector &Operands) {
2509 StringRef
Name = getLexer().getTok().getIdentifier();
2510 if (!
Name.consume_back(
".t"))
2511 return Error(getLoc(),
"expected '.t' suffix");
2516 if (
Reg != RISCV::V0)
2519 SMLoc
E = getTok().getEndLoc();
2525ParseStatus RISCVAsmParser::parseGPRAsFPR64(
OperandVector &Operands) {
2526 if (!isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2529 return parseGPRAsFPR(Operands);
2532ParseStatus RISCVAsmParser::parseGPRAsFPR(
OperandVector &Operands) {
2536 StringRef
Name = getLexer().getTok().getIdentifier();
2542 SMLoc
E = getTok().getEndLoc();
2544 Operands.
push_back(RISCVOperand::createReg(
2545 Reg, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2549ParseStatus RISCVAsmParser::parseGPRPairAsFPR64(
OperandVector &Operands) {
2550 if (isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2556 StringRef
Name = getLexer().getTok().getIdentifier();
2562 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2565 if ((
Reg - RISCV::X0) & 1) {
2568 if (getSTI().hasFeature(RISCV::FeatureStdExtZfinx))
2569 return TokError(
"double precision floating point operands must use even "
2570 "numbered X register");
2575 SMLoc
E = getTok().getEndLoc();
2578 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2580 Reg, RISCV::sub_gpr_even,
2581 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2582 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2586template <
bool IsRV64>
2587ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands) {
2588 return parseGPRPair(Operands, IsRV64);
2591ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands,
2598 if (!IsRV64Inst && isRV64())
2604 StringRef
Name = getLexer().getTok().getIdentifier();
2610 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2613 if ((
Reg - RISCV::X0) & 1)
2614 return TokError(
"register must be even");
2617 SMLoc
E = getTok().getEndLoc();
2620 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2622 Reg, RISCV::sub_gpr_even,
2623 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2624 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E));
2628ParseStatus RISCVAsmParser::parseFRMArg(
OperandVector &Operands) {
2631 "operand must be a valid floating point rounding mode mnemonic");
2633 StringRef Str = getLexer().getTok().getIdentifier();
2638 "operand must be a valid floating point rounding mode mnemonic");
2640 Operands.
push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2645ParseStatus RISCVAsmParser::parseFenceArg(
OperandVector &Operands) {
2646 const AsmToken &Tok = getLexer().getTok();
2652 Operands.
push_back(RISCVOperand::createFenceArg(0, getLoc()));
2666 for (
char c : Str) {
2695 Operands.
push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2701 return TokError(
"operand must be formed of letters selected in-order from "
2705ParseStatus RISCVAsmParser::parseMemOpBaseReg(
OperandVector &Operands) {
2708 Operands.
push_back(RISCVOperand::createToken(
"(", getLoc()));
2710 if (!parseRegister(Operands).isSuccess())
2711 return Error(getLoc(),
"expected register");
2715 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
2720ParseStatus RISCVAsmParser::parseZeroOffsetMemOp(
OperandVector &Operands) {
2739 std::unique_ptr<RISCVOperand> OptionalImmOp;
2746 SMLoc ImmStart = getLoc();
2747 if (getParser().parseIntToken(ImmVal,
2748 "expected '(' or optional integer offset"))
2753 SMLoc ImmEnd = getLoc();
2756 ImmStart, ImmEnd, isRV64());
2760 OptionalImmOp ?
"expected '(' after optional integer offset"
2761 :
"expected '(' or optional integer offset"))
2764 if (!parseRegister(Operands).isSuccess())
2765 return Error(getLoc(),
"expected register");
2771 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2773 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2774 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2779ParseStatus RISCVAsmParser::parseRegReg(
OperandVector &Operands) {
2785 StringRef OffsetRegName = getLexer().getTok().getIdentifier();
2788 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(OffsetReg))
2789 return Error(getLoc(),
"expected GPR register");
2796 return Error(getLoc(),
"expected GPR register");
2798 StringRef BaseRegName = getLexer().getTok().getIdentifier();
2801 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(BaseReg))
2802 return Error(getLoc(),
"expected GPR register");
2808 Operands.
push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));
2820ParseStatus RISCVAsmParser::parseRegList(
OperandVector &Operands,
2821 bool MustIncludeS0) {
2833 return Error(getLoc(),
"invalid register");
2835 StringRef
RegName = getTok().getIdentifier();
2838 return Error(getLoc(),
"invalid register");
2841 UsesXRegs =
RegName[0] ==
'x';
2842 if (
Reg != RISCV::X1)
2843 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2844 }
else if (RegEnd == RISCV::X1) {
2845 if (
Reg != RISCV::X8 || (UsesXRegs != (
RegName[0] ==
'x')))
2846 return Error(getLoc(), Twine(
"register must be '") +
2847 (UsesXRegs ?
"x8" :
"s0") +
"'");
2848 }
else if (RegEnd == RISCV::X9 && UsesXRegs) {
2849 if (
Reg != RISCV::X18 || (
RegName[0] !=
'x'))
2850 return Error(getLoc(),
"register must be 'x18'");
2852 return Error(getLoc(),
"too many register ranges");
2859 SMLoc MinusLoc = getLoc();
2861 if (RegEnd == RISCV::X1)
2862 return Error(MinusLoc, Twine(
"register '") + (UsesXRegs ?
"x1" :
"ra") +
2863 "' cannot start a multiple register range");
2866 return Error(getLoc(),
"invalid register");
2868 StringRef
RegName = getTok().getIdentifier();
2871 return Error(getLoc(),
"invalid register");
2873 if (RegEnd == RISCV::X8) {
2874 if ((
Reg != RISCV::X9 &&
2876 (UsesXRegs != (
RegName[0] ==
'x'))) {
2878 return Error(getLoc(),
"register must be 'x9'");
2879 return Error(getLoc(),
"register must be in the range 's1' to 's11'");
2881 }
else if (RegEnd == RISCV::X18) {
2883 return Error(getLoc(),
2884 "register must be in the range 'x19' to 'x27'");
2897 if (RegEnd == RISCV::X26)
2898 return Error(S,
"invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "
2899 "x18-x26}' is not supported");
2905 return Error(S,
"register list must include 's0' or 'x8'");
2907 Operands.
push_back(RISCVOperand::createRegList(Encode, S));
2912ParseStatus RISCVAsmParser::parseZcmpStackAdj(
OperandVector &Operands,
2913 bool ExpectNegative) {
2922 auto *RegListOp =
static_cast<RISCVOperand *
>(Operands.
back().
get());
2923 if (!RegListOp->isRegList())
2926 unsigned RlistEncode = RegListOp->RegList.Encoding;
2930 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||
2931 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {
2932 int64_t
Lower = StackAdjBase;
2933 int64_t
Upper = StackAdjBase + 48;
2934 if (ExpectNegative) {
2939 return generateImmOutOfRangeError(S,
Lower,
Upper,
2940 "stack adjustment for register list must "
2941 "be a multiple of 16 bytes in the range");
2945 Operands.
push_back(RISCVOperand::createStackAdj(StackAdj, S));
2953bool RISCVAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
2957 MatchOperandParserImpl(Operands, Mnemonic,
true);
2964 if (parseRegister(Operands,
true).isSuccess())
2968 if (parseExpression(Operands).isSuccess()) {
2971 return !parseMemOpBaseReg(Operands).isSuccess();
2976 Error(getLoc(),
"unknown operand");
2980bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &Info,
2981 StringRef Name, SMLoc NameLoc,
2987 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
2991 Operands.
push_back(RISCVOperand::createToken(Name, NameLoc));
3000 if (parseOperand(Operands, Name))
3006 if (parseOperand(Operands, Name))
3010 if (getParser().parseEOL(
"unexpected token")) {
3011 getParser().eatToEndOfStatement();
3017bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
3021 Kind = RE->getSpecifier();
3022 Expr = RE->getSubExpr();
3031bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
3040ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
3041 StringRef IDVal = DirectiveID.
getString();
3043 if (IDVal ==
".option")
3044 return parseDirectiveOption();
3045 if (IDVal ==
".attribute")
3046 return parseDirectiveAttribute();
3047 if (IDVal ==
".insn")
3048 return parseDirectiveInsn(DirectiveID.
getLoc());
3049 if (IDVal ==
".variant_cc")
3050 return parseDirectiveVariantCC();
3055bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
3056 bool FromOptionDirective) {
3059 clearFeatureBits(Feature.Value, Feature.Key);
3066 raw_string_ostream OutputErrMsg(Buffer);
3067 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3068 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
3069 << ErrMsg.getMessage();
3072 return Error(Loc, OutputErrMsg.str());
3074 auto &ISAInfo = *ParseResult;
3077 if (ISAInfo->hasExtension(Feature.Key))
3078 setFeatureBits(Feature.Value, Feature.Key);
3080 if (FromOptionDirective) {
3081 if (ISAInfo->getXLen() == 32 && isRV64())
3082 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3083 else if (ISAInfo->getXLen() == 64 && !isRV64())
3084 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3087 if (ISAInfo->getXLen() == 32)
3088 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
3089 else if (ISAInfo->getXLen() == 64)
3090 setFeatureBits(RISCV::Feature64Bit,
"64bit");
3092 return Error(Loc,
"bad arch string " + Arch);
3094 Result = ISAInfo->toString();
3098bool RISCVAsmParser::parseDirectiveOption() {
3099 MCAsmParser &Parser = getParser();
3101 AsmToken Tok = Parser.
getTok();
3109 if (Option ==
"push") {
3113 getTargetStreamer().emitDirectiveOptionPush();
3118 if (Option ==
"pop") {
3123 getTargetStreamer().emitDirectiveOptionPop();
3124 if (popFeatureBits())
3125 return Error(StartLoc,
".option pop with no .option push");
3130 if (Option ==
"arch") {
3138 Type = RISCVOptionArchArgType::Plus;
3140 Type = RISCVOptionArchArgType::Minus;
3141 else if (!
Args.empty())
3143 "unexpected token, expected + or -");
3145 Type = RISCVOptionArchArgType::Full;
3149 "unexpected token, expected identifier");
3155 if (
Type == RISCVOptionArchArgType::Full) {
3157 if (resetToArch(Arch, Loc, Result,
true))
3166 Loc,
"extension version number parsing not currently implemented");
3169 if (!enableExperimentalExtension() &&
3171 return Error(Loc,
"unexpected experimental extensions");
3173 if (Ext == std::end(
RISCVFeatureKV) || StringRef(Ext->Key) != Feature)
3174 return Error(Loc,
"unknown extension feature");
3178 if (
Type == RISCVOptionArchArgType::Plus) {
3181 setFeatureBits(Ext->Value, Ext->Key);
3184 copySTI().setFeatureBits(OldFeatureBits);
3185 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3188 raw_string_ostream OutputErrMsg(Buffer);
3189 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3190 OutputErrMsg << ErrMsg.getMessage();
3193 return Error(Loc, OutputErrMsg.str());
3196 assert(
Type == RISCVOptionArchArgType::Minus);
3201 if (getSTI().hasFeature(Feature.Value) &&
3202 Feature.Implies.test(Ext->Value))
3203 return Error(Loc, Twine(
"can't disable ") + Ext->Key +
3204 " extension; " + Feature.Key +
3205 " extension requires " + Ext->Key +
3209 clearFeatureBits(Ext->Value, Ext->Key);
3216 getTargetStreamer().emitDirectiveOptionArch(Args);
3220 if (Option ==
"exact") {
3224 getTargetStreamer().emitDirectiveOptionExact();
3225 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3226 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3230 if (Option ==
"noexact") {
3234 getTargetStreamer().emitDirectiveOptionNoExact();
3235 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3236 setFeatureBits(RISCV::FeatureRelax,
"relax");
3240 if (Option ==
"rvc") {
3244 getTargetStreamer().emitDirectiveOptionRVC();
3245 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3249 if (Option ==
"norvc") {
3253 getTargetStreamer().emitDirectiveOptionNoRVC();
3254 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3255 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3259 if (Option ==
"pic") {
3263 getTargetStreamer().emitDirectiveOptionPIC();
3264 ParserOptions.IsPicEnabled =
true;
3268 if (Option ==
"nopic") {
3272 getTargetStreamer().emitDirectiveOptionNoPIC();
3273 ParserOptions.IsPicEnabled =
false;
3277 if (Option ==
"relax") {
3281 getTargetStreamer().emitDirectiveOptionRelax();
3282 setFeatureBits(RISCV::FeatureRelax,
"relax");
3286 if (Option ==
"norelax") {
3290 getTargetStreamer().emitDirectiveOptionNoRelax();
3291 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3297 "unknown option, expected 'push', 'pop', "
3298 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3299 "'exact', or 'noexact'");
3307bool RISCVAsmParser::parseDirectiveAttribute() {
3308 MCAsmParser &Parser = getParser();
3314 std::optional<unsigned> Ret =
3317 return Error(TagLoc,
"attribute name not recognised: " + Name);
3321 const MCExpr *AttrExpr;
3328 if (check(!CE, TagLoc,
"expected numeric constant"))
3331 Tag =
CE->getValue();
3337 StringRef StringValue;
3338 int64_t IntegerValue = 0;
3339 bool IsIntegerValue =
true;
3344 IsIntegerValue =
false;
3347 if (IsIntegerValue) {
3348 const MCExpr *ValueExpr;
3354 return Error(ValueExprLoc,
"expected numeric constant");
3355 IntegerValue =
CE->getValue();
3368 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3370 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3373 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3377 getTargetStreamer().emitTextAttribute(
Tag, Result);
3385 .
Cases({
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s"},
true)
3386 .Cases({
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj"},
3388 .
Cases({
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es"},
3397bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3398 MCAsmParser &Parser = getParser();
3405 std::optional<int64_t>
Length;
3415 return Error(ErrorLoc,
3416 "instruction lengths must be a non-zero multiple of two");
3420 return Error(ErrorLoc,
3421 "instruction lengths over 64 bits are not supported");
3427 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3432 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3433 return Error(ErrorLoc,
3434 "instruction length does not match the encoding");
3437 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3440 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3443 if (!getSTI().hasFeature(RISCV::FeatureStdExtZca) &&
3444 (EncodingDerivedLength == 2))
3445 return Error(ErrorLoc,
"compressed instructions are not allowed");
3447 if (getParser().parseEOL(
"invalid operand for instruction")) {
3448 getParser().eatToEndOfStatement();
3456 Opcode = RISCV::Insn16;
3459 Opcode = RISCV::Insn32;
3462 Opcode = RISCV::Insn48;
3465 Opcode = RISCV::Insn64;
3471 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3473 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3478 return Error(ErrorLoc,
"invalid instruction format");
3480 std::string FormatName = (
".insn_" +
Format).str();
3482 ParseInstructionInfo
Info;
3485 if (parseInstruction(Info, FormatName, L, Operands))
3490 return matchAndEmitInstruction(L, Opcode, Operands, Parser.
getStreamer(),
3497bool RISCVAsmParser::parseDirectiveVariantCC() {
3499 if (getParser().parseIdentifier(Name))
3500 return TokError(
"expected symbol name");
3503 getTargetStreamer().emitDirectiveVariantCC(
3508void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3511 const MCSubtargetInfo &STI = getSTI();
3512 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3515 ++RISCVNumInstrsCompressed;
3519void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3524 for (MCInst &Inst : Seq) {
3525 emitToStreamer(Out, Inst);
3529void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3530 const MCExpr *Symbol,
3532 unsigned SecondOpcode, SMLoc IDLoc,
3544 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3549 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3552 .addExpr(RefToLinkTmpLabel));
3555void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3569void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3579 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3580 emitAuipcInstPair(DestReg, DestReg, Symbol,
RISCV::S_GOT_HI, SecondOpcode,
3584void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3593 if (ParserOptions.IsPicEnabled)
3594 emitLoadGlobalAddress(Inst, IDLoc, Out);
3596 emitLoadLocalAddress(Inst, IDLoc, Out);
3599void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3609 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3610 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3611 SecondOpcode, IDLoc, Out);
3614void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3624 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3625 RISCV::ADDI, IDLoc, Out);
3628void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3629 SMLoc IDLoc, MCStreamer &Out,
3638 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3640 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3644 if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].
contains(TmpReg)) {
3645 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3646 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3654void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3655 int64_t Width, SMLoc IDLoc,
3664 const MCOperand &DestReg = Inst.
getOperand(0);
3665 const MCOperand &SourceReg = Inst.
getOperand(1);
3667 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3668 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3670 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3672 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3677 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3683void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
3690 emitToStreamer(Out, MCInstBuilder(Opcode)
3694 .addReg(MCRegister())
3696 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
3707 "The destination register should not be V0.");
3708 emitToStreamer(Out, MCInstBuilder(Opcode)
3714 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
3726 "The destination register should be V0.");
3728 "The temporary vector register should not be V0.");
3729 emitToStreamer(Out, MCInstBuilder(Opcode)
3733 .addReg(MCRegister())
3735 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3747 "The temporary vector register should not be V0.");
3748 emitToStreamer(Out, MCInstBuilder(Opcode)
3752 .addReg(MCRegister())
3754 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3759 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3764 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
3772bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
3774 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3777 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
3778 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3779 "%tprel_add specifier");
3785bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
3787 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
3790 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
3791 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
3792 "%tlsdesc_call specifier");
3798std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3799 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
3802std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3803 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3807std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3808 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3816 case RISCV::VLOXSEG2EI8_V:
3817 case RISCV::VLOXSEG2EI16_V:
3818 case RISCV::VLOXSEG2EI32_V:
3819 case RISCV::VLOXSEG2EI64_V:
3820 case RISCV::VLUXSEG2EI8_V:
3821 case RISCV::VLUXSEG2EI16_V:
3822 case RISCV::VLUXSEG2EI32_V:
3823 case RISCV::VLUXSEG2EI64_V:
3825 case RISCV::VLOXSEG3EI8_V:
3826 case RISCV::VLOXSEG3EI16_V:
3827 case RISCV::VLOXSEG3EI32_V:
3828 case RISCV::VLOXSEG3EI64_V:
3829 case RISCV::VLUXSEG3EI8_V:
3830 case RISCV::VLUXSEG3EI16_V:
3831 case RISCV::VLUXSEG3EI32_V:
3832 case RISCV::VLUXSEG3EI64_V:
3834 case RISCV::VLOXSEG4EI8_V:
3835 case RISCV::VLOXSEG4EI16_V:
3836 case RISCV::VLOXSEG4EI32_V:
3837 case RISCV::VLOXSEG4EI64_V:
3838 case RISCV::VLUXSEG4EI8_V:
3839 case RISCV::VLUXSEG4EI16_V:
3840 case RISCV::VLUXSEG4EI32_V:
3841 case RISCV::VLUXSEG4EI64_V:
3843 case RISCV::VLOXSEG5EI8_V:
3844 case RISCV::VLOXSEG5EI16_V:
3845 case RISCV::VLOXSEG5EI32_V:
3846 case RISCV::VLOXSEG5EI64_V:
3847 case RISCV::VLUXSEG5EI8_V:
3848 case RISCV::VLUXSEG5EI16_V:
3849 case RISCV::VLUXSEG5EI32_V:
3850 case RISCV::VLUXSEG5EI64_V:
3852 case RISCV::VLOXSEG6EI8_V:
3853 case RISCV::VLOXSEG6EI16_V:
3854 case RISCV::VLOXSEG6EI32_V:
3855 case RISCV::VLOXSEG6EI64_V:
3856 case RISCV::VLUXSEG6EI8_V:
3857 case RISCV::VLUXSEG6EI16_V:
3858 case RISCV::VLUXSEG6EI32_V:
3859 case RISCV::VLUXSEG6EI64_V:
3861 case RISCV::VLOXSEG7EI8_V:
3862 case RISCV::VLOXSEG7EI16_V:
3863 case RISCV::VLOXSEG7EI32_V:
3864 case RISCV::VLOXSEG7EI64_V:
3865 case RISCV::VLUXSEG7EI8_V:
3866 case RISCV::VLUXSEG7EI16_V:
3867 case RISCV::VLUXSEG7EI32_V:
3868 case RISCV::VLUXSEG7EI64_V:
3870 case RISCV::VLOXSEG8EI8_V:
3871 case RISCV::VLOXSEG8EI16_V:
3872 case RISCV::VLOXSEG8EI32_V:
3873 case RISCV::VLOXSEG8EI64_V:
3874 case RISCV::VLUXSEG8EI8_V:
3875 case RISCV::VLUXSEG8EI16_V:
3876 case RISCV::VLUXSEG8EI32_V:
3877 case RISCV::VLUXSEG8EI64_V:
3883 if (RISCVMCRegisterClasses[RISCV::VRM2RegClassID].
contains(
Reg))
3885 if (RISCVMCRegisterClasses[RISCV::VRM4RegClassID].
contains(
Reg))
3887 if (RISCVMCRegisterClasses[RISCV::VRM8RegClassID].
contains(
Reg))
3892bool RISCVAsmParser::validateInstruction(MCInst &Inst,
3896 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3897 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3900 if (DestReg == TempReg) {
3901 SMLoc Loc = Operands.
back()->getStartLoc();
3902 return Error(Loc,
"the temporary vector register cannot be the same as "
3903 "the destination register");
3907 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3908 Opcode == RISCV::TH_LWD) {
3913 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
3914 SMLoc Loc = Operands[1]->getStartLoc();
3915 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
3919 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
3923 SMLoc Loc = Operands[1]->getStartLoc();
3924 return Error(Loc,
"rs1 and rs2 must be different");
3928 const MCInstrDesc &MCID = MII.
get(Opcode);
3932 int DestIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
3936 const MCParsedAsmOperand *ParsedOp = Operands[1].get();
3937 if (!ParsedOp->
isReg()) {
3940 ParsedOp = Operands[2].get();
3942 assert(ParsedOp->
getReg() == DestReg &&
"Can't find parsed dest operand");
3946 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3950 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
3951 assert(VS2Idx >= 0 &&
"No vs2 operand?");
3952 unsigned CheckEncoding =
3955 for (
unsigned i = 0; i < std::max(NF, Lmul); i++) {
3956 if ((DestEncoding + i) == CheckEncoding)
3957 return Error(Loc,
"the destination vector register group cannot overlap"
3958 " the source vector register group");
3963 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
3967 unsigned CheckEncoding =
3969 for (
unsigned i = 0; i < Lmul; i++) {
3970 if ((DestEncoding + i) == CheckEncoding)
3972 "the destination vector register group cannot overlap"
3973 " the source vector register group");
3979 int VMIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vm);
3980 assert(VMIdx >= 0 &&
"No vm operand?");
3982 if (DestReg == RISCV::V0) {
3985 return Error(Loc,
"the destination vector register group cannot be V0");
3993 "Unexpected mask operand register");
3995 return Error(Loc,
"the destination vector register group cannot overlap"
3996 " the mask register");
4003bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
4011 case RISCV::PseudoC_ADDI_NOP: {
4013 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
4023 if (getSTI().hasFeature(RISCV::Feature64Bit))
4025 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV32)
4030 case RISCV::PACKW: {
4034 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV64)
4039 case RISCV::PseudoLLAImm:
4040 case RISCV::PseudoLAImm:
4041 case RISCV::PseudoLI: {
4047 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
4059 emitLoadImm(
Reg, Imm, Out);
4062 case RISCV::PseudoLLA:
4063 emitLoadLocalAddress(Inst, IDLoc, Out);
4065 case RISCV::PseudoLGA:
4066 emitLoadGlobalAddress(Inst, IDLoc, Out);
4068 case RISCV::PseudoLA:
4069 emitLoadAddress(Inst, IDLoc, Out);
4071 case RISCV::PseudoLA_TLS_IE:
4072 emitLoadTLSIEAddress(Inst, IDLoc, Out);
4074 case RISCV::PseudoLA_TLS_GD:
4075 emitLoadTLSGDAddress(Inst, IDLoc, Out);
4077 case RISCV::PseudoLB:
4078 case RISCV::PseudoQC_E_LB:
4079 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
4081 case RISCV::PseudoLBU:
4082 case RISCV::PseudoQC_E_LBU:
4083 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
4085 case RISCV::PseudoLH:
4086 case RISCV::PseudoQC_E_LH:
4087 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
4089 case RISCV::PseudoLHU:
4090 case RISCV::PseudoQC_E_LHU:
4091 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
4093 case RISCV::PseudoLW:
4094 case RISCV::PseudoQC_E_LW:
4095 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
4097 case RISCV::PseudoLWU:
4098 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
4100 case RISCV::PseudoLD:
4101 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
4103 case RISCV::PseudoLD_RV32:
4104 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
4106 case RISCV::PseudoFLH:
4107 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
4109 case RISCV::PseudoFLW:
4110 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
4112 case RISCV::PseudoFLD:
4113 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
4115 case RISCV::PseudoFLQ:
4116 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
4118 case RISCV::PseudoSB:
4119 case RISCV::PseudoQC_E_SB:
4120 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
4122 case RISCV::PseudoSH:
4123 case RISCV::PseudoQC_E_SH:
4124 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
4126 case RISCV::PseudoSW:
4127 case RISCV::PseudoQC_E_SW:
4128 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
4130 case RISCV::PseudoSD:
4131 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
4133 case RISCV::PseudoSD_RV32:
4134 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
4136 case RISCV::PseudoFSH:
4137 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
4139 case RISCV::PseudoFSW:
4140 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
4142 case RISCV::PseudoFSD:
4143 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4145 case RISCV::PseudoFSQ:
4146 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4148 case RISCV::PseudoAddTPRel:
4149 if (checkPseudoAddTPRel(Inst, Operands))
4152 case RISCV::PseudoTLSDESCCall:
4153 if (checkPseudoTLSDESCCall(Inst, Operands))
4156 case RISCV::PseudoSEXT_B:
4157 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4159 case RISCV::PseudoSEXT_H:
4160 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4162 case RISCV::PseudoZEXT_H:
4163 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4165 case RISCV::PseudoZEXT_W:
4166 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4168 case RISCV::PseudoVMSGEU_VX:
4169 case RISCV::PseudoVMSGEU_VX_M:
4170 case RISCV::PseudoVMSGEU_VX_M_T:
4171 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4173 case RISCV::PseudoVMSGE_VX:
4174 case RISCV::PseudoVMSGE_VX_M:
4175 case RISCV::PseudoVMSGE_VX_M_T:
4176 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4178 case RISCV::PseudoVMSGE_VI:
4179 case RISCV::PseudoVMSLT_VI: {
4183 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4185 emitToStreamer(Out, MCInstBuilder(
Opc)
4193 case RISCV::PseudoVMSGEU_VI:
4194 case RISCV::PseudoVMSLTU_VI: {
4201 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4204 emitToStreamer(Out, MCInstBuilder(
Opc)
4212 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4215 emitToStreamer(Out, MCInstBuilder(
Opc)
4225 case RISCV::PseudoCV_ELW:
4226 emitLoadStoreSymbol(Inst, RISCV::CV_ELW, IDLoc, Out,
false);
4230 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 unsigned getNFforLXSEG(unsigned Opcode)
unsigned getLMULFromVectorRegister(MCRegister Reg)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
StringRef getStringContents() const
Get the contents of a string token (without quotes).
bool is(TokenKind K) const
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Encoding
Size and signedness of expression operations' operands.
constexpr size_t size() const
void printExpr(raw_ostream &, const MCExpr &) const
const AsmToken & getTok()
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
MCStreamer & getStreamer()
static LLVM_ABI const 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.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
const FeatureBitset & ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
const MCSymbol * getAddSym() const
uint32_t getSpecifier() const
const MCSymbol * getSubSym() const
Ternary parse status returned by various parse* methods.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
static LLVM_ABI bool isSupportedExtensionFeature(StringRef Ext)
static LLVM_ABI std::string getTargetFeatureForExtension(StringRef Ext)
static LLVM_ABI llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseArchString(StringRef Arch, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck=true)
Parse RISC-V ISA info from arch string.
static const char * getRegisterName(MCRegister Reg)
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void push_back(const T &Elt)
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.