49#define DEBUG_TYPE "riscv-asm-parser"
52 "Number of RISC-V Compressed instructions emitted");
64struct ParserOptionsSet {
71 enum class VTypeState {
82 ParserOptionsSet ParserOptions;
84 SMLoc getLoc()
const {
return getParser().
getTok().
getLoc(); }
85 bool isRV64()
const {
return getSTI().hasFeature(RISCV::Feature64Bit); }
86 bool isRVE()
const {
return getSTI().hasFeature(RISCV::FeatureStdExtE); }
87 bool enableExperimentalExtension()
const {
88 return getSTI().hasFeature(RISCV::Experimental);
91 RISCVTargetStreamer &getTargetStreamer() {
92 assert(getParser().getStreamer().getTargetStreamer() &&
93 "do not have a target streamer");
94 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
95 return static_cast<RISCVTargetStreamer &
>(TS);
98 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
99 unsigned Kind)
override;
104 bool generateImmOutOfRangeError(SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
107 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
110 bool MatchingInlineAsm)
override;
113 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
114 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
115 SMLoc &EndLoc)
override;
117 bool parseInstruction(ParseInstructionInfo &
Info, StringRef Name,
120 ParseStatus parseDirective(AsmToken DirectiveID)
override;
122 bool parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
unsigned &Sew,
123 unsigned &Lmul,
bool &Fractional,
bool &TailAgnostic,
124 bool &MaskAgnostic,
bool &AltFmt);
125 bool generateVTypeError(SMLoc ErrorLoc);
127 bool generateXSfmmVTypeError(SMLoc ErrorLoc);
130 void emitToStreamer(MCStreamer &S,
const MCInst &Inst);
134 void emitLoadImm(MCRegister DestReg, int64_t
Value, MCStreamer &Out);
138 void emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
140 unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out);
143 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
146 void emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
149 void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
153 void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
157 void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
160 void emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
161 MCStreamer &Out,
bool HasTmpReg);
164 void emitPseudoExtend(MCInst &Inst,
bool SignExtend, int64_t Width,
165 SMLoc IDLoc, MCStreamer &Out);
168 void emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc, MCStreamer &Out);
193#define GET_ASSEMBLER_HEADER
194#include "RISCVGenAsmMatcher.inc"
220 return parseRegList(
Operands,
true);
227 bool ExpectNegative =
false);
229 return parseZcmpStackAdj(
Operands,
true);
233 bool parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
234 bool parseDataExpr(
const MCExpr *&Res)
override;
236 bool parseDirectiveOption();
237 bool parseDirectiveAttribute();
238 bool parseDirectiveInsn(SMLoc L);
239 bool parseDirectiveVariantCC();
244 bool resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
245 bool FromOptionDirective);
247 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
248 if (!(getSTI().hasFeature(Feature))) {
249 MCSubtargetInfo &STI = copySTI();
250 setAvailableFeatures(
255 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
256 if (getSTI().hasFeature(Feature)) {
257 MCSubtargetInfo &STI = copySTI();
258 setAvailableFeatures(
263 void pushFeatureBits() {
264 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
265 "These two stacks must be kept synchronized");
266 FeatureBitStack.push_back(getSTI().getFeatureBits());
267 ParserOptionsStack.push_back(ParserOptions);
270 bool popFeatureBits() {
271 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
272 "These two stacks must be kept synchronized");
273 if (FeatureBitStack.empty())
276 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
277 copySTI().setFeatureBits(FeatureBits);
278 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
280 ParserOptions = ParserOptionsStack.pop_back_val();
285 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
286 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
287 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
290 enum RISCVMatchResultTy :
unsigned {
291 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
292#define GET_OPERAND_DIAGNOSTIC_TYPES
293#include "RISCVGenAsmMatcher.inc"
294#undef GET_OPERAND_DIAGNOSTIC_TYPES
298 static bool isSymbolDiff(
const MCExpr *Expr);
300 RISCVAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
301 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
302 : MCTargetAsmParser(
Options, STI, MII) {
309 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
311 auto ABIName = StringRef(
Options.ABIName);
312 if (ABIName.ends_with(
"f") && !getSTI().hasFeature(RISCV::FeatureStdExtF)) {
313 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
314 "doesn't support the F instruction set extension (ignoring "
316 }
else if (ABIName.ends_with(
"d") &&
317 !getSTI().hasFeature(RISCV::FeatureStdExtD)) {
318 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
319 "doesn't support the D instruction set extension (ignoring "
332 getTargetStreamer().emitTargetAttributes(STI,
false);
398 MCRegister OffsetReg;
401 SMLoc StartLoc, EndLoc;
416 RISCVOperand(KindTy K) : Kind(
K) {}
419 RISCVOperand(
const RISCVOperand &o) : MCParsedAsmOperand() {
421 StartLoc =
o.StartLoc;
424 case KindTy::Register:
427 case KindTy::Expression:
430 case KindTy::FPImmediate:
436 case KindTy::SystemRegister:
448 case KindTy::RegList:
451 case KindTy::StackAdj:
452 StackAdj =
o.StackAdj;
460 bool isToken()
const override {
return Kind == KindTy::Token; }
461 bool isReg()
const override {
return Kind == KindTy::Register; }
462 bool isExpr()
const {
return Kind == KindTy::Expression; }
463 bool isV0Reg()
const {
464 return Kind == KindTy::Register &&
Reg.RegNum == RISCV::V0;
466 bool isAnyReg()
const {
467 return Kind == KindTy::Register &&
468 (RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.RegNum) ||
469 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg.RegNum) ||
470 RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg.RegNum));
472 bool isAnyRegC()
const {
473 return Kind == KindTy::Register &&
474 (RISCVMCRegisterClasses[RISCV::GPRCRegClassID].contains(
476 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
479 bool isImm()
const override {
return isExpr(); }
480 bool isMem()
const override {
return false; }
481 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
482 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
483 bool isRegList()
const {
return Kind == KindTy::RegList; }
484 bool isRegListS0()
const {
485 return Kind == KindTy::RegList && RegList.Encoding !=
RISCVZC::RA;
487 bool isStackAdj()
const {
return Kind == KindTy::StackAdj; }
490 return Kind == KindTy::Register &&
491 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.RegNum);
494 bool isGPRPair()
const {
495 return Kind == KindTy::Register &&
496 RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(
500 bool isGPRPairC()
const {
501 return Kind == KindTy::Register &&
502 RISCVMCRegisterClasses[RISCV::GPRPairCRegClassID].contains(
506 bool isGPRPairNoX0()
const {
507 return Kind == KindTy::Register &&
508 RISCVMCRegisterClasses[RISCV::GPRPairNoX0RegClassID].contains(
512 bool isGPRF16()
const {
513 return Kind == KindTy::Register &&
514 RISCVMCRegisterClasses[RISCV::GPRF16RegClassID].contains(
Reg.RegNum);
517 bool isGPRF32()
const {
518 return Kind == KindTy::Register &&
519 RISCVMCRegisterClasses[RISCV::GPRF32RegClassID].contains(
Reg.RegNum);
522 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
523 bool isGPRAsFPR16()
const {
return isGPRF16() &&
Reg.IsGPRAsFPR; }
524 bool isGPRAsFPR32()
const {
return isGPRF32() &&
Reg.IsGPRAsFPR; }
525 bool isGPRPairAsFPR64()
const {
return isGPRPair() &&
Reg.IsGPRAsFPR; }
527 static bool evaluateConstantExpr(
const MCExpr *Expr, int64_t &Imm) {
529 Imm =
CE->getValue();
538 template <
int N>
bool isBareSimmNLsb0()
const {
543 if (evaluateConstantExpr(
getExpr(), Imm))
544 return isShiftedInt<
N - 1, 1>(fixImmediateForRV32(Imm, isRV64Expr()));
547 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
553 template <
int N>
bool isBareSimmN()
const {
558 if (evaluateConstantExpr(
getExpr(), Imm))
559 return isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
562 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
568 bool isBareSymbol()
const {
571 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
575 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
579 bool isCallSymbol()
const {
582 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
586 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
587 VK == ELF::R_RISCV_CALL_PLT;
590 bool isPseudoJumpSymbol()
const {
593 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
597 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
598 VK == ELF::R_RISCV_CALL_PLT;
601 bool isTPRelAddSymbol()
const {
604 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
608 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
609 VK == ELF::R_RISCV_TPREL_ADD;
612 bool isTLSDESCCallSymbol()
const {
615 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
619 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
620 VK == ELF::R_RISCV_TLSDESC_CALL;
623 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
627 bool isVTypeI10()
const {
628 if (Kind == KindTy::VType)
632 bool isVTypeI11()
const {
633 if (Kind == KindTy::VType)
638 bool isXSfmmVType()
const {
644 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
647 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
648 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
652 bool isLoadFPImm()
const {
655 if (Kind != KindTy::FPImmediate)
658 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
661 return Idx >= 0 && Idx != 1;
664 bool isImmXLenLI()
const {
670 if (evaluateConstantExpr(
getExpr(), Imm))
673 return RISCVAsmParser::isSymbolDiff(
getExpr());
676 bool isImmXLenLI_Restricted()
const {
680 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
682 return IsConstantImm &&
686 template <
unsigned N>
bool isUImm()
const {
690 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
694 template <
unsigned N,
unsigned S>
bool isUImmShifted()
const {
698 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
702 template <
class Pred>
bool isUImmPred(Pred p)
const {
706 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
707 return IsConstantImm &&
p(Imm);
710 bool isUImmLog2XLen()
const {
711 if (isExpr() && isRV64Expr())
716 bool isUImmLog2XLenNonZero()
const {
717 if (isExpr() && isRV64Expr())
718 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<6>(Imm); });
719 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<5>(Imm); });
722 bool isUImmLog2XLenHalf()
const {
723 if (isExpr() && isRV64Expr())
728 bool isUImm1()
const {
return isUImm<1>(); }
729 bool isUImm2()
const {
return isUImm<2>(); }
730 bool isUImm3()
const {
return isUImm<3>(); }
731 bool isUImm4()
const {
return isUImm<4>(); }
732 bool isUImm5()
const {
return isUImm<5>(); }
733 bool isUImm6()
const {
return isUImm<6>(); }
734 bool isUImm7()
const {
return isUImm<7>(); }
735 bool isUImm8()
const {
return isUImm<8>(); }
736 bool isUImm9()
const {
return isUImm<9>(); }
737 bool isUImm10()
const {
return isUImm<10>(); }
738 bool isUImm11()
const {
return isUImm<11>(); }
739 bool isUImm16()
const {
return isUImm<16>(); }
740 bool isUImm20()
const {
return isUImm<20>(); }
741 bool isUImm32()
const {
return isUImm<32>(); }
742 bool isUImm48()
const {
return isUImm<48>(); }
743 bool isUImm64()
const {
return isUImm<64>(); }
745 bool isUImm5NonZero()
const {
746 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<5>(Imm); });
749 bool isUImm5GT3()
const {
750 return isUImmPred([](int64_t Imm) {
return isUInt<5>(Imm) &&
Imm > 3; });
753 bool isUImm5Plus1()
const {
755 [](int64_t Imm) {
return Imm > 0 &&
isUInt<5>(Imm - 1); });
758 bool isUImm5GE6Plus1()
const {
760 [](int64_t Imm) {
return Imm >= 6 &&
isUInt<5>(Imm - 1); });
763 bool isUImm5Slist()
const {
764 return isUImmPred([](int64_t Imm) {
765 return (Imm == 0) || (
Imm == 1) || (Imm == 2) || (
Imm == 4) ||
766 (Imm == 8) || (
Imm == 16) || (Imm == 15) || (
Imm == 31);
770 bool isUImm8GE32()
const {
771 return isUImmPred([](int64_t Imm) {
return isUInt<8>(Imm) &&
Imm >= 32; });
774 bool isRnumArg()
const {
776 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(10); });
779 bool isRnumArg_0_7()
const {
781 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(7); });
784 bool isRnumArg_1_10()
const {
786 [](int64_t Imm) {
return Imm >= INT64_C(1) &&
Imm <= INT64_C(10); });
789 bool isRnumArg_2_14()
const {
791 [](int64_t Imm) {
return Imm >= INT64_C(2) &&
Imm <= INT64_C(14); });
794 template <
unsigned N>
bool isSImm()
const {
798 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
799 return IsConstantImm &&
isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
802 template <
class Pred>
bool isSImmPred(Pred p)
const {
806 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
807 return IsConstantImm &&
p(fixImmediateForRV32(Imm, isRV64Expr()));
810 bool isSImm5()
const {
return isSImm<5>(); }
811 bool isSImm6()
const {
return isSImm<6>(); }
812 bool isSImm10()
const {
return isSImm<10>(); }
813 bool isSImm11()
const {
return isSImm<11>(); }
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 isSImm12()
const {
867 if (evaluateConstantExpr(
getExpr(), Imm))
868 return isInt<12>(fixImmediateForRV32(Imm, isRV64Expr()));
871 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
874 VK == ELF::R_RISCV_TLSDESC_ADD_LO12);
877 bool isSImm12Lsb00000()
const {
881 bool isSImm10Lsb0000NonZero()
const {
886 bool isSImm16NonZero()
const {
887 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<16>(Imm); });
890 bool isUImm16NonZero()
const {
891 return isUImmPred([](int64_t Imm) {
return isUInt<16>(Imm) &&
Imm != 0; });
894 bool isSImm20LI()
const {
899 if (evaluateConstantExpr(
getExpr(), Imm))
900 return isInt<20>(fixImmediateForRV32(Imm, isRV64Expr()));
903 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
907 bool isSImm8Unsigned()
const {
return isSImm<8>() || isUImm<8>(); }
908 bool isSImm10Unsigned()
const {
return isSImm<10>() || isUImm<10>(); }
910 bool isUImm20LUI()
const {
915 if (evaluateConstantExpr(
getExpr(), Imm))
919 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
920 (VK == ELF::R_RISCV_HI20 || VK == ELF::R_RISCV_TPREL_HI20);
923 bool isUImm20AUIPC()
const {
928 if (evaluateConstantExpr(
getExpr(), Imm))
932 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
933 (VK == ELF::R_RISCV_PCREL_HI20 || VK == ELF::R_RISCV_GOT_HI20 ||
934 VK == ELF::R_RISCV_TLS_GOT_HI20 || VK == ELF::R_RISCV_TLS_GD_HI20 ||
935 VK == ELF::R_RISCV_TLSDESC_HI20);
938 bool isImmZero()
const {
939 return isUImmPred([](int64_t Imm) {
return 0 ==
Imm; });
942 bool isImmThree()
const {
943 return isUImmPred([](int64_t Imm) {
return 3 ==
Imm; });
946 bool isImmFour()
const {
947 return isUImmPred([](int64_t Imm) {
return 4 ==
Imm; });
950 bool isImm5Zibi()
const {
952 [](int64_t Imm) {
return (Imm != 0 &&
isUInt<5>(Imm)) ||
Imm == -1; });
955 bool isSImm5Plus1()
const {
960 bool isSImm18()
const {
961 return isSImmPred([](int64_t Imm) {
return isInt<18>(Imm); });
964 bool isSImm18Lsb0()
const {
968 bool isSImm19Lsb00()
const {
972 bool isSImm20Lsb000()
const {
976 bool isSImm32Lsb0()
const {
981 SMLoc getStartLoc()
const override {
return StartLoc; }
983 SMLoc getEndLoc()
const override {
return EndLoc; }
986 bool isRV64Expr()
const {
987 assert(Kind == KindTy::Expression &&
"Invalid type access!");
991 MCRegister
getReg()
const override {
992 assert(Kind == KindTy::Register &&
"Invalid type access!");
996 StringRef getSysReg()
const {
997 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
998 return StringRef(SysReg.Data, SysReg.Length);
1001 const MCExpr *
getExpr()
const {
1002 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1006 uint64_t getFPConst()
const {
1007 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1012 assert(Kind == KindTy::Token &&
"Invalid type access!");
1016 unsigned getVType()
const {
1017 assert(Kind == KindTy::VType &&
"Invalid type access!");
1022 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1026 unsigned getFence()
const {
1027 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1031 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1040 case KindTy::Expression:
1043 OS <<
' ' << (Expr.IsRV64 ?
"rv64" :
"rv32") <<
'>';
1045 case KindTy::FPImmediate:
1046 OS <<
"<fpimm: " << FPImm.Val <<
">";
1048 case KindTy::Register:
1050 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1055 case KindTy::SystemRegister:
1056 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1065 roundingModeToString(getFRM());
1073 case KindTy::RegList:
1078 case KindTy::StackAdj:
1079 OS <<
"<stackadj: ";
1083 case KindTy::RegReg:
1084 OS <<
"<RegReg: BaseReg " <<
RegName(
RegReg.BaseReg) <<
" OffsetReg "
1090 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1091 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1098 static std::unique_ptr<RISCVOperand>
1099 createReg(MCRegister
Reg, SMLoc S, SMLoc
E,
bool IsGPRAsFPR =
false) {
1100 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1101 Op->Reg.RegNum =
Reg;
1102 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1108 static std::unique_ptr<RISCVOperand> createExpr(
const MCExpr *Val, SMLoc S,
1109 SMLoc
E,
bool IsRV64) {
1110 auto Op = std::make_unique<RISCVOperand>(KindTy::Expression);
1111 Op->Expr.Expr = Val;
1112 Op->Expr.IsRV64 = IsRV64;
1118 static std::unique_ptr<RISCVOperand> createFPImm(uint64_t Val, SMLoc S) {
1119 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1120 Op->FPImm.Val = Val;
1126 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1127 unsigned Encoding) {
1128 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1129 Op->SysReg.Data = Str.data();
1130 Op->SysReg.Length = Str.size();
1137 static std::unique_ptr<RISCVOperand>
1139 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1146 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val, SMLoc S) {
1147 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1148 Op->Fence.Val = Val;
1154 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI, SMLoc S) {
1155 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1156 Op->VType.Val = VTypeI;
1162 static std::unique_ptr<RISCVOperand> createRegList(
unsigned RlistEncode,
1164 auto Op = std::make_unique<RISCVOperand>(KindTy::RegList);
1170 static std::unique_ptr<RISCVOperand>
1171 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {
1172 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1174 Op->RegReg.OffsetReg = OffsetReg;
1180 static std::unique_ptr<RISCVOperand> createStackAdj(
unsigned StackAdj, SMLoc S) {
1181 auto Op = std::make_unique<RISCVOperand>(KindTy::StackAdj);
1182 Op->StackAdj.Val = StackAdj;
1187 static void addExpr(MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1188 assert(Expr &&
"Expr shouldn't be null!");
1190 bool IsConstant = evaluateConstantExpr(Expr, Imm);
1200 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1201 assert(
N == 1 &&
"Invalid number of operands!");
1205 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1206 assert(
N == 1 &&
"Invalid number of operands!");
1207 addExpr(Inst,
getExpr(), isRV64Expr());
1210 void addSImm8UnsignedOperands(MCInst &Inst,
unsigned N)
const {
1211 assert(
N == 1 &&
"Invalid number of operands!");
1218 void addSImm10UnsignedOperands(MCInst &Inst,
unsigned N)
const {
1219 assert(
N == 1 &&
"Invalid number of operands!");
1226 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
1227 assert(
N == 1 &&
"Invalid number of operands!");
1229 addExpr(Inst,
getExpr(), isRV64Expr());
1234 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1238 void addFenceArgOperands(MCInst &Inst,
unsigned N)
const {
1239 assert(
N == 1 &&
"Invalid number of operands!");
1243 void addCSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
1244 assert(
N == 1 &&
"Invalid number of operands!");
1251 void addVTypeIOperands(MCInst &Inst,
unsigned N)
const {
1252 assert(
N == 1 &&
"Invalid number of operands!");
1254 if (Kind == KindTy::Expression) {
1255 [[maybe_unused]]
bool IsConstantImm =
1256 evaluateConstantExpr(
getExpr(), Imm);
1257 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1264 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1265 assert(
N == 1 &&
"Invalid number of operands!");
1269 void addRegRegOperands(MCInst &Inst,
unsigned N)
const {
1270 assert(
N == 2 &&
"Invalid number of operands!");
1275 void addStackAdjOperands(MCInst &Inst,
unsigned N)
const {
1276 assert(
N == 1 &&
"Invalid number of operands!");
1280 void addFRMArgOperands(MCInst &Inst,
unsigned N)
const {
1281 assert(
N == 1 &&
"Invalid number of operands!");
1287#define GET_REGISTER_MATCHER
1288#define GET_SUBTARGET_FEATURE_NAME
1289#define GET_MATCHER_IMPLEMENTATION
1290#define GET_MNEMONIC_SPELL_CHECKER
1291#include "RISCVGenAsmMatcher.inc"
1294 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1295 return Reg - RISCV::F0_D + RISCV::F0_H;
1299 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1300 return Reg - RISCV::F0_D + RISCV::F0_F;
1304 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1305 return Reg - RISCV::F0_D + RISCV::F0_Q;
1310 unsigned RegClassID;
1311 if (Kind == MCK_VRM2)
1312 RegClassID = RISCV::VRM2RegClassID;
1313 else if (Kind == MCK_VRM4)
1314 RegClassID = RISCV::VRM4RegClassID;
1315 else if (Kind == MCK_VRM8)
1316 RegClassID = RISCV::VRM8RegClassID;
1320 &RISCVMCRegisterClasses[RegClassID]);
1325 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1327 return Match_InvalidOperand;
1329 MCRegister
Reg =
Op.getReg();
1331 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg);
1333 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg);
1334 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg);
1336 if (IsRegFPR64 && Kind == MCK_FPR128) {
1338 return Match_Success;
1342 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1343 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1345 return Match_Success;
1349 if (IsRegFPR64 && Kind == MCK_FPR16) {
1351 return Match_Success;
1353 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1354 Op.Reg.RegNum =
Reg - RISCV::X0 + RISCV::X0_H;
1355 return Match_Success;
1357 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1358 Op.Reg.RegNum =
Reg - RISCV::X0 + RISCV::X0_W;
1359 return Match_Success;
1366 if (RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg) &&
1367 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1369 return Match_Success;
1373 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1376 return Match_InvalidOperand;
1377 return Match_Success;
1379 return Match_InvalidOperand;
1382bool RISCVAsmParser::generateImmOutOfRangeError(
1383 SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
1384 const Twine &Msg =
"immediate must be an integer in the range") {
1385 return Error(ErrorLoc, Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]");
1388bool RISCVAsmParser::generateImmOutOfRangeError(
1390 const Twine &Msg =
"immediate must be an integer in the range") {
1391 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[ErrorInfo]).getStartLoc();
1392 return generateImmOutOfRangeError(ErrorLoc,
Lower,
Upper, Msg);
1395bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1398 uint64_t &ErrorInfo,
1399 bool MatchingInlineAsm) {
1401 FeatureBitset MissingFeatures;
1403 auto Result = MatchInstructionImpl(
Operands, Inst, ErrorInfo, MissingFeatures,
1409 if (validateInstruction(Inst,
Operands))
1411 return processInstruction(Inst, IDLoc,
Operands, Out);
1412 case Match_MissingFeature: {
1413 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1414 bool FirstFeature =
true;
1415 std::string Msg =
"instruction requires the following:";
1416 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1417 if (MissingFeatures[i]) {
1418 Msg += FirstFeature ?
" " :
", ";
1420 FirstFeature =
false;
1423 return Error(IDLoc, Msg);
1425 case Match_MnemonicFail: {
1426 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1427 std::string Suggestion = RISCVMnemonicSpellCheck(
1429 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1431 case Match_InvalidOperand: {
1432 SMLoc ErrorLoc = IDLoc;
1433 if (ErrorInfo != ~0ULL) {
1435 return Error(ErrorLoc,
"too few operands for instruction");
1437 ErrorLoc = ((RISCVOperand &)*
Operands[ErrorInfo]).getStartLoc();
1438 if (ErrorLoc == SMLoc())
1441 return Error(ErrorLoc,
"invalid operand for instruction");
1448 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1449 SMLoc ErrorLoc = IDLoc;
1450 if (ErrorInfo != ~0ULL && ErrorInfo >=
Operands.size())
1451 return Error(ErrorLoc,
"too few operands for instruction");
1457 case Match_InvalidImmXLenLI:
1459 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[ErrorInfo]).getStartLoc();
1460 return Error(ErrorLoc,
"operand must be a constant 64-bit integer");
1462 return generateImmOutOfRangeError(
Operands, ErrorInfo,
1463 std::numeric_limits<int32_t>::min(),
1464 std::numeric_limits<uint32_t>::max());
1465 case Match_InvalidImmXLenLI_Restricted:
1467 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[ErrorInfo]).getStartLoc();
1468 return Error(ErrorLoc,
"operand either must be a constant 64-bit integer "
1469 "or a bare symbol name");
1471 return generateImmOutOfRangeError(
1472 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1473 std::numeric_limits<uint32_t>::max(),
1474 "operand either must be a bare symbol name or an immediate integer in "
1476 case Match_InvalidUImmLog2XLen:
1478 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 6) - 1);
1479 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 5) - 1);
1480 case Match_InvalidUImmLog2XLenNonZero:
1482 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 6) - 1);
1483 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 5) - 1);
1484 case Match_InvalidUImm1:
1485 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 1) - 1);
1486 case Match_InvalidUImm2:
1487 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 2) - 1);
1488 case Match_InvalidUImm2Lsb0:
1489 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, 2,
1490 "immediate must be one of");
1491 case Match_InvalidUImm3:
1492 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 3) - 1);
1493 case Match_InvalidUImm4:
1494 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 4) - 1);
1495 case Match_InvalidUImm5:
1496 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 5) - 1);
1497 case Match_InvalidUImm5NonZero:
1498 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 5) - 1);
1499 case Match_InvalidUImm5GT3:
1500 return generateImmOutOfRangeError(
Operands, ErrorInfo, 4, (1 << 5) - 1);
1501 case Match_InvalidUImm5Plus1:
1502 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 5));
1503 case Match_InvalidUImm5GE6Plus1:
1504 return generateImmOutOfRangeError(
Operands, ErrorInfo, 6, (1 << 5));
1505 case Match_InvalidUImm5Slist: {
1506 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[ErrorInfo]).getStartLoc();
1507 return Error(ErrorLoc,
1508 "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31");
1510 case Match_InvalidUImm6:
1511 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 6) - 1);
1512 case Match_InvalidUImm7:
1513 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 7) - 1);
1514 case Match_InvalidUImm8:
1515 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 8) - 1);
1516 case Match_InvalidUImm8GE32:
1517 return generateImmOutOfRangeError(
Operands, ErrorInfo, 32, (1 << 8) - 1);
1518 case Match_InvalidSImm5:
1519 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 4),
1521 case Match_InvalidSImm5NonZero:
1522 return generateImmOutOfRangeError(
1523 Operands, ErrorInfo, -(1 << 4), (1 << 4) - 1,
1524 "immediate must be non-zero in the range");
1525 case Match_InvalidSImm6:
1526 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 5),
1528 case Match_InvalidSImm6NonZero:
1529 return generateImmOutOfRangeError(
1530 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
1531 "immediate must be non-zero in the range");
1532 case Match_InvalidCLUIImm:
1533 return generateImmOutOfRangeError(
1534 Operands, ErrorInfo, 1, (1 << 5) - 1,
1535 "immediate must be in [0xfffe0, 0xfffff] or");
1536 case Match_InvalidUImm5Lsb0:
1537 return generateImmOutOfRangeError(
1538 Operands, ErrorInfo, 0, (1 << 5) - 2,
1539 "immediate must be a multiple of 2 bytes in the range");
1540 case Match_InvalidUImm6Lsb0:
1541 return generateImmOutOfRangeError(
1542 Operands, ErrorInfo, 0, (1 << 6) - 2,
1543 "immediate must be a multiple of 2 bytes in the range");
1544 case Match_InvalidUImm7Lsb00:
1545 return generateImmOutOfRangeError(
1546 Operands, ErrorInfo, 0, (1 << 7) - 4,
1547 "immediate must be a multiple of 4 bytes in the range");
1548 case Match_InvalidUImm8Lsb00:
1549 return generateImmOutOfRangeError(
1550 Operands, ErrorInfo, 0, (1 << 8) - 4,
1551 "immediate must be a multiple of 4 bytes in the range");
1552 case Match_InvalidUImm8Lsb000:
1553 return generateImmOutOfRangeError(
1554 Operands, ErrorInfo, 0, (1 << 8) - 8,
1555 "immediate must be a multiple of 8 bytes in the range");
1556 case Match_InvalidUImm9:
1557 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 9) - 1,
1558 "immediate offset must be in the range");
1559 case Match_InvalidBareSImm9Lsb0:
1560 return generateImmOutOfRangeError(
1561 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
1562 "immediate must be a multiple of 2 bytes in the range");
1563 case Match_InvalidUImm9Lsb000:
1564 return generateImmOutOfRangeError(
1565 Operands, ErrorInfo, 0, (1 << 9) - 8,
1566 "immediate must be a multiple of 8 bytes in the range");
1567 case Match_InvalidSImm8Unsigned:
1568 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 7),
1570 case Match_InvalidSImm10:
1571 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 9),
1573 case Match_InvalidSImm10Unsigned:
1574 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 9),
1576 case Match_InvalidUImm10Lsb00NonZero:
1577 return generateImmOutOfRangeError(
1578 Operands, ErrorInfo, 4, (1 << 10) - 4,
1579 "immediate must be a multiple of 4 bytes in the range");
1580 case Match_InvalidSImm10Lsb0000NonZero:
1581 return generateImmOutOfRangeError(
1582 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
1583 "immediate must be a multiple of 16 bytes and non-zero in the range");
1584 case Match_InvalidSImm11:
1585 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 10),
1587 case Match_InvalidBareSImm11Lsb0:
1588 return generateImmOutOfRangeError(
1589 Operands, ErrorInfo, -(1 << 10), (1 << 10) - 2,
1590 "immediate must be a multiple of 2 bytes in the range");
1591 case Match_InvalidUImm10:
1592 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 10) - 1);
1593 case Match_InvalidUImm11:
1594 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 11) - 1);
1595 case Match_InvalidUImm14Lsb00:
1596 return generateImmOutOfRangeError(
1597 Operands, ErrorInfo, 0, (1 << 14) - 4,
1598 "immediate must be a multiple of 4 bytes in the range");
1599 case Match_InvalidUImm16NonZero:
1600 return generateImmOutOfRangeError(
Operands, ErrorInfo, 1, (1 << 16) - 1);
1601 case Match_InvalidSImm12:
1602 return generateImmOutOfRangeError(
1603 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
1604 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo specifier or an "
1605 "integer in the range");
1606 case Match_InvalidBareSImm12Lsb0:
1607 return generateImmOutOfRangeError(
1608 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
1609 "immediate must be a multiple of 2 bytes in the range");
1610 case Match_InvalidSImm12Lsb00000:
1611 return generateImmOutOfRangeError(
1612 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 32,
1613 "immediate must be a multiple of 32 bytes in the range");
1614 case Match_InvalidBareSImm13Lsb0:
1615 return generateImmOutOfRangeError(
1616 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
1617 "immediate must be a multiple of 2 bytes in the range");
1618 case Match_InvalidSImm16:
1619 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 15),
1621 case Match_InvalidSImm16NonZero:
1622 return generateImmOutOfRangeError(
1623 Operands, ErrorInfo, -(1 << 15), (1 << 15) - 1,
1624 "immediate must be non-zero in the range");
1625 case Match_InvalidSImm20LI:
1626 return generateImmOutOfRangeError(
1627 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 1,
1628 "operand must be a symbol with a %qc.abs20 specifier or an integer "
1630 case Match_InvalidUImm20LUI:
1631 return generateImmOutOfRangeError(
1632 Operands, ErrorInfo, 0, (1 << 20) - 1,
1633 "operand must be a symbol with "
1634 "%hi/%tprel_hi specifier or an integer in "
1636 case Match_InvalidUImm20:
1637 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 20) - 1);
1638 case Match_InvalidUImm20AUIPC:
1639 return generateImmOutOfRangeError(
1640 Operands, ErrorInfo, 0, (1 << 20) - 1,
1641 "operand must be a symbol with a "
1642 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
1644 "an integer in the range");
1645 case Match_InvalidBareSImm21Lsb0:
1646 return generateImmOutOfRangeError(
1647 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
1648 "immediate must be a multiple of 2 bytes in the range");
1649 case Match_InvalidCSRSystemRegister: {
1650 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, (1 << 12) - 1,
1651 "operand must be a valid system register "
1652 "name or an integer in the range");
1654 case Match_InvalidImm5Zibi:
1655 return generateImmOutOfRangeError(
1656 Operands, ErrorInfo, -1, (1 << 5) - 1,
1657 "immediate must be non-zero in the range");
1658 case Match_InvalidVTypeI: {
1659 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[ErrorInfo]).getStartLoc();
1660 return generateVTypeError(ErrorLoc);
1662 case Match_InvalidSImm5Plus1: {
1663 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 4) + 1,
1665 "immediate must be in the range");
1667 case Match_InvalidSImm18:
1668 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 17),
1670 case Match_InvalidSImm18Lsb0:
1671 return generateImmOutOfRangeError(
1672 Operands, ErrorInfo, -(1 << 17), (1 << 17) - 2,
1673 "immediate must be a multiple of 2 bytes in the range");
1674 case Match_InvalidSImm19Lsb00:
1675 return generateImmOutOfRangeError(
1676 Operands, ErrorInfo, -(1 << 18), (1 << 18) - 4,
1677 "immediate must be a multiple of 4 bytes in the range");
1678 case Match_InvalidSImm20Lsb000:
1679 return generateImmOutOfRangeError(
1680 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 8,
1681 "immediate must be a multiple of 8 bytes in the range");
1682 case Match_InvalidSImm26:
1683 return generateImmOutOfRangeError(
Operands, ErrorInfo, -(1 << 25),
1686 case Match_InvalidBareSymbolQC_E_LI:
1689 case Match_InvalidBareSImm32:
1690 return generateImmOutOfRangeError(
Operands, ErrorInfo,
1691 std::numeric_limits<int32_t>::min(),
1692 std::numeric_limits<uint32_t>::max());
1693 case Match_InvalidBareSImm32Lsb0:
1694 return generateImmOutOfRangeError(
1695 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1696 std::numeric_limits<int32_t>::max() - 1,
1697 "operand must be a multiple of 2 bytes in the range");
1698 case Match_InvalidRnumArg: {
1699 return generateImmOutOfRangeError(
Operands, ErrorInfo, 0, 10);
1701 case Match_InvalidStackAdj: {
1702 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[ErrorInfo]).getStartLoc();
1705 "stack adjustment is invalid for this instruction and register list");
1709 if (
const char *MatchDiag = getMatchKindDiag((RISCVMatchResultTy)Result)) {
1710 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[ErrorInfo]).getStartLoc();
1711 return Error(ErrorLoc, MatchDiag);
1721MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name)
const {
1730 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1731 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1732 static_assert(RISCV::F0_D < RISCV::F0_Q,
"FPR matching must be updated");
1735 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1740bool RISCVAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1742 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1743 return Error(StartLoc,
"invalid register name");
1747ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1749 const AsmToken &Tok = getParser().getTok();
1752 StringRef
Name = getLexer().getTok().getIdentifier();
1764 SMLoc FirstS = getLoc();
1765 bool HadParens =
false;
1772 size_t ReadCount = getLexer().peekTokens(Buf);
1775 LParen = getParser().getTok();
1780 switch (getLexer().getKind()) {
1783 getLexer().UnLex(LParen);
1786 StringRef
Name = getLexer().getTok().getIdentifier();
1791 getLexer().UnLex(LParen);
1795 Operands.push_back(RISCVOperand::createToken(
"(", FirstS));
1797 SMLoc
E = getTok().getEndLoc();
1799 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
1804 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
1815 switch (getLexer().getKind()) {
1825 if (getParser().parseExpression(Res,
E))
1830 int64_t
Imm =
CE->getValue();
1832 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1841 if (getParser().parseIdentifier(Identifier))
1844 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1847 "Unexpected opcode");
1850 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1860 return generateImmOutOfRangeError(
1862 "opcode must be a valid opcode name or an immediate in the range");
1870 switch (getLexer().getKind()) {
1880 if (getParser().parseExpression(Res,
E))
1885 int64_t
Imm =
CE->getValue();
1886 if (Imm >= 0 && Imm <= 2) {
1887 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1896 if (getParser().parseIdentifier(Identifier))
1900 if (Identifier ==
"C0")
1902 else if (Identifier ==
"C1")
1904 else if (Identifier ==
"C2")
1911 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1920 return generateImmOutOfRangeError(
1922 "opcode must be a valid opcode name or an immediate in the range");
1929 auto SysRegFromConstantInt = [
this](
const MCExpr *
E, SMLoc S) {
1931 int64_t
Imm =
CE->getValue();
1933 auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
1937 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
1940 return RISCVOperand::createSysReg(
Reg.Name, S, Imm);
1944 return RISCVOperand::createSysReg(
"", S, Imm);
1947 return std::unique_ptr<RISCVOperand>();
1950 switch (getLexer().getKind()) {
1960 if (getParser().parseExpression(Res))
1963 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
1964 Operands.push_back(std::move(SysOpnd));
1968 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1972 if (getParser().parseIdentifier(Identifier))
1975 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1978 if (SysReg->IsDeprecatedName) {
1980 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
1982 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
1984 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
1990 const auto &FeatureBits = getSTI().getFeatureBits();
1991 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
1993 return SysReg->FeaturesRequired[Feature.Value];
1995 auto ErrorMsg = std::string(
"system register '") + SysReg->Name +
"' ";
1996 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
1997 ErrorMsg +=
"is RV32 only";
1999 ErrorMsg +=
" and ";
2003 "requires '" + std::string(Feature->Key) +
"' to be enabled";
2006 return Error(S, ErrorMsg);
2009 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
2019 Operands.push_back(std::move(SysOpnd));
2024 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2025 "operand must be a valid system register "
2026 "name or an integer in the range");
2030 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2042 StringRef
Identifier = getTok().getIdentifier();
2043 if (
Identifier.compare_insensitive(
"inf") == 0) {
2046 getTok().getEndLoc(), isRV64()));
2047 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2050 getTok().getEndLoc(), isRV64()));
2051 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2054 getTok().getEndLoc(), isRV64()));
2056 return TokError(
"invalid floating point literal");
2067 const AsmToken &Tok = getTok();
2069 return TokError(
"invalid floating point immediate");
2072 APFloat RealVal(APFloat::IEEEdouble());
2074 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2076 return TokError(
"invalid floating point representation");
2079 RealVal.changeSign();
2081 Operands.push_back(RISCVOperand::createFPImm(
2082 RealVal.bitcastToAPInt().getZExtValue(), S));
2094 switch (getLexer().getKind()) {
2106 if (getParser().parseExpression(Res,
E))
2110 return parseOperandWithSpecifier(
Operands);
2113 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2123 const MCExpr *Expr =
nullptr;
2124 bool Failed = parseExprWithSpecifier(Expr,
E);
2126 Operands.push_back(RISCVOperand::createExpr(Expr, S,
E, isRV64()));
2130bool RISCVAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
2131 SMLoc Loc = getLoc();
2133 return TokError(
"expected '%' relocation specifier");
2134 StringRef
Identifier = getParser().getTok().getIdentifier();
2137 return TokError(
"invalid relocation specifier");
2143 const MCExpr *SubExpr;
2144 if (getParser().parseParenExpression(SubExpr,
E))
2151bool RISCVAsmParser::parseDataExpr(
const MCExpr *&Res) {
2154 return parseExprWithSpecifier(Res,
E);
2155 return getParser().parseExpression(Res);
2166 AsmToken Tok = getLexer().getTok();
2168 if (getParser().parseIdentifier(Identifier))
2178 getLexer().UnLex(Tok);
2186 switch (getLexer().getKind()) {
2188 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2201 if (getParser().parseExpression(Expr,
E))
2204 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2214 std::string
Identifier(getTok().getIdentifier());
2220 SMLoc Loc = getLoc();
2221 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2222 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2236 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2245 if (getParser().parseExpression(Res,
E))
2248 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef)
2249 return Error(S,
"operand must be a valid jump target");
2252 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2273bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2274 unsigned &Sew,
unsigned &Lmul,
2275 bool &Fractional,
bool &TailAgnostic,
2276 bool &MaskAgnostic,
bool &AltFmt) {
2281 if (State < VTypeState::SeenSew &&
Identifier.consume_front(
"e")) {
2283 if (Identifier ==
"16alt") {
2286 }
else if (Identifier ==
"8alt") {
2296 State = VTypeState::SeenSew;
2300 if (State < VTypeState::SeenLmul &&
Identifier.consume_front(
"m")) {
2303 if (Identifier ==
"a" || Identifier ==
"u") {
2305 State = VTypeState::SeenMaskPolicy;
2316 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2317 unsigned MinLMUL = ELEN / 8;
2320 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2321 Twine(MinLMUL) +
" is reserved");
2324 State = VTypeState::SeenLmul;
2328 if (State < VTypeState::SeenTailPolicy &&
Identifier.starts_with(
"t")) {
2329 if (Identifier ==
"ta")
2330 TailAgnostic =
true;
2331 else if (Identifier ==
"tu")
2332 TailAgnostic =
false;
2336 State = VTypeState::SeenTailPolicy;
2340 if (State < VTypeState::SeenMaskPolicy &&
Identifier.starts_with(
"m")) {
2341 if (Identifier ==
"ma")
2342 MaskAgnostic =
true;
2343 else if (Identifier ==
"mu")
2344 MaskAgnostic =
false;
2348 State = VTypeState::SeenMaskPolicy;
2361 bool Fractional =
false;
2362 bool TailAgnostic =
false;
2363 bool MaskAgnostic =
false;
2364 bool AltFmt =
false;
2366 VTypeState State = VTypeState::SeenNothingYet;
2368 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2369 MaskAgnostic, AltFmt)) {
2371 if (State == VTypeState::SeenNothingYet)
2380 State == VTypeState::SeenNothingYet)
2381 return generateVTypeError(S);
2385 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2386 unsigned MaxSEW = ELEN / Lmul;
2388 if (MaxSEW >= 8 && Sew > MaxSEW)
2389 Warning(S,
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2390 " and LMUL == mf" + Twine(Lmul) +
2391 " may not be compatible with all RVV implementations");
2396 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2400bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2401 if (STI->
hasFeature(RISCV::FeatureStdExtZvfbfa))
2405 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2409 "e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2417 bool AltFmt =
false;
2429 if (Identifier !=
"16alt")
2458 Operands.push_back(RISCVOperand::createVType(
2464 return generateXSfmmVTypeError(S);
2467bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
2468 return Error(ErrorLoc,
"operand must be e[8|16|16alt|32|64],w[1|2|4]");
2475 StringRef
Name = getLexer().getTok().getIdentifier();
2476 if (!
Name.consume_back(
".t"))
2477 return Error(getLoc(),
"expected '.t' suffix");
2482 if (
Reg != RISCV::V0)
2485 SMLoc
E = getTok().getEndLoc();
2487 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2492 if (!isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2502 StringRef
Name = getLexer().getTok().getIdentifier();
2508 SMLoc
E = getTok().getEndLoc();
2510 Operands.push_back(RISCVOperand::createReg(
2511 Reg, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2516 if (isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2522 StringRef
Name = getLexer().getTok().getIdentifier();
2528 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2531 if ((
Reg - RISCV::X0) & 1) {
2534 if (getSTI().hasFeature(RISCV::FeatureStdExtZfinx))
2535 return TokError(
"double precision floating point operands must use even "
2536 "numbered X register");
2541 SMLoc
E = getTok().getEndLoc();
2544 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2546 Reg, RISCV::sub_gpr_even,
2547 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2548 Operands.push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2552template <
bool IsRV64>
2554 return parseGPRPair(
Operands, IsRV64);
2564 if (!IsRV64Inst && isRV64())
2570 StringRef
Name = getLexer().getTok().getIdentifier();
2576 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2579 if ((
Reg - RISCV::X0) & 1)
2580 return TokError(
"register must be even");
2583 SMLoc
E = getTok().getEndLoc();
2586 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2588 Reg, RISCV::sub_gpr_even,
2589 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2590 Operands.push_back(RISCVOperand::createReg(Pair, S,
E));
2597 "operand must be a valid floating point rounding mode mnemonic");
2599 StringRef Str = getLexer().getTok().getIdentifier();
2604 "operand must be a valid floating point rounding mode mnemonic");
2606 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2612 const AsmToken &Tok = getLexer().getTok();
2618 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2632 for (
char c : Str) {
2661 Operands.push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2667 return TokError(
"operand must be formed of letters selected in-order from "
2674 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
2676 if (!parseRegister(
Operands).isSuccess())
2677 return Error(getLoc(),
"expected register");
2681 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2705 std::unique_ptr<RISCVOperand> OptionalImmOp;
2712 SMLoc ImmStart = getLoc();
2713 if (getParser().parseIntToken(ImmVal,
2714 "expected '(' or optional integer offset"))
2719 SMLoc ImmEnd = getLoc();
2722 ImmStart, ImmEnd, isRV64());
2726 OptionalImmOp ?
"expected '(' after optional integer offset"
2727 :
"expected '(' or optional integer offset"))
2730 if (!parseRegister(
Operands).isSuccess())
2731 return Error(getLoc(),
"expected register");
2737 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2739 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2740 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2751 StringRef OffsetRegName = getLexer().getTok().getIdentifier();
2754 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(OffsetReg))
2755 return Error(getLoc(),
"expected GPR register");
2762 return Error(getLoc(),
"expected GPR register");
2764 StringRef BaseRegName = getLexer().getTok().getIdentifier();
2767 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(BaseReg))
2768 return Error(getLoc(),
"expected GPR register");
2774 Operands.push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));
2787 bool MustIncludeS0) {
2799 return Error(getLoc(),
"invalid register");
2801 StringRef
RegName = getTok().getIdentifier();
2804 return Error(getLoc(),
"invalid register");
2807 UsesXRegs =
RegName[0] ==
'x';
2808 if (
Reg != RISCV::X1)
2809 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2810 }
else if (RegEnd == RISCV::X1) {
2811 if (
Reg != RISCV::X8 || (UsesXRegs != (
RegName[0] ==
'x')))
2812 return Error(getLoc(), Twine(
"register must be '") +
2813 (UsesXRegs ?
"x8" :
"s0") +
"'");
2814 }
else if (RegEnd == RISCV::X9 && UsesXRegs) {
2815 if (
Reg != RISCV::X18 || (
RegName[0] !=
'x'))
2816 return Error(getLoc(),
"register must be 'x18'");
2818 return Error(getLoc(),
"too many register ranges");
2825 SMLoc MinusLoc = getLoc();
2827 if (RegEnd == RISCV::X1)
2828 return Error(MinusLoc, Twine(
"register '") + (UsesXRegs ?
"x1" :
"ra") +
2829 "' cannot start a multiple register range");
2832 return Error(getLoc(),
"invalid register");
2834 StringRef
RegName = getTok().getIdentifier();
2837 return Error(getLoc(),
"invalid register");
2839 if (RegEnd == RISCV::X8) {
2840 if ((
Reg != RISCV::X9 &&
2842 (UsesXRegs != (
RegName[0] ==
'x'))) {
2844 return Error(getLoc(),
"register must be 'x9'");
2845 return Error(getLoc(),
"register must be in the range 's1' to 's11'");
2847 }
else if (RegEnd == RISCV::X18) {
2849 return Error(getLoc(),
2850 "register must be in the range 'x19' to 'x27'");
2863 if (RegEnd == RISCV::X26)
2864 return Error(S,
"invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "
2865 "x18-x26}' is not supported");
2871 return Error(S,
"register list must include 's0' or 'x8'");
2873 Operands.push_back(RISCVOperand::createRegList(Encode, S));
2879 bool ExpectNegative) {
2888 auto *RegListOp =
static_cast<RISCVOperand *
>(
Operands.back().
get());
2889 if (!RegListOp->isRegList())
2892 unsigned RlistEncode = RegListOp->RegList.Encoding;
2896 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||
2897 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {
2898 int64_t
Lower = StackAdjBase;
2899 int64_t
Upper = StackAdjBase + 48;
2900 if (ExpectNegative) {
2905 return generateImmOutOfRangeError(S,
Lower,
Upper,
2906 "stack adjustment for register list must "
2907 "be a multiple of 16 bytes in the range");
2911 Operands.push_back(RISCVOperand::createStackAdj(StackAdj, S));
2923 MatchOperandParserImpl(
Operands, Mnemonic,
true);
2930 if (parseRegister(
Operands,
true).isSuccess())
2934 if (parseExpression(
Operands).isSuccess()) {
2937 return !parseMemOpBaseReg(
Operands).isSuccess();
2942 Error(getLoc(),
"unknown operand");
2946bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &
Info,
2947 StringRef Name, SMLoc NameLoc,
2953 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
2957 Operands.push_back(RISCVOperand::createToken(Name, NameLoc));
2976 if (getParser().parseEOL(
"unexpected token")) {
2977 getParser().eatToEndOfStatement();
2983bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
2987 Kind = RE->getSpecifier();
2988 Expr = RE->getSubExpr();
2997bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
3006ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
3007 StringRef IDVal = DirectiveID.
getString();
3009 if (IDVal ==
".option")
3010 return parseDirectiveOption();
3011 if (IDVal ==
".attribute")
3012 return parseDirectiveAttribute();
3013 if (IDVal ==
".insn")
3014 return parseDirectiveInsn(DirectiveID.
getLoc());
3015 if (IDVal ==
".variant_cc")
3016 return parseDirectiveVariantCC();
3021bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
3022 bool FromOptionDirective) {
3025 clearFeatureBits(Feature.Value, Feature.Key);
3032 raw_string_ostream OutputErrMsg(Buffer);
3033 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3034 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
3035 << ErrMsg.getMessage();
3038 return Error(Loc, OutputErrMsg.str());
3040 auto &ISAInfo = *ParseResult;
3043 if (ISAInfo->hasExtension(Feature.Key))
3044 setFeatureBits(Feature.Value, Feature.Key);
3046 if (FromOptionDirective) {
3047 if (ISAInfo->getXLen() == 32 && isRV64())
3048 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3049 else if (ISAInfo->getXLen() == 64 && !isRV64())
3050 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3053 if (ISAInfo->getXLen() == 32)
3054 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
3055 else if (ISAInfo->getXLen() == 64)
3056 setFeatureBits(RISCV::Feature64Bit,
"64bit");
3058 return Error(Loc,
"bad arch string " + Arch);
3060 Result = ISAInfo->toString();
3064bool RISCVAsmParser::parseDirectiveOption() {
3065 MCAsmParser &Parser = getParser();
3067 AsmToken Tok = Parser.
getTok();
3075 if (Option ==
"push") {
3079 getTargetStreamer().emitDirectiveOptionPush();
3084 if (Option ==
"pop") {
3089 getTargetStreamer().emitDirectiveOptionPop();
3090 if (popFeatureBits())
3091 return Error(StartLoc,
".option pop with no .option push");
3096 if (Option ==
"arch") {
3104 Type = RISCVOptionArchArgType::Plus;
3106 Type = RISCVOptionArchArgType::Minus;
3107 else if (!
Args.empty())
3109 "unexpected token, expected + or -");
3111 Type = RISCVOptionArchArgType::Full;
3115 "unexpected token, expected identifier");
3121 if (
Type == RISCVOptionArchArgType::Full) {
3123 if (resetToArch(Arch, Loc, Result,
true))
3132 Loc,
"extension version number parsing not currently implemented");
3135 if (!enableExperimentalExtension() &&
3137 return Error(Loc,
"unexpected experimental extensions");
3140 return Error(Loc,
"unknown extension feature");
3144 if (
Type == RISCVOptionArchArgType::Plus) {
3147 setFeatureBits(
Ext->Value,
Ext->Key);
3150 copySTI().setFeatureBits(OldFeatureBits);
3151 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3154 raw_string_ostream OutputErrMsg(Buffer);
3155 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3156 OutputErrMsg << ErrMsg.getMessage();
3159 return Error(Loc, OutputErrMsg.str());
3162 assert(
Type == RISCVOptionArchArgType::Minus);
3167 if (getSTI().hasFeature(Feature.Value) &&
3168 Feature.Implies.test(
Ext->Value))
3169 return Error(Loc, Twine(
"can't disable ") +
Ext->Key +
3170 " extension; " + Feature.Key +
3171 " extension requires " +
Ext->Key +
3175 clearFeatureBits(
Ext->Value,
Ext->Key);
3182 getTargetStreamer().emitDirectiveOptionArch(Args);
3186 if (Option ==
"exact") {
3190 getTargetStreamer().emitDirectiveOptionExact();
3191 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3192 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3196 if (Option ==
"noexact") {
3200 getTargetStreamer().emitDirectiveOptionNoExact();
3201 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3202 setFeatureBits(RISCV::FeatureRelax,
"relax");
3206 if (Option ==
"rvc") {
3210 getTargetStreamer().emitDirectiveOptionRVC();
3211 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3215 if (Option ==
"norvc") {
3219 getTargetStreamer().emitDirectiveOptionNoRVC();
3220 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3221 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3225 if (Option ==
"pic") {
3229 getTargetStreamer().emitDirectiveOptionPIC();
3230 ParserOptions.IsPicEnabled =
true;
3234 if (Option ==
"nopic") {
3238 getTargetStreamer().emitDirectiveOptionNoPIC();
3239 ParserOptions.IsPicEnabled =
false;
3243 if (Option ==
"relax") {
3247 getTargetStreamer().emitDirectiveOptionRelax();
3248 setFeatureBits(RISCV::FeatureRelax,
"relax");
3252 if (Option ==
"norelax") {
3256 getTargetStreamer().emitDirectiveOptionNoRelax();
3257 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3263 "unknown option, expected 'push', 'pop', "
3264 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3265 "'exact', or 'noexact'");
3273bool RISCVAsmParser::parseDirectiveAttribute() {
3274 MCAsmParser &Parser = getParser();
3280 std::optional<unsigned>
Ret =
3283 return Error(TagLoc,
"attribute name not recognised: " + Name);
3287 const MCExpr *AttrExpr;
3294 if (check(!CE, TagLoc,
"expected numeric constant"))
3297 Tag =
CE->getValue();
3303 StringRef StringValue;
3304 int64_t IntegerValue = 0;
3305 bool IsIntegerValue =
true;
3310 IsIntegerValue =
false;
3313 if (IsIntegerValue) {
3314 const MCExpr *ValueExpr;
3320 return Error(ValueExprLoc,
"expected numeric constant");
3321 IntegerValue =
CE->getValue();
3334 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3336 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3339 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3343 getTargetStreamer().emitTextAttribute(
Tag, Result);
3351 .
Cases(
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s",
true)
3352 .
Cases(
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj",
3354 .
Cases(
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es",
3363bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3364 MCAsmParser &Parser = getParser();
3371 std::optional<int64_t>
Length;
3381 return Error(ErrorLoc,
3382 "instruction lengths must be a non-zero multiple of two");
3386 return Error(ErrorLoc,
3387 "instruction lengths over 64 bits are not supported");
3393 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3398 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3399 return Error(ErrorLoc,
3400 "instruction length does not match the encoding");
3403 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3406 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3409 if (!getSTI().hasFeature(RISCV::FeatureStdExtZca) &&
3410 (EncodingDerivedLength == 2))
3411 return Error(ErrorLoc,
"compressed instructions are not allowed");
3413 if (getParser().parseEOL(
"invalid operand for instruction")) {
3414 getParser().eatToEndOfStatement();
3422 Opcode = RISCV::Insn16;
3425 Opcode = RISCV::Insn32;
3428 Opcode = RISCV::Insn48;
3431 Opcode = RISCV::Insn64;
3437 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3439 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3444 return Error(ErrorLoc,
"invalid instruction format");
3446 std::string FormatName = (
".insn_" +
Format).str();
3448 ParseInstructionInfo
Info;
3463bool RISCVAsmParser::parseDirectiveVariantCC() {
3465 if (getParser().parseIdentifier(Name))
3466 return TokError(
"expected symbol name");
3469 getTargetStreamer().emitDirectiveVariantCC(
3474void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3477 const MCSubtargetInfo &STI = getSTI();
3478 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3481 ++RISCVNumInstrsCompressed;
3485void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3490 for (MCInst &Inst : Seq) {
3491 emitToStreamer(Out, Inst);
3495void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3496 const MCExpr *Symbol,
3498 unsigned SecondOpcode, SMLoc IDLoc,
3510 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3515 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3518 .addExpr(RefToLinkTmpLabel));
3521void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3531 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_PCREL_HI20,
3532 RISCV::ADDI, IDLoc, Out);
3535void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3545 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3546 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_GOT_HI20,
3547 SecondOpcode, IDLoc, Out);
3550void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3559 if (ParserOptions.IsPicEnabled)
3560 emitLoadGlobalAddress(Inst, IDLoc, Out);
3562 emitLoadLocalAddress(Inst, IDLoc, Out);
3565void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3575 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3576 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3577 SecondOpcode, IDLoc, Out);
3580void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3590 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3591 RISCV::ADDI, IDLoc, Out);
3594void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3595 SMLoc IDLoc, MCStreamer &Out,
3604 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3606 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3610 if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].
contains(TmpReg)) {
3611 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3612 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3616 emitAuipcInstPair(DestReg, TmpReg, Symbol, ELF::R_RISCV_PCREL_HI20, Opcode,
3620void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3621 int64_t Width, SMLoc IDLoc,
3630 const MCOperand &DestReg = Inst.
getOperand(0);
3631 const MCOperand &SourceReg = Inst.
getOperand(1);
3633 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3634 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3636 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3638 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3643 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3649void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
3656 emitToStreamer(Out, MCInstBuilder(Opcode)
3660 .addReg(MCRegister())
3662 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
3673 "The destination register should not be V0.");
3674 emitToStreamer(Out, MCInstBuilder(Opcode)
3680 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
3692 "The destination register should be V0.");
3694 "The temporary vector register should not be V0.");
3695 emitToStreamer(Out, MCInstBuilder(Opcode)
3699 .addReg(MCRegister())
3701 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3713 "The temporary vector register should not be V0.");
3714 emitToStreamer(Out, MCInstBuilder(Opcode)
3718 .addReg(MCRegister())
3720 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3725 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3730 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
3738bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
3740 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3743 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3744 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3745 "%tprel_add specifier");
3751bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
3753 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
3756 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3757 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
3758 "%tlsdesc_call specifier");
3764std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3765 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
3768std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3769 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3773std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3774 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3778bool RISCVAsmParser::validateInstruction(MCInst &Inst,
3782 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3783 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3786 if (DestReg == TempReg) {
3787 SMLoc Loc =
Operands.back()->getStartLoc();
3788 return Error(Loc,
"the temporary vector register cannot be the same as "
3789 "the destination register");
3793 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3794 Opcode == RISCV::TH_LWD) {
3799 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
3800 SMLoc Loc =
Operands[1]->getStartLoc();
3801 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
3805 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
3809 SMLoc Loc =
Operands[1]->getStartLoc();
3810 return Error(Loc,
"rs1 and rs2 must be different");
3814 const MCInstrDesc &MCID = MII.
get(Opcode);
3818 if (Opcode == RISCV::SF_VC_V_XVW || Opcode == RISCV::SF_VC_V_IVW ||
3819 Opcode == RISCV::SF_VC_V_FVW || Opcode == RISCV::SF_VC_V_VVW) {
3822 SMLoc VCIXDstLoc =
Operands[2]->getStartLoc();
3825 if (VCIXDst == VCIXRs1)
3826 return Error(VCIXDstLoc,
"the destination vector register group cannot"
3827 " overlap the source vector register group");
3831 if (VCIXDst == VCIXRs2)
3832 return Error(VCIXDstLoc,
"the destination vector register group cannot"
3833 " overlap the source vector register group");
3845 SMLoc Loc =
Operands[1]->getStartLoc();
3848 if (DestReg == CheckReg)
3849 return Error(Loc,
"the destination vector register group cannot overlap"
3850 " the source vector register group");
3854 if (DestReg == CheckReg)
3855 return Error(Loc,
"the destination vector register group cannot overlap"
3856 " the source vector register group");
3861 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM ||
3862 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM ||
3863 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM ||
3864 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM ||
3865 Opcode == RISCV::VMERGE_VXM)
3866 return Error(Loc,
"the destination vector register group cannot be V0");
3873 assert((CheckReg == RISCV::V0 || !CheckReg) &&
3874 "Unexpected register for mask operand");
3876 if (DestReg == CheckReg)
3877 return Error(Loc,
"the destination vector register group cannot overlap"
3878 " the mask register");
3883bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
3891 case RISCV::PseudoC_ADDI_NOP: {
3893 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
3899 case RISCV::PseudoLLAImm:
3900 case RISCV::PseudoLAImm:
3901 case RISCV::PseudoLI: {
3907 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
3919 emitLoadImm(
Reg, Imm, Out);
3922 case RISCV::PseudoLLA:
3923 emitLoadLocalAddress(Inst, IDLoc, Out);
3925 case RISCV::PseudoLGA:
3926 emitLoadGlobalAddress(Inst, IDLoc, Out);
3928 case RISCV::PseudoLA:
3929 emitLoadAddress(Inst, IDLoc, Out);
3931 case RISCV::PseudoLA_TLS_IE:
3932 emitLoadTLSIEAddress(Inst, IDLoc, Out);
3934 case RISCV::PseudoLA_TLS_GD:
3935 emitLoadTLSGDAddress(Inst, IDLoc, Out);
3937 case RISCV::PseudoLB:
3938 case RISCV::PseudoQC_E_LB:
3939 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
3941 case RISCV::PseudoLBU:
3942 case RISCV::PseudoQC_E_LBU:
3943 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
3945 case RISCV::PseudoLH:
3946 case RISCV::PseudoQC_E_LH:
3947 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
3949 case RISCV::PseudoLHU:
3950 case RISCV::PseudoQC_E_LHU:
3951 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
3953 case RISCV::PseudoLW:
3954 case RISCV::PseudoQC_E_LW:
3955 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
3957 case RISCV::PseudoLWU:
3958 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
3960 case RISCV::PseudoLD:
3961 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
3963 case RISCV::PseudoLD_RV32:
3964 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
3966 case RISCV::PseudoFLH:
3967 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
3969 case RISCV::PseudoFLW:
3970 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
3972 case RISCV::PseudoFLD:
3973 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
3975 case RISCV::PseudoFLQ:
3976 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
3978 case RISCV::PseudoSB:
3979 case RISCV::PseudoQC_E_SB:
3980 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
3982 case RISCV::PseudoSH:
3983 case RISCV::PseudoQC_E_SH:
3984 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
3986 case RISCV::PseudoSW:
3987 case RISCV::PseudoQC_E_SW:
3988 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
3990 case RISCV::PseudoSD:
3991 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
3993 case RISCV::PseudoSD_RV32:
3994 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
3996 case RISCV::PseudoFSH:
3997 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
3999 case RISCV::PseudoFSW:
4000 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
4002 case RISCV::PseudoFSD:
4003 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4005 case RISCV::PseudoFSQ:
4006 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4008 case RISCV::PseudoAddTPRel:
4009 if (checkPseudoAddTPRel(Inst,
Operands))
4012 case RISCV::PseudoTLSDESCCall:
4013 if (checkPseudoTLSDESCCall(Inst,
Operands))
4016 case RISCV::PseudoSEXT_B:
4017 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4019 case RISCV::PseudoSEXT_H:
4020 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4022 case RISCV::PseudoZEXT_H:
4023 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4025 case RISCV::PseudoZEXT_W:
4026 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4028 case RISCV::PseudoVMSGEU_VX:
4029 case RISCV::PseudoVMSGEU_VX_M:
4030 case RISCV::PseudoVMSGEU_VX_M_T:
4031 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4033 case RISCV::PseudoVMSGE_VX:
4034 case RISCV::PseudoVMSGE_VX_M:
4035 case RISCV::PseudoVMSGE_VX_M_T:
4036 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4038 case RISCV::PseudoVMSGE_VI:
4039 case RISCV::PseudoVMSLT_VI: {
4043 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4045 emitToStreamer(Out, MCInstBuilder(
Opc)
4053 case RISCV::PseudoVMSGEU_VI:
4054 case RISCV::PseudoVMSLTU_VI: {
4061 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4064 emitToStreamer(Out, MCInstBuilder(
Opc)
4072 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4075 emitToStreamer(Out, MCInstBuilder(
Opc)
4087 emitToStreamer(Out, Inst);
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
static MCRegister MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Analysis containing CSE Info
static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, MCRegister &Reg, StringRef Name)
#define LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
#define LLVM_EXTERNAL_VISIBILITY
mir Rename Register Operands
Promote Memory to Register
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
bool isValidInsnFormat(StringRef Format, const MCSubtargetInfo &STI)
static MCRegister convertFPR64ToFPR128(MCRegister Reg)
static MCRegister convertFPR64ToFPR32(MCRegister Reg)
static cl::opt< bool > AddBuildAttributes("riscv-add-build-attributes", cl::init(false))
static MCRegister convertFPR64ToFPR16(MCRegister Reg)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser()
static MCRegister convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg, unsigned Kind)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
StringRef getStringContents() const
Get the contents of a string token (without quotes).
bool is(TokenKind K) const
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Encoding
Size and signedness of expression operations' operands.
constexpr size_t size() const
void printExpr(raw_ostream &, const MCExpr &) const
const AsmToken & getTok()
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
MCStreamer & getStreamer()
static LLVM_ABI const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
const MCObjectFileInfo * getObjectFileInfo() const
LLVM_ABI MCSymbol * createNamedTempSymbol()
Create a temporary symbol with a unique name whose name cannot be omitted in the symbol table.
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specified operand constraint if it is present.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
bool isPositionIndependent() const
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
const MCSymbol * getAddSym() const
uint32_t getSpecifier() const
const MCSymbol * getSubSym() const
Ternary parse status returned by various parse* methods.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
static LLVM_ABI bool isSupportedExtensionFeature(StringRef Ext)
static LLVM_ABI std::string getTargetFeatureForExtension(StringRef Ext)
static LLVM_ABI llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseArchString(StringRef Arch, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck=true)
Parse RISC-V ISA info from arch string.
static const char * getRegisterName(MCRegister Reg)
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
char back() const
back - Get the last character in the string.
A switch()-like statement whose cases are string literals.
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
uint16_t StackAdjustment(const RuntimeFunction &RF)
StackAdjustment - calculated stack adjustment in words.
LLVM_ABI std::optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)
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)
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
Context & getContext() const
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
FunctionAddr VTableAddr Value
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
testing::Matcher< const detail::ErrorHolder & > Failed()
Target & getTheRISCV32Target()
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Target & getTheRISCV64beTarget()
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
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.