52#define DEBUG_TYPE "riscv-asm-parser"
55 "Number of RISC-V Compressed instructions emitted");
63struct ParserOptionsSet {
70 enum class VTypeState {
81 ParserOptionsSet ParserOptions;
83 SMLoc getLoc()
const {
return getParser().
getTok().
getLoc(); }
84 bool isRV64()
const {
return getSTI().hasFeature(RISCV::Feature64Bit); }
85 bool isRVE()
const {
return getSTI().hasFeature(RISCV::FeatureStdExtE); }
86 bool enableExperimentalExtension()
const {
87 return getSTI().hasFeature(RISCV::Experimental);
90 RISCVTargetStreamer &getTargetStreamer() {
91 assert(getParser().getStreamer().getTargetStreamer() &&
92 "do not have a target streamer");
93 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
94 return static_cast<RISCVTargetStreamer &
>(TS);
97 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
98 unsigned Kind)
override;
100 bool generateImmOutOfRangeError(SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
103 struct NearMissMessage {
108 std::string getCustomOperandDiag(
unsigned MatchError);
110 void FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
111 SmallVectorImpl<NearMissMessage> &NearMissesOut,
113 void ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses, SMLoc IDLoc,
116 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
119 bool MatchingInlineAsm)
override;
122 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
123 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
124 SMLoc &EndLoc)
override;
126 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
129 ParseStatus parseDirective(AsmToken DirectiveID)
override;
131 bool parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
unsigned &Sew,
132 unsigned &Lmul,
bool &Fractional,
bool &TailAgnostic,
133 bool &MaskAgnostic,
bool &AltFmt);
134 bool generateVTypeError(SMLoc ErrorLoc);
136 bool generateXSfmmVTypeError(SMLoc ErrorLoc);
139 void emitToStreamer(MCStreamer &S,
const MCInst &Inst);
143 void emitLoadImm(MCRegister DestReg, int64_t
Value, MCStreamer &Out);
147 void emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
149 unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out);
152 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
155 void emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
158 void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
162 void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
166 void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
169 void emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
170 MCStreamer &Out,
bool HasTmpReg);
175 void emitQCELILoadStoreSymbol(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
176 MCStreamer &Out,
bool HasTmpReg);
179 void emitPseudoExtend(MCInst &Inst,
bool SignExtend, int64_t Width,
180 SMLoc IDLoc, MCStreamer &Out);
183 void emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc, MCStreamer &Out);
208#define GET_ASSEMBLER_HEADER
209#include "RISCVGenAsmMatcher.inc"
239 return parseRegList(
Operands,
true);
245 bool ExpectNegative =
false);
247 return parseZcmpStackAdj(
Operands,
true);
251 bool parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
252 bool parseDataExpr(
const MCExpr *&Res)
override;
254 bool parseDirectiveOption();
255 bool parseDirectiveAttribute();
256 bool parseDirectiveInsn(SMLoc L);
257 bool parseDirectiveVariantCC();
262 bool resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
263 bool FromOptionDirective);
265 void setFeatureBits(
uint64_t Feature, StringRef FeatureString) {
267 MCSubtargetInfo &STI = copySTI();
273 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
277 void clearFeatureBits(
uint64_t Feature, StringRef FeatureString) {
279 MCSubtargetInfo &STI = copySTI();
280 setAvailableFeatures(
285 void pushFeatureBits() {
286 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
287 "These two stacks must be kept synchronized");
288 FeatureBitStack.push_back(getSTI().getFeatureBits());
289 ParserOptionsStack.push_back(ParserOptions);
292 bool popFeatureBits() {
293 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
294 "These two stacks must be kept synchronized");
295 if (FeatureBitStack.empty())
298 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
299 copySTI().setFeatureBits(FeatureBits);
300 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
302 ParserOptions = ParserOptionsStack.pop_back_val();
307 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
308 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
309 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
310 std::unique_ptr<RISCVOperand> defaultSMTVType();
311 std::unique_ptr<RISCVOperand> defaultZeroOffset();
314 enum RISCVMatchResultTy :
unsigned {
315 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
316#define GET_OPERAND_DIAGNOSTIC_TYPES
317#include "RISCVGenAsmMatcher.inc"
318#undef GET_OPERAND_DIAGNOSTIC_TYPES
322 static bool isSymbolDiff(
const MCExpr *Expr);
324 RISCVAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
325 const MCInstrInfo &MII)
326 : MCTargetAsmParser(STI, MII) {
333 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
339 getTargetStreamer().emitTargetAttributes(STI,
false);
345 void onBeginOfFile()
override {
346 Expected<RISCVABI::ABI> ABIOrErr =
420 MCRegister OffsetReg;
423 SMLoc StartLoc, EndLoc;
439 RISCVOperand(KindTy K) : Kind(
K) {}
442 RISCVOperand(
const RISCVOperand &o) : MCParsedAsmOperand() {
444 StartLoc =
o.StartLoc;
447 case KindTy::Register:
450 case KindTy::Expression:
453 case KindTy::FPImmediate:
459 case KindTy::SystemRegister:
465 case KindTy::SMTVType:
466 SMTVType =
o.SMTVType;
474 case KindTy::RegList:
477 case KindTy::StackAdj:
478 StackAdj =
o.StackAdj;
486 bool isToken()
const override {
return Kind == KindTy::Token; }
487 bool isReg()
const override {
return Kind == KindTy::Register; }
488 bool isExpr()
const {
return Kind == KindTy::Expression; }
489 bool isV0Reg()
const {
490 return Kind == KindTy::Register &&
Reg.Reg == RISCV::V0;
492 bool isAnyReg()
const {
493 return Kind == KindTy::Register &&
494 (getRISCVMCRegisterClass(RISCV::GPRRegClassID).contains(
Reg.Reg) ||
495 getRISCVMCRegisterClass(RISCV::FPR64RegClassID).contains(
Reg.Reg) ||
496 getRISCVMCRegisterClass(RISCV::VRRegClassID).contains(
Reg.Reg));
498 bool isAnyRegC()
const {
499 return Kind == KindTy::Register &&
500 (getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(
Reg.Reg) ||
501 getRISCVMCRegisterClass(RISCV::FPR64CRegClassID).contains(
Reg.Reg));
503 bool isImm()
const override {
return isExpr(); }
504 bool isMem()
const override {
return false; }
505 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
506 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
507 bool isRegList()
const {
return Kind == KindTy::RegList; }
508 bool isRegListS0()
const {
509 return Kind == KindTy::RegList && RegList.Encoding !=
RISCVZC::RA;
511 bool isStackAdj()
const {
return Kind == KindTy::StackAdj; }
514 return Kind == KindTy::Register &&
515 getRISCVMCRegisterClass(RISCV::GPRRegClassID).contains(
Reg.Reg);
518 bool isYGPR()
const {
519 return Kind == KindTy::Register &&
520 getRISCVMCRegisterClass(RISCV::YGPRRegClassID).contains(
Reg.Reg);
523 bool isGPRPair()
const {
524 return Kind == KindTy::Register &&
525 getRISCVMCRegisterClass(RISCV::GPRPairRegClassID).contains(
Reg.Reg);
528 bool isGPRPairC()
const {
529 return Kind == KindTy::Register &&
530 getRISCVMCRegisterClass(RISCV::GPRPairCRegClassID).contains(
Reg.Reg);
533 bool isGPRPairNoX0()
const {
534 return Kind == KindTy::Register &&
535 getRISCVMCRegisterClass(RISCV::GPRPairNoX0RegClassID)
539 bool isGPRF16()
const {
540 return Kind == KindTy::Register &&
541 getRISCVMCRegisterClass(RISCV::GPRF16RegClassID).contains(
Reg.Reg);
544 bool isGPRF32()
const {
545 return Kind == KindTy::Register &&
546 getRISCVMCRegisterClass(RISCV::GPRF32RegClassID).contains(
Reg.Reg);
549 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
550 bool isGPRAsFPR16()
const {
return isGPRF16() &&
Reg.IsGPRAsFPR; }
551 bool isGPRAsFPR32()
const {
return isGPRF32() &&
Reg.IsGPRAsFPR; }
552 bool isGPRPairAsFPR64()
const {
return isGPRPair() &&
Reg.IsGPRAsFPR; }
554 static bool evaluateConstantExpr(
const MCExpr *Expr, int64_t &
Imm) {
556 Imm =
CE->getValue();
565 template <
int N>
bool isBareSimmNLsb0()
const {
574 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
580 template <
int N>
bool isBareSimmN()
const {
586 return isInt<N>(fixImmediateForRV32(
Imm, isRV64Expr()));
589 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
595 bool isBareSymbol()
const {
598 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
602 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
606 bool isCallSymbol()
const {
609 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
613 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
617 bool isTailCallSymbol()
const {
return isCallSymbol(); }
619 bool isPseudoJumpSymbol()
const {
622 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
626 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
630 bool isTPRelAddSymbol()
const {
633 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
637 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
638 VK == ELF::R_RISCV_TPREL_ADD;
641 bool isTLSDESCCallSymbol()
const {
644 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
648 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
649 VK == ELF::R_RISCV_TLSDESC_CALL;
652 bool isQCAccessSymbol()
const {
655 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
659 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
663 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
667 bool isVTypeI10()
const {
668 if (Kind == KindTy::VType)
672 bool isVTypeI11()
const {
673 if (Kind == KindTy::VType)
678 bool isXSfmmVType()
const {
682 bool isTileLambda()
const {
688 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
691 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
692 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
697 bool isSMTVType()
const {
698 return Kind == KindTy::SMTVType &&
702 bool isSMTI8()
const {
707 bool isLoadFPImm()
const {
710 if (Kind != KindTy::FPImmediate)
713 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
716 return Idx >= 0 && Idx != 1;
719 bool isImmXLenLI()
const {
728 return RISCVAsmParser::isSymbolDiff(
getExpr());
731 bool isImmXLenLI_Restricted()
const {
735 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
737 return IsConstantImm &&
741 template <
unsigned N>
bool isUImm()
const {
745 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
749 template <
unsigned N,
unsigned S>
bool isUImmShifted()
const {
753 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
757 template <
class Pred>
bool isUImmPred(Pred p)
const {
761 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
762 return IsConstantImm &&
p(
Imm);
765 bool isUImmLog2XLen()
const {
766 if (isExpr() && isRV64Expr())
771 bool isUImmLog2XLenNonZero()
const {
772 if (isExpr() && isRV64Expr())
777 bool isUImmLog2XLenHalf()
const {
778 if (isExpr() && isRV64Expr())
783 bool isUImm1()
const {
return isUImm<1>(); }
784 bool isUImm2()
const {
return isUImm<2>(); }
785 bool isUImm3()
const {
return isUImm<3>(); }
786 bool isUImm4()
const {
return isUImm<4>(); }
787 bool isUImm5()
const {
return isUImm<5>(); }
788 bool isUImm6()
const {
return isUImm<6>(); }
789 bool isUImm7()
const {
return isUImm<7>(); }
790 bool isUImm8()
const {
return isUImm<8>(); }
791 bool isUImm9()
const {
return isUImm<9>(); }
792 bool isUImm10()
const {
return isUImm<10>(); }
793 bool isUImm11()
const {
return isUImm<11>(); }
794 bool isUImm16()
const {
return isUImm<16>(); }
795 bool isUImm20()
const {
return isUImm<20>(); }
796 bool isUImm32()
const {
return isUImm<32>(); }
797 bool isUImm48()
const {
return isUImm<48>(); }
798 bool isUImm64()
const {
return isUImm<64>(); }
800 bool isUImm5NonZero()
const {
804 bool isUImm5GT3()
const {
808 bool isUImm4Plus1()
const {
813 bool isUImm5Plus1()
const {
818 bool isUImm6Plus1()
const {
823 bool isUImm5GE6Plus1()
const {
828 bool isUImm5Slist()
const {
829 return isUImmPred([](int64_t
Imm) {
830 return (
Imm == 0) || (
Imm == 1) || (
Imm == 2) || (
Imm == 4) ||
831 (
Imm == 8) || (
Imm == 16) || (
Imm == 15) || (
Imm == 31);
835 bool isUImm7EqXLen()
const {
837 [
this](int64_t
Imm) {
return isRV64Expr() ?
Imm == 64 :
Imm == 32; });
840 bool isUImm8GE32()
const {
844 bool isRnumArg()
const {
846 [](int64_t
Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(10); });
849 bool isRnumArg_0_7()
const {
851 [](int64_t
Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(7); });
854 bool isRnumArg_1_10()
const {
856 [](int64_t
Imm) {
return Imm >= INT64_C(1) &&
Imm <= INT64_C(10); });
859 bool isRnumArg_2_14()
const {
861 [](int64_t
Imm) {
return Imm >= INT64_C(2) &&
Imm <= INT64_C(14); });
864 template <
unsigned N>
bool isSImm()
const {
868 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
869 return IsConstantImm &&
isInt<N>(fixImmediateForRV32(
Imm, isRV64Expr()));
872 bool isYBNDSWImm()
const {
877 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
881 template <
class Pred>
bool isSImmPred(Pred p)
const {
885 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
886 return IsConstantImm &&
p(fixImmediateForRV32(
Imm, isRV64Expr()));
889 bool isSImm5()
const {
return isSImm<5>(); }
890 bool isSImm6()
const {
return isSImm<6>(); }
891 bool isSImm10()
const {
return isSImm<10>(); }
892 bool isSImm11()
const {
return isSImm<11>(); }
893 bool isSImm12()
const {
return isSImm<12>(); }
894 bool isSImm16()
const {
return isSImm<16>(); }
895 bool isSImm26()
const {
return isSImm<26>(); }
897 bool isSImm5NonZero()
const {
901 bool isSImm6NonZero()
const {
905 bool isCLUIImm()
const {
906 return isUImmPred([](int64_t
Imm) {
911 bool isUImm2Lsb0()
const {
return isUImmShifted<1, 1>(); }
913 bool isUImm5Lsb0()
const {
return isUImmShifted<4, 1>(); }
915 bool isUImm6Lsb0()
const {
return isUImmShifted<5, 1>(); }
917 bool isUImm6Lsb000()
const {
return isUImmShifted<3, 3>(); }
919 bool isUImm7Lsb00()
const {
return isUImmShifted<5, 2>(); }
921 bool isUImm7Lsb000()
const {
return isUImmShifted<4, 3>(); }
923 bool isUImm8Lsb00()
const {
return isUImmShifted<6, 2>(); }
925 bool isUImm8Lsb000()
const {
return isUImmShifted<5, 3>(); }
927 bool isUImm9Lsb000()
const {
return isUImmShifted<6, 3>(); }
929 bool isUImm14Lsb00()
const {
return isUImmShifted<12, 2>(); }
931 bool isUImm10Lsb00NonZero()
const {
938 static int64_t fixImmediateForRV32(int64_t
Imm,
bool IsRV64Imm) {
944 bool isSImm12LO()
const {
950 return isInt<12>(fixImmediateForRV32(
Imm, isRV64Expr()));
953 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
956 VK == ELF::R_RISCV_TLSDESC_ADD_LO12);
964 template <
bool (RISCVOperand::*Pred)() const>
965 DiagnosticPredicate isOptionalMemOffset()
const {
969 : DiagnosticPredicate::NearMatch;
972 bool isSImm12Lsb00000()
const {
976 bool isSImm10Lsb0000NonZero()
const {
981 bool isSImm16NonZero()
const {
985 bool isUImm16NonZero()
const {
989 bool isSImm20LI()
const {
995 return isInt<20>(fixImmediateForRV32(
Imm, isRV64Expr()));
998 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
1002 bool isSImm8PLI_B()
const {
return isSImm<8>() || isUImm<8>(); }
1003 bool isSImm10PLUI()
const {
return isSImm<10>() || isUImm<10>(); }
1005 bool isSImm10PLI_H()
const {
1006 return isSImm<10>() || isUImmPred([](int64_t
Imm) {
1010 bool isSImm10PLI_W()
const {
1011 return isSImm<10>() || isUImmPred([](int64_t
Imm) {
1016 bool isUImm20LUI()
const {
1025 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
1026 (VK == ELF::R_RISCV_HI20 || VK == ELF::R_RISCV_TPREL_HI20);
1029 bool isUImm20AUIPC()
const {
1038 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
1040 VK == ELF::R_RISCV_TLS_GOT_HI20 || VK == ELF::R_RISCV_TLS_GD_HI20 ||
1041 VK == ELF::R_RISCV_TLSDESC_HI20);
1044 bool isImmZero()
const {
1045 return isUImmPred([](int64_t
Imm) {
return 0 ==
Imm; });
1048 bool isImmThree()
const {
1049 return isUImmPred([](int64_t
Imm) {
return 3 ==
Imm; });
1052 bool isImmFour()
const {
1053 return isUImmPred([](int64_t
Imm) {
return 4 ==
Imm; });
1056 bool isImm5Zibi()
const {
1061 bool isSImm5Plus1()
const {
1066 bool isSImm18()
const {
1070 bool isSImm18Lsb0()
const {
1074 bool isSImm19Lsb00()
const {
1078 bool isSImm20Lsb000()
const {
1082 bool isSImm32Lsb0()
const {
1087 SMLoc getStartLoc()
const override {
return StartLoc; }
1089 SMLoc getEndLoc()
const override {
return EndLoc; }
1092 bool isRV64Expr()
const {
1093 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1097 MCRegister
getReg()
const override {
1098 assert(Kind == KindTy::Register &&
"Invalid type access!");
1102 StringRef getSysReg()
const {
1103 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
1104 return StringRef(SysReg.Data, SysReg.Length);
1107 const MCExpr *
getExpr()
const {
1108 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1113 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1118 assert(Kind == KindTy::Token &&
"Invalid type access!");
1122 unsigned getVType()
const {
1123 assert(Kind == KindTy::VType &&
"Invalid type access!");
1128 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1132 unsigned getFence()
const {
1133 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1138 assert(Kind == KindTy::SMTVType &&
"Invalid type access!");
1139 return SMTVType.SMTVType;
1142 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1151 case KindTy::Expression:
1154 OS <<
' ' << (Expr.IsRV64 ?
"rv64" :
"rv32") <<
'>';
1156 case KindTy::FPImmediate:
1157 OS <<
"<fpimm: " << FPImm.Val <<
">";
1159 case KindTy::Register:
1161 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1166 case KindTy::SystemRegister:
1167 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1176 OS << roundingModeToString(getFRM());
1179 case KindTy::SMTVType:
1180 OS <<
"<smtvtype: ";
1181 OS << SMTVTypeModeToString(getSMTVType());
1189 case KindTy::RegList:
1194 case KindTy::StackAdj:
1195 OS <<
"<stackadj: ";
1199 case KindTy::RegReg:
1200 OS <<
"<RegReg: BaseReg " <<
RegName(
RegReg.BaseReg) <<
" OffsetReg "
1206 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1207 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1214 static std::unique_ptr<RISCVOperand>
1215 createReg(MCRegister
Reg, SMLoc S, SMLoc
E,
bool IsGPRAsFPR =
false) {
1216 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1218 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1224 static std::unique_ptr<RISCVOperand> createExpr(
const MCExpr *Val, SMLoc S,
1225 SMLoc
E,
bool IsRV64) {
1226 auto Op = std::make_unique<RISCVOperand>(KindTy::Expression);
1227 Op->Expr.Expr = Val;
1228 Op->Expr.IsRV64 = IsRV64;
1234 static std::unique_ptr<RISCVOperand> createFPImm(
uint64_t Val, SMLoc S) {
1235 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1236 Op->FPImm.Val = Val;
1242 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1243 unsigned Encoding) {
1244 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1245 Op->SysReg.Data = Str.data();
1246 Op->SysReg.Length = Str.size();
1253 static std::unique_ptr<RISCVOperand>
1255 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1262 static std::unique_ptr<RISCVOperand>
1264 auto Op = std::make_unique<RISCVOperand>(KindTy::SMTVType);
1265 Op->SMTVType.SMTVType = VType;
1271 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val, SMLoc S) {
1272 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1273 Op->Fence.Val = Val;
1279 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI, SMLoc S) {
1280 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1281 Op->VType.Val = VTypeI;
1287 static std::unique_ptr<RISCVOperand> createRegList(
unsigned RlistEncode,
1289 auto Op = std::make_unique<RISCVOperand>(KindTy::RegList);
1295 static std::unique_ptr<RISCVOperand>
1296 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {
1297 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1299 Op->RegReg.OffsetReg = OffsetReg;
1305 static std::unique_ptr<RISCVOperand> createStackAdj(
unsigned StackAdj, SMLoc S) {
1306 auto Op = std::make_unique<RISCVOperand>(KindTy::StackAdj);
1307 Op->StackAdj.Val = StackAdj;
1312 static void addExpr(MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1313 assert(Expr &&
"Expr shouldn't be null!");
1325 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1326 assert(
N == 1 &&
"Invalid number of operands!");
1330 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1331 assert(
N == 1 &&
"Invalid number of operands!");
1332 addExpr(Inst,
getExpr(), isRV64Expr());
1335 template <
unsigned Bits>
1336 void addSExtImmOperands(MCInst &Inst,
unsigned N)
const {
1337 assert(
N == 1 &&
"Invalid number of operands!");
1344 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
1345 assert(
N == 1 &&
"Invalid number of operands!");
1347 addExpr(Inst,
getExpr(), isRV64Expr());
1352 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1356 void addFenceArgOperands(MCInst &Inst,
unsigned N)
const {
1357 assert(
N == 1 &&
"Invalid number of operands!");
1361 void addCSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
1362 assert(
N == 1 &&
"Invalid number of operands!");
1369 void addVTypeIOperands(MCInst &Inst,
unsigned N)
const {
1370 assert(
N == 1 &&
"Invalid number of operands!");
1372 if (Kind == KindTy::Expression) {
1373 [[maybe_unused]]
bool IsConstantImm =
1375 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1382 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1383 assert(
N == 1 &&
"Invalid number of operands!");
1387 void addRegRegOperands(MCInst &Inst,
unsigned N)
const {
1388 assert(
N == 2 &&
"Invalid number of operands!");
1393 void addStackAdjOperands(MCInst &Inst,
unsigned N)
const {
1394 assert(
N == 1 &&
"Invalid number of operands!");
1398 void addFRMArgOperands(MCInst &Inst,
unsigned N)
const {
1399 assert(
N == 1 &&
"Invalid number of operands!");
1403 void addSMTVTypeOperand(MCInst &Inst,
unsigned N)
const {
1404 assert(
N == 1 &&
"Invalid number of operands!");
1410#define GET_REGISTER_MATCHER
1411#define GET_SUBTARGET_FEATURE_NAME
1412#define GET_MATCHER_IMPLEMENTATION
1413#define GET_MNEMONIC_SPELL_CHECKER
1414#include "RISCVGenAsmMatcher.inc"
1417 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1418 return Reg - RISCV::F0_D + RISCV::F0_H;
1422 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1423 return Reg - RISCV::F0_D + RISCV::F0_F;
1427 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1428 return Reg - RISCV::F0_D + RISCV::F0_Q;
1432 assert(
Reg >= RISCV::X0 &&
Reg <= RISCV::X31 &&
"Invalid register");
1433 return Reg - RISCV::X0 + RISCV::X0_Y;
1438 unsigned RegClassID;
1439 if (Kind == MCK_VRM2)
1440 RegClassID = RISCV::VRM2RegClassID;
1441 else if (Kind == MCK_VRM4)
1442 RegClassID = RISCV::VRM4RegClassID;
1443 else if (Kind == MCK_VRM8)
1444 RegClassID = RISCV::VRM8RegClassID;
1448 &getRISCVMCRegisterClass(RegClassID));
1452 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1453 return Reg - RISCV::F0_D + RISCV::F0_Q2;
1458 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1460 return Match_InvalidOperand;
1462 MCRegister
Reg =
Op.getReg();
1464 getRISCVMCRegisterClass(RISCV::FPR64RegClassID).contains(
Reg);
1466 getRISCVMCRegisterClass(RISCV::FPR64CRegClassID).contains(
Reg);
1467 bool IsRegVR = getRISCVMCRegisterClass(RISCV::VRRegClassID).contains(
Reg);
1469 if (
Op.isGPR() && Kind == MCK_YGPR) {
1472 return Match_Success;
1474 if (IsRegFPR64 && Kind == MCK_FPR256) {
1476 return Match_Success;
1478 if (IsRegFPR64 && Kind == MCK_FPR128) {
1480 return Match_Success;
1484 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1485 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1487 return Match_Success;
1491 if (IsRegFPR64 && Kind == MCK_FPR16) {
1493 return Match_Success;
1495 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1496 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_H;
1497 return Match_Success;
1499 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1500 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_W;
1501 return Match_Success;
1508 if (getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg) &&
1509 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1511 return Match_Success;
1515 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1518 return Match_InvalidOperand;
1519 return Match_Success;
1521 return Match_InvalidOperand;
1524bool RISCVAsmParser::generateImmOutOfRangeError(
1525 SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
1526 const Twine &
Msg =
"immediate must be an integer in the range") {
1533std::string RISCVAsmParser::getCustomOperandDiag(
unsigned MatchError) {
1535 StringRef
Msg =
"immediate must be an integer in the range") {
1536 return (
Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]").str();
1539 switch (MatchError) {
1543 if (
const char *Diag = getMatchKindDiag((RISCVMatchResultTy)MatchError))
1545 return std::string();
1546 case Match_InvalidImmXLenLI:
1548 return "operand must be a constant 64-bit integer";
1549 return Range(std::numeric_limits<int32_t>::min(),
1550 std::numeric_limits<uint32_t>::max());
1551 case Match_InvalidImmXLenLI_Restricted:
1553 return "operand either must be a constant 64-bit integer "
1554 "or a bare symbol name";
1555 return Range(std::numeric_limits<int32_t>::min(),
1556 std::numeric_limits<uint32_t>::max(),
1557 "operand either must be a bare symbol name or an immediate "
1558 "integer in the range");
1559 case Match_InvalidUImmLog2XLen:
1561 return Range(0, (1 << 6) - 1);
1562 return Range(0, (1 << 5) - 1);
1563 case Match_InvalidUImmLog2XLenNonZero:
1565 return Range(1, (1 << 6) - 1);
1566 return Range(1, (1 << 5) - 1);
1567 case Match_InvalidUImm1:
1568 return Range(0, (1 << 1) - 1);
1569 case Match_InvalidUImm2:
1570 return Range(0, (1 << 2) - 1);
1571 case Match_InvalidUImm2Lsb0:
1572 return Range(0, 2,
"immediate must be one of");
1573 case Match_InvalidUImm3:
1574 return Range(0, (1 << 3) - 1);
1575 case Match_InvalidUImm4:
1576 return Range(0, (1 << 4) - 1);
1577 case Match_InvalidUImm4Plus1:
1578 return Range(1, (1 << 4));
1579 case Match_InvalidUImm5:
1580 return Range(0, (1 << 5) - 1);
1581 case Match_InvalidUImm5NonZero:
1582 return Range(1, (1 << 5) - 1);
1583 case Match_InvalidUImm5GT3:
1584 return Range(4, (1 << 5) - 1);
1585 case Match_InvalidUImm5Plus1:
1586 return Range(1, (1 << 5));
1587 case Match_InvalidUImm5GE6Plus1:
1588 return Range(6, (1 << 5));
1589 case Match_InvalidUImm5Slist:
1590 return "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31";
1591 case Match_InvalidUImm6:
1592 return Range(0, (1 << 6) - 1);
1593 case Match_InvalidUImm6Plus1:
1594 return Range(1, (1 << 6));
1595 case Match_InvalidUImm7:
1596 return Range(0, (1 << 7) - 1);
1597 case Match_InvalidUImm8:
1598 return Range(0, (1 << 8) - 1);
1599 case Match_InvalidUImm8GE32:
1600 return Range(32, (1 << 8) - 1);
1601 case Match_InvalidSImm5:
1602 return Range(-(1 << 4), (1 << 4) - 1);
1603 case Match_InvalidSImm5NonZero:
1604 return Range(-(1 << 4), (1 << 4) - 1,
1605 "immediate must be non-zero in the range");
1606 case Match_InvalidSImm6:
1607 return Range(-(1 << 5), (1 << 5) - 1);
1608 case Match_InvalidSImm6NonZero:
1609 return Range(-(1 << 5), (1 << 5) - 1,
1610 "immediate must be non-zero in the range");
1611 case Match_InvalidCLUIImm:
1612 return Range(1, (1 << 5) - 1,
"immediate must be in [0xfffe0, 0xfffff] or");
1613 case Match_InvalidUImm5Lsb0:
1614 return Range(0, (1 << 5) - 2,
1615 "immediate must be a multiple of 2 bytes in the range");
1616 case Match_InvalidUImm6Lsb0:
1617 return Range(0, (1 << 6) - 2,
1618 "immediate must be a multiple of 2 bytes in the range");
1619 case Match_InvalidUImm6Lsb000:
1620 return Range(0, (1 << 6) - 8,
1621 "immediate must be a multiple of 8 in the range");
1622 case Match_InvalidUImm7Lsb00:
1623 return Range(0, (1 << 7) - 4,
1624 "immediate must be a multiple of 4 bytes in the range");
1625 case Match_InvalidUImm8Lsb00:
1626 return Range(0, (1 << 8) - 4,
1627 "immediate must be a multiple of 4 bytes in the range");
1628 case Match_InvalidUImm8Lsb000:
1629 return Range(0, (1 << 8) - 8,
1630 "immediate must be a multiple of 8 bytes in the range");
1631 case Match_InvalidUImm9:
1632 return Range(0, (1 << 9) - 1,
"immediate offset must be in the range");
1633 case Match_InvalidBareSImm9Lsb0:
1634 return Range(-(1 << 8), (1 << 8) - 2,
1635 "immediate must be a multiple of 2 bytes in the range");
1636 case Match_InvalidUImm9Lsb000:
1637 return Range(0, (1 << 9) - 8,
1638 "immediate must be a multiple of 8 bytes in the range");
1639 case Match_InvalidSImm8PLI_B:
1640 return Range(-(1 << 7), (1 << 8) - 1);
1641 case Match_InvalidSImm10:
1642 case Match_InvalidSImm10PLI_H:
1643 case Match_InvalidSImm10PLI_W:
1644 return Range(-(1 << 9), (1 << 9) - 1);
1645 case Match_InvalidSImm10PLUI:
1646 return Range(-(1 << 9), (1 << 10) - 1);
1647 case Match_InvalidUImm10Lsb00NonZero:
1648 return Range(4, (1 << 10) - 4,
1649 "immediate must be a multiple of 4 bytes in the range");
1650 case Match_InvalidSImm10Lsb0000NonZero:
1652 -(1 << 9), (1 << 9) - 16,
1653 "immediate must be a multiple of 16 bytes and non-zero in the range");
1654 case Match_InvalidSImm11:
1655 return Range(-(1 << 10), (1 << 10) - 1);
1656 case Match_InvalidBareSImm11Lsb0:
1657 return Range(-(1 << 10), (1 << 10) - 2,
1658 "immediate must be a multiple of 2 bytes in the range");
1659 case Match_InvalidUImm10:
1660 return Range(0, (1 << 10) - 1);
1661 case Match_InvalidUImm11:
1662 return Range(0, (1 << 11) - 1);
1663 case Match_InvalidUImm14Lsb00:
1664 return Range(0, (1 << 14) - 4,
1665 "immediate must be a multiple of 4 bytes in the range");
1666 case Match_InvalidUImm16NonZero:
1667 return Range(1, (1 << 16) - 1);
1668 case Match_InvalidSImm12:
1669 return Range(-(1 << 11), (1 << 11) - 1);
1670 case Match_InvalidSImm12LO:
1671 return Range(-(1 << 11), (1 << 11) - 1,
1672 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo "
1673 "specifier or an integer in the range");
1674 case Match_InvalidBareSImm12Lsb0:
1675 return Range(-(1 << 11), (1 << 11) - 2,
1676 "immediate must be a multiple of 2 bytes in the range");
1677 case Match_InvalidSImm12Lsb00000:
1678 return Range(-(1 << 11), (1 << 11) - 32,
1679 "immediate must be a multiple of 32 bytes in the range");
1680 case Match_InvalidBareSImm13Lsb0:
1681 return Range(-(1 << 12), (1 << 12) - 2,
1682 "immediate must be a multiple of 2 bytes in the range");
1683 case Match_InvalidSImm16:
1684 return Range(-(1 << 15), (1 << 15) - 1);
1685 case Match_InvalidSImm16NonZero:
1686 return Range(-(1 << 15), (1 << 15) - 1,
1687 "immediate must be non-zero in the range");
1688 case Match_InvalidSImm20LI:
1689 return Range(-(1 << 19), (1 << 19) - 1,
1690 "operand must be a symbol with a %qc.abs20 specifier or an "
1691 "integer in the range");
1692 case Match_InvalidUImm20LUI:
1693 return Range(0, (1 << 20) - 1,
1694 "operand must be a symbol with %hi/%tprel_hi specifier or an "
1695 "integer in the range");
1696 case Match_InvalidUImm20:
1697 return Range(0, (1 << 20) - 1);
1698 case Match_InvalidUImm20AUIPC:
1701 "operand must be a symbol with a "
1702 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
1703 "or an integer in the range");
1704 case Match_InvalidBareSImm21Lsb0:
1705 return Range(-(1 << 20), (1 << 20) - 2,
1706 "immediate must be a multiple of 2 bytes in the range");
1707 case Match_InvalidCSRSystemRegister:
1708 return Range(0, (1 << 12) - 1,
1709 "operand must be a valid system register name or an integer "
1711 case Match_InvalidImm5Zibi:
1712 return Range(-1, (1 << 5) - 1,
"immediate must be non-zero in the range");
1713 case Match_InvalidVTypeI:
1714 return "operand must be "
1715 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]";
1716 case Match_InvalidSImm5Plus1:
1717 return Range(-(1 << 4) + 1, (1 << 4),
"immediate must be in the range");
1718 case Match_InvalidSImm18:
1719 return Range(-(1 << 17), (1 << 17) - 1);
1720 case Match_InvalidSImm18Lsb0:
1721 return Range(-(1 << 17), (1 << 17) - 2,
1722 "immediate must be a multiple of 2 bytes in the range");
1723 case Match_InvalidSImm19Lsb00:
1724 return Range(-(1 << 18), (1 << 18) - 4,
1725 "immediate must be a multiple of 4 bytes in the range");
1726 case Match_InvalidSImm20Lsb000:
1727 return Range(-(1 << 19), (1 << 19) - 8,
1728 "immediate must be a multiple of 8 bytes in the range");
1729 case Match_InvalidSImm26:
1730 return Range(-(1 << 25), (1 << 25) - 1);
1732 case Match_InvalidBareSymbolQC_E_LI:
1735 case Match_InvalidBareSImm32:
1736 return Range(std::numeric_limits<int32_t>::min(),
1737 std::numeric_limits<uint32_t>::max());
1738 case Match_InvalidBareSImm32Lsb0:
1739 return Range(std::numeric_limits<int32_t>::min(),
1740 std::numeric_limits<int32_t>::max() - 1,
1741 "operand must be a multiple of 2 bytes in the range");
1742 case Match_InvalidRnumArg:
1743 return Range(0, 10);
1744 case Match_InvalidStackAdj:
1745 return "stack adjustment is invalid for this instruction and register "
1747 case Match_InvalidYBNDSWImm:
1748 return "immediate must be an integer in the range "
1749 "[1, 255], a multiple of 8 in the range [256, 504], "
1750 "or a multiple of 16 in the range [512, 4096]";
1751 case Match_InvalidUImm7EqXLen:
1752 return (
"immediate must be an integer equal to XLEN (" +
1753 Twine(isRV64() ?
"64" :
"32") +
")")
1761void RISCVAsmParser::FilterNearMisses(
1762 SmallVectorImpl<NearMissInfo> &NearMissesIn,
1763 SmallVectorImpl<NearMissMessage> &NearMissesOut, SMLoc IDLoc,
1767 std::multimap<unsigned, unsigned> OperandMissesSeen;
1768 SmallSet<FeatureBitset, 4> FeatureMissesSeen;
1769 bool ReportedTooFewOperands =
false;
1770 bool ReportedTooManyOperands =
false;
1772 for (NearMissInfo &
I : NearMissesIn) {
1773 switch (
I.getKind()) {
1776 ((RISCVOperand &)*
Operands[
I.getOperandIndex()]).getStartLoc();
1781 if (
I.getOperandClass() == InvalidMatchClass) {
1782 if (!ReportedTooManyOperands) {
1784 OperandLoc,
"unexpected extra operand for instruction"});
1785 ReportedTooManyOperands =
true;
1790 std::string OperandDiag = getCustomOperandDiag(
I.getOperandError());
1794 unsigned DupCheckMatchClass =
1795 OperandDiag.empty() ? ~0
U :
I.getOperandClass();
1796 auto PrevReports = OperandMissesSeen.equal_range(
I.getOperandIndex());
1798 PrevReports.first, PrevReports.second,
1799 [DupCheckMatchClass](
const std::pair<unsigned, unsigned> Pair) {
1800 if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
1801 return Pair.second == DupCheckMatchClass;
1802 return isSubclass((MatchClassKind)DupCheckMatchClass,
1803 (MatchClassKind)Pair.second);
1806 OperandMissesSeen.insert(
1807 std::make_pair(
I.getOperandIndex(), DupCheckMatchClass));
1809 NearMissMessage Message;
1810 Message.Loc = OperandLoc;
1811 if (!OperandDiag.empty()) {
1812 Message.Message = OperandDiag;
1814 Message.Message =
"invalid operand for instruction";
1816 dbgs() <<
"Missing diagnostic string for operand class "
1817 << getMatchClassName((MatchClassKind)
I.getOperandClass())
1818 <<
I.getOperandClass() <<
", error " <<
I.getOperandError()
1819 <<
", opcode " << MII.
getName(
I.getOpcode()) <<
"\n");
1825 const FeatureBitset &MissingFeatures =
I.getFeatures();
1827 if (!FeatureMissesSeen.
insert(MissingFeatures).second)
1830 NearMissMessage Message;
1831 Message.Loc = IDLoc;
1832 bool FirstFeature =
true;
1833 Message.Message =
"instruction requires the following:";
1834 for (
unsigned Feature : MissingFeatures) {
1835 Message.Message += FirstFeature ?
" " :
", ";
1837 FirstFeature =
false;
1847 if (!ReportedTooFewOperands) {
1848 SMLoc EndLoc = ((RISCVOperand &)*
Operands.back()).getEndLoc();
1850 NearMissMessage{EndLoc,
"too few operands for instruction"});
1851 ReportedTooFewOperands =
true;
1863void RISCVAsmParser::ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses,
1866 FilterNearMisses(NearMisses, Messages, IDLoc,
Operands);
1871 Error(IDLoc,
"invalid instruction");
1874 Error(Messages[0].Loc, Messages[0].Message);
1879 "invalid instruction, any one of the following would fix this:");
1880 for (
auto &M : Messages)
1885bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1889 bool MatchingInlineAsm) {
1894 MatchInstructionImpl(
Operands, Inst, &NearMisses, MatchingInlineAsm);
1899 if (validateInstruction(Inst,
Operands))
1901 return processInstruction(Inst, IDLoc,
Operands, Out);
1902 case Match_MnemonicFail: {
1903 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1904 std::string Suggestion = RISCVMnemonicSpellCheck(
1906 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1908 case Match_NearMisses:
1909 ReportNearMisses(NearMisses, IDLoc,
Operands);
1920MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name)
const {
1929 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1930 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1931 static_assert(RISCV::F0_D < RISCV::F0_Q,
"FPR matching must be updated");
1934 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1939bool RISCVAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1941 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1942 return Error(StartLoc,
"invalid register name");
1946ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1948 const AsmToken &Tok = getParser().getTok();
1951 StringRef
Name = getLexer().getTok().getIdentifier();
1963 SMLoc FirstS = getLoc();
1964 bool HadParens =
false;
1971 size_t ReadCount = getLexer().peekTokens(Buf);
1974 LParen = getParser().getTok();
1979 switch (getLexer().getKind()) {
1982 getLexer().UnLex(LParen);
1985 StringRef
Name = getLexer().getTok().getIdentifier();
1990 getLexer().UnLex(LParen);
1994 Operands.push_back(RISCVOperand::createToken(
"(", FirstS));
1996 SMLoc
E = getTok().getEndLoc();
1998 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2003 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2014 switch (getLexer().getKind()) {
2024 if (getParser().parseExpression(Res,
E))
2029 int64_t
Imm =
CE->getValue();
2031 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2040 if (getParser().parseIdentifier(Identifier))
2043 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
2046 "Unexpected opcode");
2049 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2059 return generateImmOutOfRangeError(
2061 "opcode must be a valid opcode name or an immediate in the range");
2069 switch (getLexer().getKind()) {
2079 if (getParser().parseExpression(Res,
E))
2084 int64_t
Imm =
CE->getValue();
2085 if (
Imm >= 0 &&
Imm <= 2) {
2086 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2095 if (getParser().parseIdentifier(Identifier))
2099 if (Identifier ==
"C0")
2101 else if (Identifier ==
"C1")
2103 else if (Identifier ==
"C2")
2110 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2119 return generateImmOutOfRangeError(
2121 "opcode must be a valid opcode name or an immediate in the range");
2128 auto SysRegFromConstantInt = [
this](
const MCExpr *
E, SMLoc S) {
2130 int64_t
Imm =
CE->getValue();
2132 auto Range = RISCVSysReg::lookupSysRegByEncoding(
Imm);
2136 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2139 return RISCVOperand::createSysReg(
2140 RISCVSysReg::getSysRegStr(
Reg.Name), S,
Imm);
2144 return RISCVOperand::createSysReg(
"", S,
Imm);
2147 return std::unique_ptr<RISCVOperand>();
2150 switch (getLexer().getKind()) {
2160 if (getParser().parseExpression(Res))
2163 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
2164 Operands.push_back(std::move(SysOpnd));
2168 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2172 if (getParser().parseIdentifier(Identifier))
2175 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
2178 if (SysReg->IsDeprecatedName) {
2180 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
2182 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2184 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
2185 RISCVSysReg::getSysRegStr(
Reg.Name) +
"'");
2190 const auto &FeatureBits = getSTI().getFeatureBits();
2191 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
2192 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
2193 const auto *Feature =
2195 return SysReg->FeaturesRequired[Feature.Value];
2197 std::string ErrorMsg =
2198 std::string(
"system register '") +
2199 std::string(RISCVSysReg::getSysRegStr(SysReg->Name)) +
"' ";
2200 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
2201 ErrorMsg +=
"is RV32 only";
2203 ErrorMsg +=
" and ";
2207 "requires '" + std::string(Feature->key()) +
"' to be enabled";
2210 return Error(S, ErrorMsg);
2213 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
2223 Operands.push_back(std::move(SysOpnd));
2228 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2229 "operand must be a valid system register "
2230 "name or an integer in the range");
2234 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2246 StringRef
Identifier = getTok().getIdentifier();
2247 if (
Identifier.compare_insensitive(
"inf") == 0) {
2250 getTok().getEndLoc(), isRV64()));
2251 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2254 getTok().getEndLoc(), isRV64()));
2255 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2258 getTok().getEndLoc(), isRV64()));
2260 return TokError(
"invalid floating point literal");
2271 const AsmToken &Tok = getTok();
2273 return TokError(
"invalid floating point immediate");
2276 APFloat RealVal(APFloat::IEEEdouble());
2278 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2280 return TokError(
"invalid floating point representation");
2283 RealVal.changeSign();
2285 Operands.push_back(RISCVOperand::createFPImm(
2286 RealVal.bitcastToAPInt().getZExtValue(), S));
2298 switch (getLexer().getKind()) {
2310 if (getParser().parseExpression(Res,
E))
2314 return parseOperandWithSpecifier(
Operands);
2317 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2327 const MCExpr *Expr =
nullptr;
2328 bool Failed = parseExprWithSpecifier(Expr,
E);
2330 Operands.push_back(RISCVOperand::createExpr(Expr, S,
E, isRV64()));
2334bool RISCVAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
2335 SMLoc Loc = getLoc();
2337 return TokError(
"expected '%' relocation specifier");
2338 StringRef
Identifier = getParser().getTok().getIdentifier();
2341 return TokError(
"invalid relocation specifier");
2347 const MCExpr *SubExpr;
2348 if (getParser().parseParenExpression(SubExpr,
E))
2355bool RISCVAsmParser::parseDataExpr(
const MCExpr *&Res) {
2358 return parseExprWithSpecifier(Res,
E);
2359 return getParser().parseExpression(Res);
2369 StringRef
Identifier = getTok().getIdentifier();
2379 if (getParser().parseExpression(Res,
E))
2382 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2392 std::string
Identifier(getTok().getIdentifier());
2398 SMLoc Loc = getLoc();
2399 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2400 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2414 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2426 std::string
Identifier(getTok().getIdentifier());
2432 SMLoc Loc = getLoc();
2433 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2434 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2448 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2457 if (getParser().parseExpression(Res,
E))
2460 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef)
2461 return Error(S,
"operand must be a valid jump target");
2464 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2485bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2486 unsigned &Sew,
unsigned &Lmul,
2487 bool &Fractional,
bool &TailAgnostic,
2488 bool &MaskAgnostic,
bool &AltFmt) {
2493 if (State < VTypeState::SeenSew &&
Identifier.consume_front(
"e")) {
2495 if (Identifier ==
"16alt") {
2498 }
else if (Identifier ==
"8alt") {
2508 State = VTypeState::SeenSew;
2512 if (State < VTypeState::SeenLmul &&
Identifier.consume_front(
"m")) {
2515 if (Identifier ==
"a" || Identifier ==
"u") {
2517 State = VTypeState::SeenMaskPolicy;
2528 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2529 unsigned MinLMUL = ELEN / 8;
2532 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2533 Twine(MinLMUL) +
" is reserved");
2536 State = VTypeState::SeenLmul;
2540 if (State < VTypeState::SeenTailPolicy &&
Identifier.starts_with(
"t")) {
2541 if (Identifier ==
"ta")
2542 TailAgnostic =
true;
2543 else if (Identifier ==
"tu")
2544 TailAgnostic =
false;
2548 State = VTypeState::SeenTailPolicy;
2552 if (State < VTypeState::SeenMaskPolicy &&
Identifier.starts_with(
"m")) {
2553 if (Identifier ==
"ma")
2554 MaskAgnostic =
true;
2555 else if (Identifier ==
"mu")
2556 MaskAgnostic =
false;
2560 State = VTypeState::SeenMaskPolicy;
2573 bool Fractional =
false;
2574 bool TailAgnostic =
false;
2575 bool MaskAgnostic =
false;
2578 VTypeState State = VTypeState::SeenNothingYet;
2580 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2581 MaskAgnostic, AltFmt)) {
2583 if (State == VTypeState::SeenNothingYet)
2592 State == VTypeState::SeenNothingYet)
2593 return generateVTypeError(S);
2597 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2598 unsigned MaxSEW = ELEN / Lmul;
2600 if (MaxSEW >= 8 && Sew > MaxSEW)
2601 Warning(S,
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2602 " and LMUL == mf" + Twine(Lmul) +
2603 " may not be compatible with all RVV implementations");
2608 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2612bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2613 return Error(ErrorLoc,
2615 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2635 if (Identifier !=
"16alt")
2664 Operands.push_back(RISCVOperand::createVType(
2670 return generateXSfmmVTypeError(S);
2673bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
2674 return Error(ErrorLoc,
"operand must be e[8|16|16alt|32|64],w[1|2|4]");
2681 StringRef
Name = getLexer().getTok().getIdentifier();
2682 if (!
Name.consume_back(
".t")) {
2686 return Error(getLoc(),
"expected '.t' suffix");
2693 if (
Reg != RISCV::V0)
2696 SMLoc
E = getTok().getEndLoc();
2698 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2706 StringRef
Name = getLexer().getTok().getIdentifier();
2707 if (!
Name.consume_back(
".scale"))
2708 return Error(getLoc(),
"expected '.scale' suffix");
2713 if (
Reg != RISCV::V0)
2716 SMLoc
E = getTok().getEndLoc();
2718 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2727 StringRef
Name = getLexer().getTok().getIdentifier();
2728 if (!
Name.consume_front(
"L") && !
Name.consume_front(
"l"))
2733 return Error(S,
"operand must be L1, L2, L4, L8, L16, L32, or L64");
2735 unsigned EncodedLambda =
Log2_32(Lambda) + 1;
2737 SMLoc
E = getTok().getEndLoc();
2739 Operands.push_back(RISCVOperand::createExpr(
2745 if (!isRV64() || getSTI().
hasFeature(RISCV::FeatureStdExtF))
2755 StringRef
Name = getLexer().getTok().getIdentifier();
2761 SMLoc
E = getTok().getEndLoc();
2763 Operands.push_back(RISCVOperand::createReg(
2769 if (isRV64() || getSTI().
hasFeature(RISCV::FeatureStdExtF))
2775 StringRef
Name = getLexer().getTok().getIdentifier();
2781 if (!getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg))
2784 if ((
Reg - RISCV::X0) & 1) {
2787 if (getSTI().
hasFeature(RISCV::FeatureStdExtZfinx))
2788 return TokError(
"double precision floating point operands must use even "
2789 "numbered X register");
2794 SMLoc
E = getTok().getEndLoc();
2797 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2799 Reg, RISCV::sub_gpr_even,
2800 &getRISCVMCRegisterClass(RISCV::GPRPairRegClassID));
2801 Operands.push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2805template <
bool IsRV64>
2807 return parseGPRPair(
Operands, IsRV64);
2817 if (!IsRV64Inst && isRV64())
2823 StringRef
Name = getLexer().getTok().getIdentifier();
2829 if (!getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg))
2832 if ((
Reg - RISCV::X0) & 1)
2833 return TokError(
"register must be even");
2836 SMLoc
E = getTok().getEndLoc();
2839 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2841 Reg, RISCV::sub_gpr_even,
2842 &getRISCVMCRegisterClass(RISCV::GPRPairRegClassID));
2843 Operands.push_back(RISCVOperand::createReg(Pair, S,
E));
2850 "operand must be a valid SpacemiT's Integer Matrix VType mnemonic");
2852 StringRef Str = getLexer().getTok().getIdentifier();
2855 if (!isValidSMTVTypeMode(VType))
2856 return TokError(
"SpacemiT's Integer Matrix only supports [i4|i8] mode");
2858 Operands.push_back(RISCVOperand::createSMTVType(VType, getLoc()));
2866 "operand must be a valid floating point rounding mode mnemonic");
2868 StringRef Str = getLexer().getTok().getIdentifier();
2873 "operand must be a valid floating point rounding mode mnemonic");
2875 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2880std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultSMTVType() {
2881 return RISCVOperand::createSMTVType(XSMTVTypeMode::SMTVTypeMode::SMT_I8,
2886 const AsmToken &Tok = getLexer().getTok();
2892 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2906 for (
char c : Str) {
2935 Operands.push_back(RISCVOperand::createFenceArg(
Imm, getLoc()));
2941 return TokError(
"operand must be formed of letters selected in-order from "
2948 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
2950 if (!parseRegister(
Operands).isSuccess())
2951 return Error(getLoc(),
"expected register");
2955 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2979 std::unique_ptr<RISCVOperand> OptionalImmOp;
2986 SMLoc ImmStart = getLoc();
2987 if (getParser().parseIntToken(ImmVal,
2988 "expected '(' or optional integer offset"))
2993 SMLoc ImmEnd = getLoc();
2996 ImmStart, ImmEnd, isRV64());
3000 OptionalImmOp ?
"expected '(' after optional integer offset"
3001 :
"expected '(' or optional integer offset"))
3004 if (!parseRegister(
Operands).isSuccess())
3005 return Error(getLoc(),
"expected register");
3011 if (OptionalImmOp && !OptionalImmOp->isImmZero())
3013 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
3014 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
3025 StringRef OffsetRegName = getLexer().getTok().getIdentifier();
3028 !getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(OffsetReg))
3029 return Error(getLoc(),
"expected GPR register");
3036 return Error(getLoc(),
"expected GPR register");
3038 StringRef BaseRegName = getLexer().getTok().getIdentifier();
3041 !getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(BaseReg))
3042 return Error(getLoc(),
"expected GPR register");
3048 Operands.push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));
3061 bool MustIncludeS0) {
3073 return Error(getLoc(),
"invalid register");
3075 StringRef
RegName = getTok().getIdentifier();
3078 return Error(getLoc(),
"invalid register");
3081 UsesXRegs =
RegName[0] ==
'x';
3082 if (
Reg != RISCV::X1)
3083 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
3084 }
else if (RegEnd == RISCV::X1) {
3085 if (
Reg != RISCV::X8 || (UsesXRegs != (
RegName[0] ==
'x')))
3086 return Error(getLoc(), Twine(
"register must be '") +
3087 (UsesXRegs ?
"x8" :
"s0") +
"'");
3088 }
else if (RegEnd == RISCV::X9 && UsesXRegs) {
3089 if (
Reg != RISCV::X18 || (
RegName[0] !=
'x'))
3090 return Error(getLoc(),
"register must be 'x18'");
3092 return Error(getLoc(),
"too many register ranges");
3099 SMLoc MinusLoc = getLoc();
3101 if (RegEnd == RISCV::X1)
3102 return Error(MinusLoc, Twine(
"register '") + (UsesXRegs ?
"x1" :
"ra") +
3103 "' cannot start a multiple register range");
3106 return Error(getLoc(),
"invalid register");
3108 StringRef
RegName = getTok().getIdentifier();
3111 return Error(getLoc(),
"invalid register");
3113 if (RegEnd == RISCV::X8) {
3114 if ((
Reg != RISCV::X9 &&
3116 (UsesXRegs != (
RegName[0] ==
'x'))) {
3118 return Error(getLoc(),
"register must be 'x9'");
3119 return Error(getLoc(),
"register must be in the range 's1' to 's11'");
3121 }
else if (RegEnd == RISCV::X18) {
3123 return Error(getLoc(),
3124 "register must be in the range 'x19' to 'x27'");
3137 if (RegEnd == RISCV::X26)
3138 return Error(S,
"invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "
3139 "x18-x26}' is not supported");
3145 return Error(S,
"register list must include 's0' or 'x8'");
3147 Operands.push_back(RISCVOperand::createRegList(Encode, S));
3153 bool ExpectNegative) {
3162 auto *RegListOp =
static_cast<RISCVOperand *
>(
Operands.back().
get());
3163 if (!RegListOp->isRegList())
3166 unsigned RlistEncode = RegListOp->RegList.Encoding;
3170 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||
3171 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {
3172 int64_t
Lower = StackAdjBase;
3173 int64_t
Upper = StackAdjBase + 48;
3174 if (ExpectNegative) {
3179 return generateImmOutOfRangeError(S,
Lower,
Upper,
3180 "stack adjustment for register list must "
3181 "be a multiple of 16 bytes in the range");
3185 Operands.push_back(RISCVOperand::createStackAdj(StackAdj, S));
3197 MatchOperandParserImpl(
Operands, Mnemonic,
true);
3204 if (parseRegister(
Operands,
true).isSuccess())
3208 if (parseExpression(
Operands).isSuccess()) {
3211 return !parseMemOpBaseReg(
Operands).isSuccess();
3216 Error(getLoc(),
"unknown operand");
3220bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &Info,
3221 StringRef Name, SMLoc NameLoc,
3227 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
3231 Operands.push_back(RISCVOperand::createToken(Name, NameLoc));
3250 if (getParser().parseEOL(
"unexpected token")) {
3251 getParser().eatToEndOfStatement();
3257bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
3261 Kind = RE->getSpecifier();
3262 Expr = RE->getSubExpr();
3271bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
3280ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
3281 StringRef IDVal = DirectiveID.
getString();
3283 if (IDVal ==
".option")
3284 return parseDirectiveOption();
3285 if (IDVal ==
".attribute")
3286 return parseDirectiveAttribute();
3287 if (IDVal ==
".insn")
3288 return parseDirectiveInsn(DirectiveID.
getLoc());
3289 if (IDVal ==
".variant_cc")
3290 return parseDirectiveVariantCC();
3295bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
3296 bool FromOptionDirective) {
3297 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
3300 clearFeatureBits(Feature.Value, Feature.key());
3307 raw_string_ostream OutputErrMsg(Buffer);
3308 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3309 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
3310 << ErrMsg.getMessage();
3313 return Error(Loc, OutputErrMsg.str());
3315 auto &ISAInfo = *ParseResult;
3318 if (ISAInfo->hasExtension(Feature.key()))
3319 setFeatureBits(Feature.Value, Feature.key());
3321 if (FromOptionDirective) {
3322 if (ISAInfo->getXLen() == 32 && isRV64())
3323 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3324 else if (ISAInfo->getXLen() == 64 && !isRV64())
3325 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3328 if (ISAInfo->getXLen() == 32)
3329 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
3330 else if (ISAInfo->getXLen() == 64)
3331 setFeatureBits(RISCV::Feature64Bit,
"64bit");
3333 return Error(Loc,
"bad arch string " + Arch);
3335 Result = ISAInfo->toString();
3339bool RISCVAsmParser::parseDirectiveOption() {
3340 MCAsmParser &Parser = getParser();
3342 AsmToken Tok = Parser.
getTok();
3350 if (Option ==
"push") {
3354 getTargetStreamer().emitDirectiveOptionPush();
3359 if (Option ==
"pop") {
3364 getTargetStreamer().emitDirectiveOptionPop();
3365 if (popFeatureBits())
3366 return Error(StartLoc,
".option pop with no .option push");
3371 if (Option ==
"arch") {
3379 Type = RISCVOptionArchArgType::Plus;
3381 Type = RISCVOptionArchArgType::Minus;
3382 else if (!
Args.empty())
3384 "unexpected token, expected + or -");
3386 Type = RISCVOptionArchArgType::Full;
3390 "unexpected token, expected identifier");
3396 if (
Type == RISCVOptionArchArgType::Full) {
3398 if (resetToArch(Arch, Loc, Result,
true))
3407 Loc,
"extension version number parsing not currently implemented");
3410 if (!enableExperimentalExtension() &&
3412 return Error(Loc,
"unexpected experimental extensions");
3413 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
3415 if (Ext == std::end(
AllFeatures) || StringRef(Ext->key()) != Feature)
3416 return Error(Loc,
"unknown extension feature");
3420 if (
Type == RISCVOptionArchArgType::Plus) {
3423 setFeatureBits(Ext->Value, Ext->key());
3426 copySTI().setFeatureBits(OldFeatureBits);
3427 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3430 raw_string_ostream OutputErrMsg(Buffer);
3431 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3432 OutputErrMsg << ErrMsg.getMessage();
3435 return Error(Loc, OutputErrMsg.str());
3438 assert(
Type == RISCVOptionArchArgType::Minus);
3444 Feature.Implies.test(Ext->Value))
3445 return Error(Loc, Twine(
"can't disable ") + Ext->key() +
3446 " extension; " + Feature.key() +
3447 " extension requires " + Ext->key() +
3451 clearFeatureBits(Ext->Value, Ext->key());
3458 getTargetStreamer().emitDirectiveOptionArch(Args);
3461 getTargetStreamer().setArchString((*ParseResult)->toString());
3465 if (Option ==
"exact") {
3469 getTargetStreamer().emitDirectiveOptionExact();
3470 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3471 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3475 if (Option ==
"noexact") {
3479 getTargetStreamer().emitDirectiveOptionNoExact();
3480 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3481 setFeatureBits(RISCV::FeatureRelax,
"relax");
3485 if (Option ==
"rvc") {
3489 getTargetStreamer().emitDirectiveOptionRVC();
3490 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3492 getTargetStreamer().setArchString((*ParseResult)->toString());
3496 if (Option ==
"norvc") {
3500 getTargetStreamer().emitDirectiveOptionNoRVC();
3501 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3502 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3504 getTargetStreamer().setArchString((*ParseResult)->toString());
3508 if (Option ==
"pic") {
3512 getTargetStreamer().emitDirectiveOptionPIC();
3513 ParserOptions.IsPicEnabled =
true;
3517 if (Option ==
"nopic") {
3521 getTargetStreamer().emitDirectiveOptionNoPIC();
3522 ParserOptions.IsPicEnabled =
false;
3526 if (Option ==
"relax") {
3530 getTargetStreamer().emitDirectiveOptionRelax();
3531 setFeatureBits(RISCV::FeatureRelax,
"relax");
3535 if (Option ==
"norelax") {
3539 getTargetStreamer().emitDirectiveOptionNoRelax();
3540 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3546 "unknown option, expected 'push', 'pop', "
3547 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3548 "'exact', or 'noexact'");
3556bool RISCVAsmParser::parseDirectiveAttribute() {
3557 MCAsmParser &Parser = getParser();
3563 std::optional<unsigned> Ret =
3566 return Error(TagLoc,
"attribute name not recognised: " + Name);
3570 const MCExpr *AttrExpr;
3577 if (check(!CE, TagLoc,
"expected numeric constant"))
3580 Tag =
CE->getValue();
3586 StringRef StringValue;
3587 int64_t IntegerValue = 0;
3588 bool IsIntegerValue =
true;
3593 IsIntegerValue =
false;
3596 if (IsIntegerValue) {
3597 const MCExpr *ValueExpr;
3603 return Error(ValueExprLoc,
"expected numeric constant");
3604 IntegerValue =
CE->getValue();
3617 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3619 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3622 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3626 getTargetStreamer().emitTextAttribute(
Tag, Result);
3630 getTargetStreamer().setArchString(Result);
3638 .
Cases({
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s"},
true)
3639 .Cases({
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj"},
3641 .
Cases({
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es"},
3650bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3651 MCAsmParser &Parser = getParser();
3658 std::optional<int64_t>
Length;
3668 return Error(ErrorLoc,
3669 "instruction lengths must be a non-zero multiple of two");
3673 return Error(ErrorLoc,
3674 "instruction lengths over 64 bits are not supported");
3680 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3685 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3686 return Error(ErrorLoc,
3687 "instruction length does not match the encoding");
3690 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3693 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3696 if (!getSTI().
hasFeature(RISCV::FeatureStdExtZca) &&
3697 (EncodingDerivedLength == 2))
3698 return Error(ErrorLoc,
"compressed instructions are not allowed");
3700 if (getParser().parseEOL(
"invalid operand for instruction")) {
3701 getParser().eatToEndOfStatement();
3709 Opcode = RISCV::Insn16;
3712 Opcode = RISCV::Insn32;
3715 Opcode = RISCV::Insn48;
3718 Opcode = RISCV::Insn64;
3724 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3726 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3731 return Error(ErrorLoc,
"invalid instruction format");
3733 std::string FormatName = (
".insn_" +
Format).str();
3735 ParseInstructionInfo
Info;
3738 if (parseInstruction(Info, FormatName, L,
Operands))
3750bool RISCVAsmParser::parseDirectiveVariantCC() {
3752 if (getParser().parseIdentifier(Name))
3753 return TokError(
"expected symbol name");
3756 getTargetStreamer().emitDirectiveVariantCC(
3761void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3764 const MCSubtargetInfo &STI = getSTI();
3765 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3768 ++RISCVNumInstrsCompressed;
3772void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3777 for (MCInst &Inst : Seq) {
3778 emitToStreamer(Out, Inst);
3782void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3783 const MCExpr *Symbol,
3785 unsigned SecondOpcode, SMLoc IDLoc,
3793 Out.emitLabel(TmpLabel);
3797 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3802 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3805 .addExpr(RefToLinkTmpLabel));
3808void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3821 Out, MCInstBuilder(RISCV::QC_E_LI).addReg(DestReg).addExpr(Symbol));
3827void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3837 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3838 emitAuipcInstPair(DestReg, DestReg, Symbol,
RISCV::S_GOT_HI, SecondOpcode,
3842void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3851 if (ParserOptions.IsPicEnabled)
3852 emitLoadGlobalAddress(Inst, IDLoc, Out);
3854 emitLoadLocalAddress(Inst, IDLoc, Out);
3857void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3867 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3868 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3869 SecondOpcode, IDLoc, Out);
3872void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3882 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3883 RISCV::ADDI, IDLoc, Out);
3886void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3887 SMLoc IDLoc, MCStreamer &Out,
3896 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3898 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3902 if (getRISCVMCRegisterClass(RISCV::GPRPairRegClassID).
contains(TmpReg)) {
3903 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3904 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3912void RISCVAsmParser::emitQCELILoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3913 SMLoc IDLoc, MCStreamer &Out,
3923 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3927 MCInstBuilder(RISCV::QC_E_LI).addReg(AddrReg).addExpr(Symbol));
3930 const MCExpr *AccessExpr =
3936 struct CompressedForm {
3940 std::optional<CompressedForm> Compressed;
3944 case RISCV::PseudoQCAccessLBU:
3945 Compressed = {RISCV::PseudoQCAccessC_LBU, RISCV::FeatureStdExtZcb};
3947 case RISCV::PseudoQCAccessLH:
3948 Compressed = {RISCV::PseudoQCAccessC_LH, RISCV::FeatureStdExtZcb};
3950 case RISCV::PseudoQCAccessLHU:
3951 Compressed = {RISCV::PseudoQCAccessC_LHU, RISCV::FeatureStdExtZcb};
3953 case RISCV::PseudoQCAccessLW:
3954 Compressed = {RISCV::PseudoQCAccessC_LW, RISCV::FeatureStdExtZca};
3956 case RISCV::PseudoQCAccessSB:
3957 Compressed = {RISCV::PseudoQCAccessC_SB, RISCV::FeatureStdExtZcb};
3959 case RISCV::PseudoQCAccessSH:
3960 Compressed = {RISCV::PseudoQCAccessC_SH, RISCV::FeatureStdExtZcb};
3962 case RISCV::PseudoQCAccessSW:
3963 Compressed = {RISCV::PseudoQCAccessC_SW, RISCV::FeatureStdExtZca};
3970 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(AddrReg);
3971 if (HasTmpReg && CanUseGPRC) {
3974 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(DataReg);
3977 bool UseCompressed =
3978 Compressed && getSTI().hasFeature(Compressed->Feature) && CanUseGPRC;
3980 unsigned ActualOpcode = UseCompressed ? Compressed->Opcode : Opcode;
3983 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3987 .addExpr(AccessExpr));
3989 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3993 .addExpr(AccessExpr));
3997void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3998 int64_t Width, SMLoc IDLoc,
4007 const MCOperand &DestReg = Inst.
getOperand(0);
4008 const MCOperand &SourceReg = Inst.
getOperand(1);
4010 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
4011 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
4013 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
4015 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
4020 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
4026void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
4033 emitToStreamer(Out, MCInstBuilder(Opcode)
4037 .addReg(MCRegister())
4039 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
4050 "The destination register should not be V0.");
4052 emitToStreamer(Out, MCInstBuilder(Opcode)
4058 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
4070 "The temporary vector register should not be V0.");
4071 emitToStreamer(Out, MCInstBuilder(Opcode)
4075 .addReg(MCRegister())
4077 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4089 "The temporary vector register should not be V0.");
4090 emitToStreamer(Out, MCInstBuilder(Opcode)
4094 .addReg(MCRegister())
4096 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4101 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4106 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
4114bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
4116 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
4119 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
4120 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
4121 "%tprel_add specifier");
4127bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
4129 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
4132 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
4133 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
4134 "%tlsdesc_call specifier");
4140std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
4141 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
4144std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
4145 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
4149std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
4150 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
4154std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultZeroOffset() {
4156 llvm::SMLoc(), llvm::SMLoc(), isRV64());
4163 case RISCV::VLOXSEG2EI8_V:
4164 case RISCV::VLOXSEG2EI16_V:
4165 case RISCV::VLOXSEG2EI32_V:
4166 case RISCV::VLOXSEG2EI64_V:
4167 case RISCV::VLUXSEG2EI8_V:
4168 case RISCV::VLUXSEG2EI16_V:
4169 case RISCV::VLUXSEG2EI32_V:
4170 case RISCV::VLUXSEG2EI64_V:
4172 case RISCV::VLOXSEG3EI8_V:
4173 case RISCV::VLOXSEG3EI16_V:
4174 case RISCV::VLOXSEG3EI32_V:
4175 case RISCV::VLOXSEG3EI64_V:
4176 case RISCV::VLUXSEG3EI8_V:
4177 case RISCV::VLUXSEG3EI16_V:
4178 case RISCV::VLUXSEG3EI32_V:
4179 case RISCV::VLUXSEG3EI64_V:
4181 case RISCV::VLOXSEG4EI8_V:
4182 case RISCV::VLOXSEG4EI16_V:
4183 case RISCV::VLOXSEG4EI32_V:
4184 case RISCV::VLOXSEG4EI64_V:
4185 case RISCV::VLUXSEG4EI8_V:
4186 case RISCV::VLUXSEG4EI16_V:
4187 case RISCV::VLUXSEG4EI32_V:
4188 case RISCV::VLUXSEG4EI64_V:
4190 case RISCV::VLOXSEG5EI8_V:
4191 case RISCV::VLOXSEG5EI16_V:
4192 case RISCV::VLOXSEG5EI32_V:
4193 case RISCV::VLOXSEG5EI64_V:
4194 case RISCV::VLUXSEG5EI8_V:
4195 case RISCV::VLUXSEG5EI16_V:
4196 case RISCV::VLUXSEG5EI32_V:
4197 case RISCV::VLUXSEG5EI64_V:
4199 case RISCV::VLOXSEG6EI8_V:
4200 case RISCV::VLOXSEG6EI16_V:
4201 case RISCV::VLOXSEG6EI32_V:
4202 case RISCV::VLOXSEG6EI64_V:
4203 case RISCV::VLUXSEG6EI8_V:
4204 case RISCV::VLUXSEG6EI16_V:
4205 case RISCV::VLUXSEG6EI32_V:
4206 case RISCV::VLUXSEG6EI64_V:
4208 case RISCV::VLOXSEG7EI8_V:
4209 case RISCV::VLOXSEG7EI16_V:
4210 case RISCV::VLOXSEG7EI32_V:
4211 case RISCV::VLOXSEG7EI64_V:
4212 case RISCV::VLUXSEG7EI8_V:
4213 case RISCV::VLUXSEG7EI16_V:
4214 case RISCV::VLUXSEG7EI32_V:
4215 case RISCV::VLUXSEG7EI64_V:
4217 case RISCV::VLOXSEG8EI8_V:
4218 case RISCV::VLOXSEG8EI16_V:
4219 case RISCV::VLOXSEG8EI32_V:
4220 case RISCV::VLOXSEG8EI64_V:
4221 case RISCV::VLUXSEG8EI8_V:
4222 case RISCV::VLUXSEG8EI16_V:
4223 case RISCV::VLUXSEG8EI32_V:
4224 case RISCV::VLUXSEG8EI64_V:
4230 if (getRISCVMCRegisterClass(RISCV::VRM2RegClassID).
contains(
Reg))
4232 if (getRISCVMCRegisterClass(RISCV::VRM4RegClassID).
contains(
Reg))
4234 if (getRISCVMCRegisterClass(RISCV::VRM8RegClassID).
contains(
Reg))
4241 case RISCV::VFWMMACC_VV_SCALE:
4242 case RISCV::VFQMMACC_VV_SCALE:
4243 case RISCV::VF8WMMACC_VV_SCALE:
4244 case RISCV::VFWIMMACC_VV:
4245 case RISCV::VFQIMMACC_VV:
4246 case RISCV::VF8WIMMACC_VV:
4253bool RISCVAsmParser::validateInstruction(MCInst &Inst,
4257 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
4258 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
4261 if (DestReg == TempReg) {
4262 SMLoc Loc =
Operands.back()->getStartLoc();
4263 return Error(Loc,
"the temporary vector register cannot be the same as "
4264 "the destination register");
4268 if (Opcode == RISCV::PseudoVMSGEU_VX_M || Opcode == RISCV::PseudoVMSGE_VX_M) {
4271 if (MaskReg == RISCV::V0 && DestReg == RISCV::V0) {
4272 SMLoc Loc =
Operands.back()->getStartLoc();
4273 return Error(Loc,
"the destination vector register cannot overlap the "
4274 "mask register unless a temporary register is "
4279 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
4280 Opcode == RISCV::TH_LWD) {
4285 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
4286 SMLoc Loc =
Operands[1]->getStartLoc();
4287 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
4291 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
4295 SMLoc Loc =
Operands[1]->getStartLoc();
4296 return Error(Loc,
"rs1 and rs2 must be different");
4301 auto CheckOperandDoesNotOverlapV0 = [&](
int OperandIdx,
4302 unsigned ParsedIdx) {
4305 "vd, vs1, and vs2 cannot overlap v0.scale");
4310 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4312 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4314 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4315 assert(DestIdx >= 0 && VS1Idx >= 0 && VS2Idx >= 0 &&
4316 "Unexpected Zvvfmm scaled operand list");
4318 if (CheckOperandDoesNotOverlapV0(DestIdx, 1) ||
4319 CheckOperandDoesNotOverlapV0(VS1Idx, 2) ||
4320 CheckOperandDoesNotOverlapV0(VS2Idx, 3))
4324 const MCInstrDesc &MCID = MII.
get(Opcode);
4328 int DestIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4332 const MCParsedAsmOperand *ParsedOp =
Operands[1].get();
4333 if (!ParsedOp->
isReg()) {
4338 assert(ParsedOp->
getReg() == DestReg &&
"Can't find parsed dest operand");
4342 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4346 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4347 assert(VS2Idx >= 0 &&
"No vs2 operand?");
4348 unsigned CheckEncoding =
4351 for (
unsigned i = 0; i < std::max(NF, Lmul); i++) {
4352 if ((DestEncoding + i) == CheckEncoding)
4353 return Error(Loc,
"the destination vector register group cannot overlap"
4354 " the source vector register group");
4359 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4363 unsigned CheckEncoding =
4365 for (
unsigned i = 0; i < Lmul; i++) {
4366 if ((DestEncoding + i) == CheckEncoding)
4368 "the destination vector register group cannot overlap"
4369 " the source vector register group");
4375 int VMIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vm);
4376 assert(VMIdx >= 0 &&
"No vm operand?");
4378 if (DestReg == RISCV::V0) {
4381 return Error(Loc,
"the destination vector register group cannot be V0");
4389 "Unexpected mask operand register");
4391 return Error(Loc,
"the destination vector register group cannot overlap"
4392 " the mask register");
4400 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vmask);
4402 if (MaskReg != RISCV::V0 && MaskReg != RISCV::V1)
4404 "vmask operand only supports v0 or v1");
4407 RISCV::OpName RegOps[] = {RISCV::OpName::vd, RISCV::OpName::vs1,
4408 RISCV::OpName::vs2};
4409 for (RISCV::OpName OpN : RegOps) {
4410 int Idx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), OpN);
4416 for (
unsigned i = 0; i < RegLmul; i++) {
4417 if ((RegEnc + i) == MaskEnc) {
4418 SMLoc Loc =
Operands[Idx]->getStartLoc();
4419 return Error(Loc, Twine(
"register conflicts with vmask register ") +
4429bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
4437 case RISCV::PseudoC_ADDI_NOP: {
4439 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
4449 if (getSTI().
hasFeature(RISCV::Feature64Bit))
4451 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV32)
4456 case RISCV::PACKW: {
4460 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV64)
4465 case RISCV::PseudoLLAImm:
4466 case RISCV::PseudoLAImm:
4467 case RISCV::PseudoLI: {
4473 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
4485 emitLoadImm(
Reg,
Imm, Out);
4488 case RISCV::PseudoLLA:
4489 emitLoadLocalAddress(Inst, IDLoc, Out);
4491 case RISCV::PseudoLGA:
4492 emitLoadGlobalAddress(Inst, IDLoc, Out);
4494 case RISCV::PseudoLA:
4495 emitLoadAddress(Inst, IDLoc, Out);
4497 case RISCV::PseudoLA_TLS_IE:
4498 emitLoadTLSIEAddress(Inst, IDLoc, Out);
4500 case RISCV::PseudoLA_TLS_GD:
4501 emitLoadTLSGDAddress(Inst, IDLoc, Out);
4503 case RISCV::PseudoLB:
4504 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
4506 case RISCV::PseudoLBU:
4507 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
4509 case RISCV::PseudoLH:
4510 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
4512 case RISCV::PseudoLHU:
4513 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
4515 case RISCV::PseudoLW:
4516 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
4518 case RISCV::PseudoLWU:
4519 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
4521 case RISCV::PseudoLD:
4522 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
4524 case RISCV::PseudoLD_RV32:
4525 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
4527 case RISCV::PseudoFLH:
4528 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
4530 case RISCV::PseudoFLW:
4531 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
4533 case RISCV::PseudoFLD:
4534 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
4536 case RISCV::PseudoFLQ:
4537 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
4539 case RISCV::PseudoSB:
4540 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
4542 case RISCV::PseudoSH:
4543 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
4545 case RISCV::PseudoSW:
4546 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
4548 case RISCV::PseudoSD:
4549 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
4551 case RISCV::PseudoSD_RV32:
4552 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
4554 case RISCV::PseudoQC_E_LB:
4555 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLB, IDLoc, Out,
4558 case RISCV::PseudoQC_E_LBU:
4559 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLBU, IDLoc, Out,
4562 case RISCV::PseudoQC_E_LH:
4563 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLH, IDLoc, Out,
4566 case RISCV::PseudoQC_E_LHU:
4567 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLHU, IDLoc, Out,
4570 case RISCV::PseudoQC_E_LW:
4571 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLW, IDLoc, Out,
4574 case RISCV::PseudoQC_E_SB:
4575 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSB, IDLoc, Out,
4578 case RISCV::PseudoQC_E_SH:
4579 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSH, IDLoc, Out,
4582 case RISCV::PseudoQC_E_SW:
4583 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSW, IDLoc, Out,
4586 case RISCV::PseudoFSH:
4587 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
4589 case RISCV::PseudoFSW:
4590 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
4592 case RISCV::PseudoFSD:
4593 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4595 case RISCV::PseudoFSQ:
4596 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4598 case RISCV::PseudoAddTPRel:
4599 if (checkPseudoAddTPRel(Inst,
Operands))
4602 case RISCV::PseudoTLSDESCCall:
4603 if (checkPseudoTLSDESCCall(Inst,
Operands))
4606 case RISCV::PseudoSEXT_B:
4607 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4609 case RISCV::PseudoSEXT_H:
4610 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4612 case RISCV::PseudoZEXT_H:
4613 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4615 case RISCV::PseudoZEXT_W:
4616 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4618 case RISCV::PseudoVMSGEU_VX_M:
4619 case RISCV::PseudoVMSGEU_VX_M_T:
4620 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4622 case RISCV::PseudoVMSGE_VX_M:
4623 case RISCV::PseudoVMSGE_VX_M_T:
4624 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4626 case RISCV::PseudoVMSGE_VI:
4627 case RISCV::PseudoVMSLT_VI: {
4631 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4633 emitToStreamer(Out, MCInstBuilder(
Opc)
4641 case RISCV::PseudoVMSGEU_VI:
4642 case RISCV::PseudoVMSLTU_VI: {
4649 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4652 emitToStreamer(Out, MCInstBuilder(
Opc)
4660 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4663 emitToStreamer(Out, MCInstBuilder(
Opc)
4673 case RISCV::PseudoCV_ELW:
4674 emitLoadStoreSymbol(Inst, RISCV::CV_ELW, IDLoc, Out,
false);
4678 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
const FeatureInfo AllFeatures[]
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
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))
static MCRegister convertGPRToYGPR(MCRegister Reg)
bool isValidInsnFormat(StringRef Format, const MCSubtargetInfo &STI)
static bool isZvvfmmScaleOpcode(unsigned Opcode)
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 isUImm2(const MachineOperand &MO)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
This file defines the SmallSet 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.
Error takeError()
Take ownership of the stored error.
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 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.
StringRef getName(unsigned Opcode) const
Returns the name for the instructions with the given 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.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) 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
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
reference emplace_back(ArgTypes &&... Args)
Represent a constant reference to a string, i.e.
std::string str() const
Get the contents as an std::string.
char back() const
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)
Expected< ABI > computeTargetABI(const MCSubtargetInfo &STI, StringRef ABIName)
LLVM_ABI const TagNameMap & getRISCVAttributeTags()
static RoundingMode stringToRoundingMode(StringRef Str)
llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseFeatureBits(const MCSubtargetInfo &STI)
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)
bool isValidYBNDSWImm(int64_t Imm)
@ CE
Windows NT (Windows on ARM)
static SMTVTypeMode stringToSMTVTypeMode(StringRef Str)
static bool isValidSMTVTypeMode(unsigned Mode)
@ Valid
The data is already valid.
initializer< Ty > init(const Ty &Val)
std::function< llvm::json::Value()> Lambda
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.
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()
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
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...
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()
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
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.
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,...