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 {
349 if (getTargetStreamer().hasTargetABI())
352 Expected<RISCVABI::ABI> ABIOrErr =
356 getTargetStreamer().setTargetABI(
360 getTargetStreamer().setTargetABI(*ABIOrErr);
431 MCRegister OffsetReg;
434 SMLoc StartLoc, EndLoc;
450 RISCVOperand(KindTy K) : Kind(
K) {}
453 RISCVOperand(
const RISCVOperand &o) : MCParsedAsmOperand() {
455 StartLoc =
o.StartLoc;
458 case KindTy::Register:
461 case KindTy::Expression:
464 case KindTy::FPImmediate:
470 case KindTy::SystemRegister:
476 case KindTy::SMTVType:
477 SMTVType =
o.SMTVType;
485 case KindTy::RegList:
488 case KindTy::StackAdj:
489 StackAdj =
o.StackAdj;
497 bool isToken()
const override {
return Kind == KindTy::Token; }
498 bool isReg()
const override {
return Kind == KindTy::Register; }
499 bool isExpr()
const {
return Kind == KindTy::Expression; }
500 bool isV0Reg()
const {
501 return Kind == KindTy::Register &&
Reg.Reg == RISCV::V0;
503 bool isAnyReg()
const {
504 return Kind == KindTy::Register &&
505 (getRISCVMCRegisterClass(RISCV::GPRRegClassID).contains(
Reg.Reg) ||
506 getRISCVMCRegisterClass(RISCV::FPR64RegClassID).contains(
Reg.Reg) ||
507 getRISCVMCRegisterClass(RISCV::VRRegClassID).contains(
Reg.Reg));
509 bool isAnyRegC()
const {
510 return Kind == KindTy::Register &&
511 (getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(
Reg.Reg) ||
512 getRISCVMCRegisterClass(RISCV::FPR64CRegClassID).contains(
Reg.Reg));
514 bool isImm()
const override {
return isExpr(); }
515 bool isMem()
const override {
return false; }
516 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
517 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
518 bool isRegList()
const {
return Kind == KindTy::RegList; }
519 bool isRegListS0()
const {
520 return Kind == KindTy::RegList && RegList.Encoding !=
RISCVZC::RA;
522 bool isStackAdj()
const {
return Kind == KindTy::StackAdj; }
525 return Kind == KindTy::Register &&
526 getRISCVMCRegisterClass(RISCV::GPRRegClassID).contains(
Reg.Reg);
529 bool isYGPR()
const {
530 return Kind == KindTy::Register &&
531 getRISCVMCRegisterClass(RISCV::YGPRRegClassID).contains(
Reg.Reg);
534 bool isGPRPair()
const {
535 return Kind == KindTy::Register &&
536 getRISCVMCRegisterClass(RISCV::GPRPairRegClassID).contains(
Reg.Reg);
539 bool isGPRPairC()
const {
540 return Kind == KindTy::Register &&
541 getRISCVMCRegisterClass(RISCV::GPRPairCRegClassID).contains(
Reg.Reg);
544 bool isGPRPairNoX0()
const {
545 return Kind == KindTy::Register &&
546 getRISCVMCRegisterClass(RISCV::GPRPairNoX0RegClassID)
550 bool isGPRF16()
const {
551 return Kind == KindTy::Register &&
552 getRISCVMCRegisterClass(RISCV::GPRF16RegClassID).contains(
Reg.Reg);
555 bool isGPRF32()
const {
556 return Kind == KindTy::Register &&
557 getRISCVMCRegisterClass(RISCV::GPRF32RegClassID).contains(
Reg.Reg);
560 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
561 bool isGPRAsFPR16()
const {
return isGPRF16() &&
Reg.IsGPRAsFPR; }
562 bool isGPRAsFPR32()
const {
return isGPRF32() &&
Reg.IsGPRAsFPR; }
563 bool isGPRPairAsFPR64()
const {
return isGPRPair() &&
Reg.IsGPRAsFPR; }
565 static bool evaluateConstantExpr(
const MCExpr *Expr, int64_t &
Imm) {
567 Imm =
CE->getValue();
576 template <
int N>
bool isBareSimmNLsb0()
const {
585 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
591 template <
int N>
bool isBareSimmN()
const {
597 return isInt<N>(fixImmediateForRV32(
Imm, isRV64Expr()));
600 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
606 bool isBareSymbol()
const {
609 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
613 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
617 bool isCallSymbol()
const {
620 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
624 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
628 bool isTailCallSymbol()
const {
return isCallSymbol(); }
630 bool isPseudoJumpSymbol()
const {
633 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
637 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
641 bool isTPRelAddSymbol()
const {
644 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
648 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
649 VK == ELF::R_RISCV_TPREL_ADD;
652 bool isTLSDESCCallSymbol()
const {
655 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
659 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
660 VK == ELF::R_RISCV_TLSDESC_CALL;
663 bool isQCAccessSymbol()
const {
666 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
670 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
674 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
678 bool isVTypeI10()
const {
679 if (Kind == KindTy::VType)
683 bool isVTypeI11()
const {
684 if (Kind == KindTy::VType)
689 bool isXSfmmVType()
const {
693 bool isTileLambda()
const {
699 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
702 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
703 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
708 bool isSMTVType()
const {
709 return Kind == KindTy::SMTVType &&
713 bool isSMTI8()
const {
718 bool isLoadFPImm()
const {
721 if (Kind != KindTy::FPImmediate)
724 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
727 return Idx >= 0 && Idx != 1;
730 bool isImmXLenLI()
const {
739 return RISCVAsmParser::isSymbolDiff(
getExpr());
742 bool isImmXLenLI_Restricted()
const {
746 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
748 return IsConstantImm &&
752 template <
unsigned N>
bool isUImm()
const {
756 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
760 template <
unsigned N,
unsigned S>
bool isUImmShifted()
const {
764 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
768 template <
class Pred>
bool isUImmPred(Pred p)
const {
772 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
773 return IsConstantImm &&
p(
Imm);
776 bool isUImmLog2XLen()
const {
777 if (isExpr() && isRV64Expr())
782 bool isUImmLog2XLenNonZero()
const {
783 if (isExpr() && isRV64Expr())
788 bool isUImmLog2XLenHalf()
const {
789 if (isExpr() && isRV64Expr())
794 bool isUImm5NonZero()
const {
798 bool isUImm5GT3()
const {
802 bool isUImm4Plus1()
const {
807 bool isUImm5Plus1()
const {
812 bool isUImm6Plus1()
const {
817 bool isUImm5GE6Plus1()
const {
822 bool isUImm5Slist()
const {
823 return isUImmPred([](int64_t
Imm) {
824 return (
Imm == 0) || (
Imm == 1) || (
Imm == 2) || (
Imm == 4) ||
825 (
Imm == 8) || (
Imm == 16) || (
Imm == 15) || (
Imm == 31);
829 bool isUImm7EqXLen()
const {
831 [
this](int64_t
Imm) {
return isRV64Expr() ?
Imm == 64 :
Imm == 32; });
834 bool isUImm8GE32()
const {
838 bool isRnumArg()
const {
840 [](int64_t
Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(10); });
843 bool isRnumArg_0_7()
const {
845 [](int64_t
Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(7); });
848 bool isRnumArg_1_10()
const {
850 [](int64_t
Imm) {
return Imm >= INT64_C(1) &&
Imm <= INT64_C(10); });
853 bool isRnumArg_2_14()
const {
855 [](int64_t
Imm) {
return Imm >= INT64_C(2) &&
Imm <= INT64_C(14); });
858 template <
unsigned N>
bool isSImm()
const {
862 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
863 return IsConstantImm &&
isInt<N>(fixImmediateForRV32(
Imm, isRV64Expr()));
866 bool isYBNDSWImm()
const {
871 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
875 template <
class Pred>
bool isSImmPred(Pred p)
const {
879 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
880 return IsConstantImm &&
p(fixImmediateForRV32(
Imm, isRV64Expr()));
883 bool isSImm5NonZero()
const {
887 bool isSImm6NonZero()
const {
891 bool isCLUIImm()
const {
892 return isUImmPred([](int64_t
Imm) {
897 bool isUImm10Lsb00NonZero()
const {
904 static int64_t fixImmediateForRV32(int64_t
Imm,
bool IsRV64Imm) {
910 bool isSImm12LO()
const {
916 return isInt<12>(fixImmediateForRV32(
Imm, isRV64Expr()));
919 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
922 VK == ELF::R_RISCV_TLSDESC_ADD_LO12);
930 template <
bool (RISCVOperand::*Pred)() const>
931 DiagnosticPredicate isOptionalMemOffset()
const {
935 : DiagnosticPredicate::NearMatch;
938 bool isSImm12Lsb00000()
const {
942 bool isSImm10Lsb0000NonZero()
const {
947 bool isSImm16NonZero()
const {
951 bool isUImm16NonZero()
const {
955 bool isSImm20LI()
const {
961 return isInt<20>(fixImmediateForRV32(
Imm, isRV64Expr()));
964 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
968 bool isSImm8PLI_B()
const {
return isSImm<8>() || isUImm<8>(); }
969 bool isSImm10PLUI()
const {
return isSImm<10>() || isUImm<10>(); }
971 bool isSImm10PLI_H()
const {
972 return isSImm<10>() || isUImmPred([](int64_t
Imm) {
976 bool isSImm10PLI_W()
const {
977 return isSImm<10>() || isUImmPred([](int64_t
Imm) {
982 bool isUImm20LUI()
const {
991 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
992 (VK == ELF::R_RISCV_HI20 || VK == ELF::R_RISCV_TPREL_HI20);
995 bool isUImm20AUIPC()
const {
1004 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
1006 VK == ELF::R_RISCV_TLS_GOT_HI20 || VK == ELF::R_RISCV_TLS_GD_HI20 ||
1007 VK == ELF::R_RISCV_TLSDESC_HI20);
1010 bool isImmZero()
const {
1011 return isUImmPred([](int64_t
Imm) {
return 0 ==
Imm; });
1014 bool isImmThree()
const {
1015 return isUImmPred([](int64_t
Imm) {
return 3 ==
Imm; });
1018 bool isImmFour()
const {
1019 return isUImmPred([](int64_t
Imm) {
return 4 ==
Imm; });
1022 bool isImm5Zibi()
const {
1027 bool isSImm5Plus1()
const {
1032 bool isSImm18Lsb0()
const {
1036 bool isSImm19Lsb00()
const {
1040 bool isSImm20Lsb000()
const {
1044 bool isSImm32Lsb0()
const {
1049 SMLoc getStartLoc()
const override {
return StartLoc; }
1051 SMLoc getEndLoc()
const override {
return EndLoc; }
1054 bool isRV64Expr()
const {
1055 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1059 MCRegister
getReg()
const override {
1060 assert(Kind == KindTy::Register &&
"Invalid type access!");
1064 StringRef getSysReg()
const {
1065 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
1066 return StringRef(SysReg.Data, SysReg.Length);
1069 const MCExpr *
getExpr()
const {
1070 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1075 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1080 assert(Kind == KindTy::Token &&
"Invalid type access!");
1084 unsigned getVType()
const {
1085 assert(Kind == KindTy::VType &&
"Invalid type access!");
1090 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1094 unsigned getFence()
const {
1095 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1100 assert(Kind == KindTy::SMTVType &&
"Invalid type access!");
1101 return SMTVType.SMTVType;
1104 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1113 case KindTy::Expression:
1116 OS <<
' ' << (Expr.IsRV64 ?
"rv64" :
"rv32") <<
'>';
1118 case KindTy::FPImmediate:
1119 OS <<
"<fpimm: " << FPImm.Val <<
">";
1121 case KindTy::Register:
1123 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1128 case KindTy::SystemRegister:
1129 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1138 OS << roundingModeToString(getFRM());
1141 case KindTy::SMTVType:
1142 OS <<
"<smtvtype: ";
1143 OS << SMTVTypeModeToString(getSMTVType());
1151 case KindTy::RegList:
1156 case KindTy::StackAdj:
1157 OS <<
"<stackadj: ";
1161 case KindTy::RegReg:
1162 OS <<
"<RegReg: BaseReg " <<
RegName(
RegReg.BaseReg) <<
" OffsetReg "
1168 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1169 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1176 static std::unique_ptr<RISCVOperand>
1177 createReg(MCRegister
Reg, SMLoc S, SMLoc
E,
bool IsGPRAsFPR =
false) {
1178 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1180 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1186 static std::unique_ptr<RISCVOperand> createExpr(
const MCExpr *Val, SMLoc S,
1187 SMLoc
E,
bool IsRV64) {
1188 auto Op = std::make_unique<RISCVOperand>(KindTy::Expression);
1189 Op->Expr.Expr = Val;
1190 Op->Expr.IsRV64 = IsRV64;
1196 static std::unique_ptr<RISCVOperand> createFPImm(
uint64_t Val, SMLoc S) {
1197 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1198 Op->FPImm.Val = Val;
1204 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1205 unsigned Encoding) {
1206 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1207 Op->SysReg.Data = Str.data();
1208 Op->SysReg.Length = Str.size();
1215 static std::unique_ptr<RISCVOperand>
1217 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1224 static std::unique_ptr<RISCVOperand>
1226 auto Op = std::make_unique<RISCVOperand>(KindTy::SMTVType);
1227 Op->SMTVType.SMTVType = VType;
1233 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val, SMLoc S) {
1234 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1235 Op->Fence.Val = Val;
1241 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI, SMLoc S) {
1242 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1243 Op->VType.Val = VTypeI;
1249 static std::unique_ptr<RISCVOperand> createRegList(
unsigned RlistEncode,
1251 auto Op = std::make_unique<RISCVOperand>(KindTy::RegList);
1257 static std::unique_ptr<RISCVOperand>
1258 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {
1259 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1261 Op->RegReg.OffsetReg = OffsetReg;
1267 static std::unique_ptr<RISCVOperand> createStackAdj(
unsigned StackAdj, SMLoc S) {
1268 auto Op = std::make_unique<RISCVOperand>(KindTy::StackAdj);
1269 Op->StackAdj.Val = StackAdj;
1274 static void addExpr(MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1275 assert(Expr &&
"Expr shouldn't be null!");
1287 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1288 assert(
N == 1 &&
"Invalid number of operands!");
1292 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1293 assert(
N == 1 &&
"Invalid number of operands!");
1294 addExpr(Inst,
getExpr(), isRV64Expr());
1297 template <
unsigned Bits>
1298 void addSExtImmOperands(MCInst &Inst,
unsigned N)
const {
1299 assert(
N == 1 &&
"Invalid number of operands!");
1306 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
1307 assert(
N == 1 &&
"Invalid number of operands!");
1309 addExpr(Inst,
getExpr(), isRV64Expr());
1314 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1318 void addFenceArgOperands(MCInst &Inst,
unsigned N)
const {
1319 assert(
N == 1 &&
"Invalid number of operands!");
1323 void addCSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
1324 assert(
N == 1 &&
"Invalid number of operands!");
1331 void addVTypeIOperands(MCInst &Inst,
unsigned N)
const {
1332 assert(
N == 1 &&
"Invalid number of operands!");
1334 if (Kind == KindTy::Expression) {
1335 [[maybe_unused]]
bool IsConstantImm =
1337 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1344 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1345 assert(
N == 1 &&
"Invalid number of operands!");
1349 void addRegRegOperands(MCInst &Inst,
unsigned N)
const {
1350 assert(
N == 2 &&
"Invalid number of operands!");
1355 void addStackAdjOperands(MCInst &Inst,
unsigned N)
const {
1356 assert(
N == 1 &&
"Invalid number of operands!");
1360 void addFRMArgOperands(MCInst &Inst,
unsigned N)
const {
1361 assert(
N == 1 &&
"Invalid number of operands!");
1365 void addSMTVTypeOperand(MCInst &Inst,
unsigned N)
const {
1366 assert(
N == 1 &&
"Invalid number of operands!");
1372#define GET_REGISTER_MATCHER
1373#define GET_SUBTARGET_FEATURE_NAME
1374#define GET_MATCHER_IMPLEMENTATION
1375#define GET_MNEMONIC_SPELL_CHECKER
1376#include "RISCVGenAsmMatcher.inc"
1379 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1380 return Reg - RISCV::F0_D + RISCV::F0_H;
1384 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1385 return Reg - RISCV::F0_D + RISCV::F0_F;
1389 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1390 return Reg - RISCV::F0_D + RISCV::F0_Q;
1394 assert(
Reg >= RISCV::X0 &&
Reg <= RISCV::X31 &&
"Invalid register");
1395 return Reg - RISCV::X0 + RISCV::X0_Y;
1400 unsigned RegClassID;
1401 if (Kind == MCK_VRM2)
1402 RegClassID = RISCV::VRM2RegClassID;
1403 else if (Kind == MCK_VRM4)
1404 RegClassID = RISCV::VRM4RegClassID;
1405 else if (Kind == MCK_VRM8)
1406 RegClassID = RISCV::VRM8RegClassID;
1410 &getRISCVMCRegisterClass(RegClassID));
1414 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1415 return Reg - RISCV::F0_D + RISCV::F0_Q2;
1420 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1422 return Match_InvalidOperand;
1424 MCRegister
Reg =
Op.getReg();
1426 getRISCVMCRegisterClass(RISCV::FPR64RegClassID).contains(
Reg);
1428 getRISCVMCRegisterClass(RISCV::FPR64CRegClassID).contains(
Reg);
1429 bool IsRegVR = getRISCVMCRegisterClass(RISCV::VRRegClassID).contains(
Reg);
1431 if (
Op.isGPR() && Kind == MCK_YGPR) {
1434 return Match_Success;
1436 if (IsRegFPR64 && Kind == MCK_FPR256) {
1438 return Match_Success;
1440 if (IsRegFPR64 && Kind == MCK_FPR128) {
1442 return Match_Success;
1446 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1447 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1449 return Match_Success;
1453 if (IsRegFPR64 && Kind == MCK_FPR16) {
1455 return Match_Success;
1457 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1458 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_H;
1459 return Match_Success;
1461 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1462 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_W;
1463 return Match_Success;
1470 if (getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg) &&
1471 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1473 return Match_Success;
1477 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1480 return Match_InvalidOperand;
1481 return Match_Success;
1483 return Match_InvalidOperand;
1486bool RISCVAsmParser::generateImmOutOfRangeError(
1487 SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
1488 const Twine &
Msg =
"immediate must be an integer in the range") {
1495std::string RISCVAsmParser::getCustomOperandDiag(
unsigned MatchError) {
1497 StringRef
Msg =
"immediate must be an integer in the range") {
1498 return (
Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]").str();
1501 switch (MatchError) {
1505 if (
const char *Diag = getMatchKindDiag((RISCVMatchResultTy)MatchError))
1507 return std::string();
1508 case Match_InvalidImmXLenLI:
1510 return "operand must be a constant 64-bit integer";
1511 return Range(std::numeric_limits<int32_t>::min(),
1512 std::numeric_limits<uint32_t>::max());
1513 case Match_InvalidImmXLenLI_Restricted:
1515 return "operand either must be a constant 64-bit integer "
1516 "or a bare symbol name";
1517 return Range(std::numeric_limits<int32_t>::min(),
1518 std::numeric_limits<uint32_t>::max(),
1519 "operand either must be a bare symbol name or an immediate "
1520 "integer in the range");
1521 case Match_InvalidUImmLog2XLen:
1523 return Range(0, (1 << 6) - 1);
1524 return Range(0, (1 << 5) - 1);
1525 case Match_InvalidUImmLog2XLenNonZero:
1527 return Range(1, (1 << 6) - 1);
1528 return Range(1, (1 << 5) - 1);
1529 case Match_InvalidUImm1:
1530 return Range(0, (1 << 1) - 1);
1531 case Match_InvalidUImm2:
1532 return Range(0, (1 << 2) - 1);
1533 case Match_InvalidUImm2Lsb0:
1534 return Range(0, 2,
"immediate must be one of");
1535 case Match_InvalidUImm3:
1536 return Range(0, (1 << 3) - 1);
1537 case Match_InvalidUImm4:
1538 return Range(0, (1 << 4) - 1);
1539 case Match_InvalidUImm4Plus1:
1540 return Range(1, (1 << 4));
1541 case Match_InvalidUImm5:
1542 return Range(0, (1 << 5) - 1);
1543 case Match_InvalidUImm5NonZero:
1544 return Range(1, (1 << 5) - 1);
1545 case Match_InvalidUImm5GT3:
1546 return Range(4, (1 << 5) - 1);
1547 case Match_InvalidUImm5Plus1:
1548 return Range(1, (1 << 5));
1549 case Match_InvalidUImm5GE6Plus1:
1550 return Range(6, (1 << 5));
1551 case Match_InvalidUImm5Slist:
1552 return "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31";
1553 case Match_InvalidUImm6:
1554 return Range(0, (1 << 6) - 1);
1555 case Match_InvalidUImm6Plus1:
1556 return Range(1, (1 << 6));
1557 case Match_InvalidUImm7:
1558 return Range(0, (1 << 7) - 1);
1559 case Match_InvalidUImm8:
1560 return Range(0, (1 << 8) - 1);
1561 case Match_InvalidUImm8GE32:
1562 return Range(32, (1 << 8) - 1);
1563 case Match_InvalidSImm5:
1564 return Range(-(1 << 4), (1 << 4) - 1);
1565 case Match_InvalidSImm5NonZero:
1566 return Range(-(1 << 4), (1 << 4) - 1,
1567 "immediate must be non-zero in the range");
1568 case Match_InvalidSImm6:
1569 return Range(-(1 << 5), (1 << 5) - 1);
1570 case Match_InvalidSImm6NonZero:
1571 return Range(-(1 << 5), (1 << 5) - 1,
1572 "immediate must be non-zero in the range");
1573 case Match_InvalidCLUIImm:
1574 return Range(1, (1 << 5) - 1,
"immediate must be in [0xfffe0, 0xfffff] or");
1575 case Match_InvalidUImm5Lsb0:
1576 return Range(0, (1 << 5) - 2,
1577 "immediate must be a multiple of 2 bytes in the range");
1578 case Match_InvalidUImm6Lsb0:
1579 return Range(0, (1 << 6) - 2,
1580 "immediate must be a multiple of 2 bytes in the range");
1581 case Match_InvalidUImm6Lsb000:
1582 return Range(0, (1 << 6) - 8,
1583 "immediate must be a multiple of 8 in the range");
1584 case Match_InvalidUImm7Lsb00:
1585 return Range(0, (1 << 7) - 4,
1586 "immediate must be a multiple of 4 bytes in the range");
1587 case Match_InvalidUImm8Lsb00:
1588 return Range(0, (1 << 8) - 4,
1589 "immediate must be a multiple of 4 bytes in the range");
1590 case Match_InvalidUImm8Lsb000:
1591 return Range(0, (1 << 8) - 8,
1592 "immediate must be a multiple of 8 bytes in the range");
1593 case Match_InvalidUImm9:
1594 return Range(0, (1 << 9) - 1,
"immediate offset must be in the range");
1595 case Match_InvalidBareSImm9Lsb0:
1596 return Range(-(1 << 8), (1 << 8) - 2,
1597 "immediate must be a multiple of 2 bytes in the range");
1598 case Match_InvalidUImm9Lsb000:
1599 return Range(0, (1 << 9) - 8,
1600 "immediate must be a multiple of 8 bytes in the range");
1601 case Match_InvalidSImm8PLI_B:
1602 return Range(-(1 << 7), (1 << 8) - 1);
1603 case Match_InvalidSImm10:
1604 case Match_InvalidSImm10PLI_H:
1605 case Match_InvalidSImm10PLI_W:
1606 return Range(-(1 << 9), (1 << 9) - 1);
1607 case Match_InvalidSImm10PLUI:
1608 return Range(-(1 << 9), (1 << 10) - 1);
1609 case Match_InvalidUImm10Lsb00NonZero:
1610 return Range(4, (1 << 10) - 4,
1611 "immediate must be a multiple of 4 bytes in the range");
1612 case Match_InvalidSImm10Lsb0000NonZero:
1614 -(1 << 9), (1 << 9) - 16,
1615 "immediate must be a multiple of 16 bytes and non-zero in the range");
1616 case Match_InvalidSImm11:
1617 return Range(-(1 << 10), (1 << 10) - 1);
1618 case Match_InvalidBareSImm11Lsb0:
1619 return Range(-(1 << 10), (1 << 10) - 2,
1620 "immediate must be a multiple of 2 bytes in the range");
1621 case Match_InvalidUImm10:
1622 return Range(0, (1 << 10) - 1);
1623 case Match_InvalidUImm11:
1624 return Range(0, (1 << 11) - 1);
1625 case Match_InvalidUImm14Lsb00:
1626 return Range(0, (1 << 14) - 4,
1627 "immediate must be a multiple of 4 bytes in the range");
1628 case Match_InvalidUImm16NonZero:
1629 return Range(1, (1 << 16) - 1);
1630 case Match_InvalidSImm12:
1631 return Range(-(1 << 11), (1 << 11) - 1);
1632 case Match_InvalidSImm12LO:
1633 return Range(-(1 << 11), (1 << 11) - 1,
1634 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo "
1635 "specifier or an integer in the range");
1636 case Match_InvalidBareSImm12Lsb0:
1637 return Range(-(1 << 11), (1 << 11) - 2,
1638 "immediate must be a multiple of 2 bytes in the range");
1639 case Match_InvalidSImm12Lsb00000:
1640 return Range(-(1 << 11), (1 << 11) - 32,
1641 "immediate must be a multiple of 32 bytes in the range");
1642 case Match_InvalidBareSImm13Lsb0:
1643 return Range(-(1 << 12), (1 << 12) - 2,
1644 "immediate must be a multiple of 2 bytes in the range");
1645 case Match_InvalidSImm16:
1646 return Range(-(1 << 15), (1 << 15) - 1);
1647 case Match_InvalidSImm16NonZero:
1648 return Range(-(1 << 15), (1 << 15) - 1,
1649 "immediate must be non-zero in the range");
1650 case Match_InvalidSImm20LI:
1651 return Range(-(1 << 19), (1 << 19) - 1,
1652 "operand must be a symbol with a %qc.abs20 specifier or an "
1653 "integer in the range");
1654 case Match_InvalidUImm20LUI:
1655 return Range(0, (1 << 20) - 1,
1656 "operand must be a symbol with %hi/%tprel_hi specifier or an "
1657 "integer in the range");
1658 case Match_InvalidUImm20:
1659 return Range(0, (1 << 20) - 1);
1660 case Match_InvalidUImm20AUIPC:
1663 "operand must be a symbol with a "
1664 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
1665 "or an integer in the range");
1666 case Match_InvalidBareSImm21Lsb0:
1667 return Range(-(1 << 20), (1 << 20) - 2,
1668 "immediate must be a multiple of 2 bytes in the range");
1669 case Match_InvalidCSRSystemRegister:
1670 return Range(0, (1 << 12) - 1,
1671 "operand must be a valid system register name or an integer "
1673 case Match_InvalidImm5Zibi:
1674 return Range(-1, (1 << 5) - 1,
"immediate must be non-zero in the range");
1675 case Match_InvalidVTypeI:
1676 return "operand must be "
1677 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]";
1678 case Match_InvalidSImm5Plus1:
1679 return Range(-(1 << 4) + 1, (1 << 4),
"immediate must be in the range");
1680 case Match_InvalidSImm18:
1681 return Range(-(1 << 17), (1 << 17) - 1);
1682 case Match_InvalidSImm18Lsb0:
1683 return Range(-(1 << 17), (1 << 17) - 2,
1684 "immediate must be a multiple of 2 bytes in the range");
1685 case Match_InvalidSImm19Lsb00:
1686 return Range(-(1 << 18), (1 << 18) - 4,
1687 "immediate must be a multiple of 4 bytes in the range");
1688 case Match_InvalidSImm20Lsb000:
1689 return Range(-(1 << 19), (1 << 19) - 8,
1690 "immediate must be a multiple of 8 bytes in the range");
1691 case Match_InvalidSImm26:
1692 return Range(-(1 << 25), (1 << 25) - 1);
1694 case Match_InvalidBareSymbolQC_E_LI:
1697 case Match_InvalidBareSImm32:
1698 return Range(std::numeric_limits<int32_t>::min(),
1699 std::numeric_limits<uint32_t>::max());
1700 case Match_InvalidBareSImm32Lsb0:
1701 return Range(std::numeric_limits<int32_t>::min(),
1702 std::numeric_limits<int32_t>::max() - 1,
1703 "operand must be a multiple of 2 bytes in the range");
1704 case Match_InvalidRnumArg:
1705 return Range(0, 10);
1706 case Match_InvalidStackAdj:
1707 return "stack adjustment is invalid for this instruction and register "
1709 case Match_InvalidYBNDSWImm:
1710 return "immediate must be an integer in the range "
1711 "[1, 255], a multiple of 8 in the range [256, 504], "
1712 "or a multiple of 16 in the range [512, 4096]";
1713 case Match_InvalidUImm7EqXLen:
1714 return (
"immediate must be an integer equal to XLEN (" +
1715 Twine(isRV64() ?
"64" :
"32") +
")")
1723void RISCVAsmParser::FilterNearMisses(
1724 SmallVectorImpl<NearMissInfo> &NearMissesIn,
1725 SmallVectorImpl<NearMissMessage> &NearMissesOut, SMLoc IDLoc,
1729 std::multimap<unsigned, unsigned> OperandMissesSeen;
1730 SmallSet<FeatureBitset, 4> FeatureMissesSeen;
1731 bool ReportedTooFewOperands =
false;
1732 bool ReportedTooManyOperands =
false;
1734 for (NearMissInfo &
I : NearMissesIn) {
1735 switch (
I.getKind()) {
1738 ((RISCVOperand &)*
Operands[
I.getOperandIndex()]).getStartLoc();
1743 if (
I.getOperandClass() == InvalidMatchClass) {
1744 if (!ReportedTooManyOperands) {
1746 OperandLoc,
"unexpected extra operand for instruction"});
1747 ReportedTooManyOperands =
true;
1752 std::string OperandDiag = getCustomOperandDiag(
I.getOperandError());
1756 unsigned DupCheckMatchClass =
1757 OperandDiag.empty() ? ~0
U :
I.getOperandClass();
1758 auto PrevReports = OperandMissesSeen.equal_range(
I.getOperandIndex());
1760 PrevReports.first, PrevReports.second,
1761 [DupCheckMatchClass](
const std::pair<unsigned, unsigned> Pair) {
1762 if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
1763 return Pair.second == DupCheckMatchClass;
1764 return isSubclass((MatchClassKind)DupCheckMatchClass,
1765 (MatchClassKind)Pair.second);
1768 OperandMissesSeen.insert(
1769 std::make_pair(
I.getOperandIndex(), DupCheckMatchClass));
1771 NearMissMessage Message;
1772 Message.Loc = OperandLoc;
1773 if (!OperandDiag.empty()) {
1774 Message.Message = OperandDiag;
1776 Message.Message =
"invalid operand for instruction";
1778 dbgs() <<
"Missing diagnostic string for operand class "
1779 << getMatchClassName((MatchClassKind)
I.getOperandClass())
1780 <<
I.getOperandClass() <<
", error " <<
I.getOperandError()
1781 <<
", opcode " << MII.
getName(
I.getOpcode()) <<
"\n");
1787 const FeatureBitset &MissingFeatures =
I.getFeatures();
1789 if (!FeatureMissesSeen.
insert(MissingFeatures).second)
1792 NearMissMessage Message;
1793 Message.Loc = IDLoc;
1794 bool FirstFeature =
true;
1795 Message.Message =
"instruction requires the following:";
1796 for (
unsigned Feature : MissingFeatures) {
1797 Message.Message += FirstFeature ?
" " :
", ";
1799 FirstFeature =
false;
1809 if (!ReportedTooFewOperands) {
1810 SMLoc EndLoc = ((RISCVOperand &)*
Operands.back()).getEndLoc();
1812 NearMissMessage{EndLoc,
"too few operands for instruction"});
1813 ReportedTooFewOperands =
true;
1825void RISCVAsmParser::ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses,
1828 FilterNearMisses(NearMisses, Messages, IDLoc,
Operands);
1833 Error(IDLoc,
"invalid instruction");
1836 Error(Messages[0].Loc, Messages[0].Message);
1841 "invalid instruction, any one of the following would fix this:");
1842 for (
auto &M : Messages)
1847bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1851 bool MatchingInlineAsm) {
1856 MatchInstructionImpl(
Operands, Inst, &NearMisses, MatchingInlineAsm);
1861 if (validateInstruction(Inst,
Operands))
1863 return processInstruction(Inst, IDLoc,
Operands, Out);
1864 case Match_MnemonicFail: {
1865 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1866 std::string Suggestion = RISCVMnemonicSpellCheck(
1868 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1870 case Match_NearMisses:
1871 ReportNearMisses(NearMisses, IDLoc,
Operands);
1882MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name)
const {
1891 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1892 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1893 static_assert(RISCV::F0_D < RISCV::F0_Q,
"FPR matching must be updated");
1896 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1901bool RISCVAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1903 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1904 return Error(StartLoc,
"invalid register name");
1908ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1910 const AsmToken &Tok = getParser().getTok();
1913 StringRef
Name = getLexer().getTok().getIdentifier();
1925 SMLoc FirstS = getLoc();
1926 bool HadParens =
false;
1933 size_t ReadCount = getLexer().peekTokens(Buf);
1936 LParen = getParser().getTok();
1941 switch (getLexer().getKind()) {
1944 getLexer().UnLex(LParen);
1947 StringRef
Name = getLexer().getTok().getIdentifier();
1952 getLexer().UnLex(LParen);
1956 Operands.push_back(RISCVOperand::createToken(
"(", FirstS));
1958 SMLoc
E = getTok().getEndLoc();
1960 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
1965 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
1976 switch (getLexer().getKind()) {
1986 if (getParser().parseExpression(Res,
E))
1991 int64_t
Imm =
CE->getValue();
1993 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2002 if (getParser().parseIdentifier(Identifier))
2005 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
2008 "Unexpected opcode");
2011 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2021 return generateImmOutOfRangeError(
2023 "opcode must be a valid opcode name or an immediate in the range");
2031 switch (getLexer().getKind()) {
2041 if (getParser().parseExpression(Res,
E))
2046 int64_t
Imm =
CE->getValue();
2047 if (
Imm >= 0 &&
Imm <= 2) {
2048 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2057 if (getParser().parseIdentifier(Identifier))
2061 if (Identifier ==
"C0")
2063 else if (Identifier ==
"C1")
2065 else if (Identifier ==
"C2")
2072 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2081 return generateImmOutOfRangeError(
2083 "opcode must be a valid opcode name or an immediate in the range");
2090 auto SysRegFromConstantInt = [
this](
const MCExpr *
E, SMLoc S) {
2092 int64_t
Imm =
CE->getValue();
2094 auto Range = RISCVSysReg::lookupSysRegByEncoding(
Imm);
2098 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2101 return RISCVOperand::createSysReg(
2102 RISCVSysReg::getSysRegStr(
Reg.Name), S,
Imm);
2106 return RISCVOperand::createSysReg(
"", S,
Imm);
2109 return std::unique_ptr<RISCVOperand>();
2112 switch (getLexer().getKind()) {
2122 if (getParser().parseExpression(Res))
2125 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
2126 Operands.push_back(std::move(SysOpnd));
2130 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2134 if (getParser().parseIdentifier(Identifier))
2137 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
2140 if (SysReg->IsDeprecatedName) {
2142 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
2144 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2146 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
2147 RISCVSysReg::getSysRegStr(
Reg.Name) +
"'");
2152 const auto &FeatureBits = getSTI().getFeatureBits();
2153 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
2154 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
2155 const auto *Feature =
2157 return SysReg->FeaturesRequired[Feature.Value];
2159 std::string ErrorMsg =
2160 std::string(
"system register '") +
2161 std::string(RISCVSysReg::getSysRegStr(SysReg->Name)) +
"' ";
2162 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
2163 ErrorMsg +=
"is RV32 only";
2165 ErrorMsg +=
" and ";
2169 "requires '" + std::string(Feature->key()) +
"' to be enabled";
2172 return Error(S, ErrorMsg);
2175 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
2185 Operands.push_back(std::move(SysOpnd));
2190 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2191 "operand must be a valid system register "
2192 "name or an integer in the range");
2196 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2208 StringRef
Identifier = getTok().getIdentifier();
2209 if (
Identifier.compare_insensitive(
"inf") == 0) {
2212 getTok().getEndLoc(), isRV64()));
2213 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2216 getTok().getEndLoc(), isRV64()));
2217 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2220 getTok().getEndLoc(), isRV64()));
2222 return TokError(
"invalid floating point literal");
2233 const AsmToken &Tok = getTok();
2235 return TokError(
"invalid floating point immediate");
2238 APFloat RealVal(APFloat::IEEEdouble());
2240 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2242 return TokError(
"invalid floating point representation");
2245 RealVal.changeSign();
2247 Operands.push_back(RISCVOperand::createFPImm(
2248 RealVal.bitcastToAPInt().getZExtValue(), S));
2260 switch (getLexer().getKind()) {
2272 if (getParser().parseExpression(Res,
E))
2276 return parseOperandWithSpecifier(
Operands);
2279 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2289 const MCExpr *Expr =
nullptr;
2290 bool Failed = parseExprWithSpecifier(Expr,
E);
2292 Operands.push_back(RISCVOperand::createExpr(Expr, S,
E, isRV64()));
2296bool RISCVAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
2297 SMLoc Loc = getLoc();
2299 return TokError(
"expected '%' relocation specifier");
2300 StringRef
Identifier = getParser().getTok().getIdentifier();
2303 return TokError(
"invalid relocation specifier");
2309 const MCExpr *SubExpr;
2310 if (getParser().parseParenExpression(SubExpr,
E))
2317bool RISCVAsmParser::parseDataExpr(
const MCExpr *&Res) {
2320 return parseExprWithSpecifier(Res,
E);
2321 return getParser().parseExpression(Res);
2331 StringRef
Identifier = getTok().getIdentifier();
2341 if (getParser().parseExpression(Res,
E))
2344 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2354 std::string
Identifier(getTok().getIdentifier());
2360 SMLoc Loc = getLoc();
2361 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2362 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2376 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2388 std::string
Identifier(getTok().getIdentifier());
2394 SMLoc Loc = getLoc();
2395 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2396 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2410 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2419 if (getParser().parseExpression(Res,
E))
2422 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef)
2423 return Error(S,
"operand must be a valid jump target");
2426 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2447bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2448 unsigned &Sew,
unsigned &Lmul,
2449 bool &Fractional,
bool &TailAgnostic,
2450 bool &MaskAgnostic,
bool &AltFmt) {
2455 if (State < VTypeState::SeenSew &&
Identifier.consume_front(
"e")) {
2457 if (Identifier ==
"16alt") {
2460 }
else if (Identifier ==
"8alt") {
2470 State = VTypeState::SeenSew;
2474 if (State < VTypeState::SeenLmul &&
Identifier.consume_front(
"m")) {
2477 if (Identifier ==
"a" || Identifier ==
"u") {
2479 State = VTypeState::SeenMaskPolicy;
2490 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2491 unsigned MinLMUL = ELEN / 8;
2494 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2495 Twine(MinLMUL) +
" is reserved");
2498 State = VTypeState::SeenLmul;
2502 if (State < VTypeState::SeenTailPolicy &&
Identifier.starts_with(
"t")) {
2503 if (Identifier ==
"ta")
2504 TailAgnostic =
true;
2505 else if (Identifier ==
"tu")
2506 TailAgnostic =
false;
2510 State = VTypeState::SeenTailPolicy;
2514 if (State < VTypeState::SeenMaskPolicy &&
Identifier.starts_with(
"m")) {
2515 if (Identifier ==
"ma")
2516 MaskAgnostic =
true;
2517 else if (Identifier ==
"mu")
2518 MaskAgnostic =
false;
2522 State = VTypeState::SeenMaskPolicy;
2535 bool Fractional =
false;
2536 bool TailAgnostic =
false;
2537 bool MaskAgnostic =
false;
2540 VTypeState State = VTypeState::SeenNothingYet;
2542 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2543 MaskAgnostic, AltFmt)) {
2545 if (State == VTypeState::SeenNothingYet)
2554 State == VTypeState::SeenNothingYet)
2555 return generateVTypeError(S);
2559 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2560 unsigned MaxSEW = ELEN / Lmul;
2562 if (MaxSEW >= 8 && Sew > MaxSEW)
2563 Warning(S,
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2564 " and LMUL == mf" + Twine(Lmul) +
2565 " may not be compatible with all RVV implementations");
2570 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2574bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2575 return Error(ErrorLoc,
2577 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2597 if (Identifier !=
"16alt")
2626 Operands.push_back(RISCVOperand::createVType(
2632 return generateXSfmmVTypeError(S);
2635bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
2636 return Error(ErrorLoc,
"operand must be e[8|16|16alt|32|64],w[1|2|4]");
2643 StringRef
Name = getLexer().getTok().getIdentifier();
2644 if (!
Name.consume_back(
".t")) {
2648 return Error(getLoc(),
"expected '.t' suffix");
2655 if (
Reg != RISCV::V0)
2658 SMLoc
E = getTok().getEndLoc();
2660 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2668 StringRef
Name = getLexer().getTok().getIdentifier();
2669 if (!
Name.consume_back(
".scale"))
2670 return Error(getLoc(),
"expected '.scale' suffix");
2675 if (
Reg != RISCV::V0)
2678 SMLoc
E = getTok().getEndLoc();
2680 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2689 StringRef
Name = getLexer().getTok().getIdentifier();
2690 if (!
Name.consume_front(
"L") && !
Name.consume_front(
"l"))
2695 return Error(S,
"operand must be L1, L2, L4, L8, L16, L32, or L64");
2697 unsigned EncodedLambda =
Log2_32(Lambda) + 1;
2699 SMLoc
E = getTok().getEndLoc();
2701 Operands.push_back(RISCVOperand::createExpr(
2707 if (!isRV64() || getSTI().
hasFeature(RISCV::FeatureStdExtF))
2717 StringRef
Name = getLexer().getTok().getIdentifier();
2723 SMLoc
E = getTok().getEndLoc();
2725 Operands.push_back(RISCVOperand::createReg(
2731 if (isRV64() || getSTI().
hasFeature(RISCV::FeatureStdExtF))
2737 StringRef
Name = getLexer().getTok().getIdentifier();
2743 if (!getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg))
2746 if ((
Reg - RISCV::X0) & 1) {
2749 if (getSTI().
hasFeature(RISCV::FeatureStdExtZfinx))
2750 return TokError(
"double precision floating point operands must use even "
2751 "numbered X register");
2756 SMLoc
E = getTok().getEndLoc();
2759 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2761 Reg, RISCV::sub_gpr_even,
2762 &getRISCVMCRegisterClass(RISCV::GPRPairRegClassID));
2763 Operands.push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2767template <
bool IsRV64>
2769 return parseGPRPair(
Operands, IsRV64);
2779 if (!IsRV64Inst && isRV64())
2785 StringRef
Name = getLexer().getTok().getIdentifier();
2791 if (!getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg))
2794 if ((
Reg - RISCV::X0) & 1)
2795 return TokError(
"register must be even");
2798 SMLoc
E = getTok().getEndLoc();
2801 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2803 Reg, RISCV::sub_gpr_even,
2804 &getRISCVMCRegisterClass(RISCV::GPRPairRegClassID));
2805 Operands.push_back(RISCVOperand::createReg(Pair, S,
E));
2812 "operand must be a valid SpacemiT's Integer Matrix VType mnemonic");
2814 StringRef Str = getLexer().getTok().getIdentifier();
2817 if (!isValidSMTVTypeMode(VType))
2818 return TokError(
"SpacemiT's Integer Matrix only supports [i4|i8] mode");
2820 Operands.push_back(RISCVOperand::createSMTVType(VType, getLoc()));
2828 "operand must be a valid floating point rounding mode mnemonic");
2830 StringRef Str = getLexer().getTok().getIdentifier();
2835 "operand must be a valid floating point rounding mode mnemonic");
2837 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2842std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultSMTVType() {
2843 return RISCVOperand::createSMTVType(XSMTVTypeMode::SMTVTypeMode::SMT_I8,
2848 const AsmToken &Tok = getLexer().getTok();
2854 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2868 for (
char c : Str) {
2897 Operands.push_back(RISCVOperand::createFenceArg(
Imm, getLoc()));
2903 return TokError(
"operand must be formed of letters selected in-order from "
2910 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
2912 if (!parseRegister(
Operands).isSuccess())
2913 return Error(getLoc(),
"expected register");
2917 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2941 std::unique_ptr<RISCVOperand> OptionalImmOp;
2948 SMLoc ImmStart = getLoc();
2949 if (getParser().parseIntToken(ImmVal,
2950 "expected '(' or optional integer offset"))
2955 SMLoc ImmEnd = getLoc();
2958 ImmStart, ImmEnd, isRV64());
2962 OptionalImmOp ?
"expected '(' after optional integer offset"
2963 :
"expected '(' or optional integer offset"))
2966 if (!parseRegister(
Operands).isSuccess())
2967 return Error(getLoc(),
"expected register");
2973 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2975 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2976 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2987 StringRef OffsetRegName = getLexer().getTok().getIdentifier();
2990 !getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(OffsetReg))
2991 return Error(getLoc(),
"expected GPR register");
2998 return Error(getLoc(),
"expected GPR register");
3000 StringRef BaseRegName = getLexer().getTok().getIdentifier();
3003 !getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(BaseReg))
3004 return Error(getLoc(),
"expected GPR register");
3010 Operands.push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));
3023 bool MustIncludeS0) {
3035 return Error(getLoc(),
"invalid register");
3037 StringRef
RegName = getTok().getIdentifier();
3040 return Error(getLoc(),
"invalid register");
3043 UsesXRegs =
RegName[0] ==
'x';
3044 if (
Reg != RISCV::X1)
3045 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
3046 }
else if (RegEnd == RISCV::X1) {
3047 if (
Reg != RISCV::X8 || (UsesXRegs != (
RegName[0] ==
'x')))
3048 return Error(getLoc(), Twine(
"register must be '") +
3049 (UsesXRegs ?
"x8" :
"s0") +
"'");
3050 }
else if (RegEnd == RISCV::X9 && UsesXRegs) {
3051 if (
Reg != RISCV::X18 || (
RegName[0] !=
'x'))
3052 return Error(getLoc(),
"register must be 'x18'");
3054 return Error(getLoc(),
"too many register ranges");
3061 SMLoc MinusLoc = getLoc();
3063 if (RegEnd == RISCV::X1)
3064 return Error(MinusLoc, Twine(
"register '") + (UsesXRegs ?
"x1" :
"ra") +
3065 "' cannot start a multiple register range");
3068 return Error(getLoc(),
"invalid register");
3070 StringRef
RegName = getTok().getIdentifier();
3073 return Error(getLoc(),
"invalid register");
3075 if (RegEnd == RISCV::X8) {
3076 if ((
Reg != RISCV::X9 &&
3078 (UsesXRegs != (
RegName[0] ==
'x'))) {
3080 return Error(getLoc(),
"register must be 'x9'");
3081 return Error(getLoc(),
"register must be in the range 's1' to 's11'");
3083 }
else if (RegEnd == RISCV::X18) {
3085 return Error(getLoc(),
3086 "register must be in the range 'x19' to 'x27'");
3099 if (RegEnd == RISCV::X26)
3100 return Error(S,
"invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "
3101 "x18-x26}' is not supported");
3107 return Error(S,
"register list must include 's0' or 'x8'");
3109 Operands.push_back(RISCVOperand::createRegList(Encode, S));
3115 bool ExpectNegative) {
3124 auto *RegListOp =
static_cast<RISCVOperand *
>(
Operands.back().
get());
3125 if (!RegListOp->isRegList())
3128 unsigned RlistEncode = RegListOp->RegList.Encoding;
3132 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||
3133 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {
3134 int64_t
Lower = StackAdjBase;
3135 int64_t
Upper = StackAdjBase + 48;
3136 if (ExpectNegative) {
3141 return generateImmOutOfRangeError(S,
Lower,
Upper,
3142 "stack adjustment for register list must "
3143 "be a multiple of 16 bytes in the range");
3147 Operands.push_back(RISCVOperand::createStackAdj(StackAdj, S));
3159 MatchOperandParserImpl(
Operands, Mnemonic,
true);
3166 if (parseRegister(
Operands,
true).isSuccess())
3170 if (parseExpression(
Operands).isSuccess()) {
3173 return !parseMemOpBaseReg(
Operands).isSuccess();
3178 Error(getLoc(),
"unknown operand");
3182bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &Info,
3183 StringRef Name, SMLoc NameLoc,
3189 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
3193 Operands.push_back(RISCVOperand::createToken(Name, NameLoc));
3212 if (getParser().parseEOL(
"unexpected token")) {
3213 getParser().eatToEndOfStatement();
3219bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
3223 Kind = RE->getSpecifier();
3224 Expr = RE->getSubExpr();
3233bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
3242ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
3243 StringRef IDVal = DirectiveID.
getString();
3245 if (IDVal ==
".option")
3246 return parseDirectiveOption();
3247 if (IDVal ==
".attribute")
3248 return parseDirectiveAttribute();
3249 if (IDVal ==
".insn")
3250 return parseDirectiveInsn(DirectiveID.
getLoc());
3251 if (IDVal ==
".variant_cc")
3252 return parseDirectiveVariantCC();
3257bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
3258 bool FromOptionDirective) {
3259 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
3262 clearFeatureBits(Feature.Value, Feature.key());
3269 raw_string_ostream OutputErrMsg(Buffer);
3270 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3271 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
3272 << ErrMsg.getMessage();
3275 return Error(Loc, OutputErrMsg.str());
3277 auto &ISAInfo = *ParseResult;
3280 if (ISAInfo->hasExtension(Feature.key()))
3281 setFeatureBits(Feature.Value, Feature.key());
3283 if (FromOptionDirective) {
3284 if (ISAInfo->getXLen() == 32 && isRV64())
3285 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3286 else if (ISAInfo->getXLen() == 64 && !isRV64())
3287 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3290 if (ISAInfo->getXLen() == 32)
3291 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
3292 else if (ISAInfo->getXLen() == 64)
3293 setFeatureBits(RISCV::Feature64Bit,
"64bit");
3295 return Error(Loc,
"bad arch string " + Arch);
3297 Result = ISAInfo->toString();
3301bool RISCVAsmParser::parseDirectiveOption() {
3302 MCAsmParser &Parser = getParser();
3304 AsmToken Tok = Parser.
getTok();
3312 if (Option ==
"push") {
3316 getTargetStreamer().emitDirectiveOptionPush();
3321 if (Option ==
"pop") {
3326 getTargetStreamer().emitDirectiveOptionPop();
3327 if (popFeatureBits())
3328 return Error(StartLoc,
".option pop with no .option push");
3333 if (Option ==
"arch") {
3341 Type = RISCVOptionArchArgType::Plus;
3343 Type = RISCVOptionArchArgType::Minus;
3344 else if (!
Args.empty())
3346 "unexpected token, expected + or -");
3348 Type = RISCVOptionArchArgType::Full;
3352 "unexpected token, expected identifier");
3358 if (
Type == RISCVOptionArchArgType::Full) {
3360 if (resetToArch(Arch, Loc, Result,
true))
3369 Loc,
"extension version number parsing not currently implemented");
3372 if (!enableExperimentalExtension() &&
3374 return Error(Loc,
"unexpected experimental extensions");
3375 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
3377 if (Ext == std::end(
AllFeatures) || StringRef(Ext->key()) != Feature)
3378 return Error(Loc,
"unknown extension feature");
3382 if (
Type == RISCVOptionArchArgType::Plus) {
3385 setFeatureBits(Ext->Value, Ext->key());
3388 copySTI().setFeatureBits(OldFeatureBits);
3389 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3392 raw_string_ostream OutputErrMsg(Buffer);
3393 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3394 OutputErrMsg << ErrMsg.getMessage();
3397 return Error(Loc, OutputErrMsg.str());
3400 assert(
Type == RISCVOptionArchArgType::Minus);
3406 Feature.Implies.test(Ext->Value))
3407 return Error(Loc, Twine(
"can't disable ") + Ext->key() +
3408 " extension; " + Feature.key() +
3409 " extension requires " + Ext->key() +
3413 clearFeatureBits(Ext->Value, Ext->key());
3420 getTargetStreamer().emitDirectiveOptionArch(Args);
3423 getTargetStreamer().setArchString((*ParseResult)->toString());
3427 if (Option ==
"exact") {
3431 getTargetStreamer().emitDirectiveOptionExact();
3432 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3433 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3437 if (Option ==
"noexact") {
3441 getTargetStreamer().emitDirectiveOptionNoExact();
3442 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3443 setFeatureBits(RISCV::FeatureRelax,
"relax");
3447 if (Option ==
"rvc") {
3451 getTargetStreamer().emitDirectiveOptionRVC();
3452 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3454 getTargetStreamer().setArchString((*ParseResult)->toString());
3458 if (Option ==
"norvc") {
3462 getTargetStreamer().emitDirectiveOptionNoRVC();
3463 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3464 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3466 getTargetStreamer().setArchString((*ParseResult)->toString());
3470 if (Option ==
"pic") {
3474 getTargetStreamer().emitDirectiveOptionPIC();
3475 ParserOptions.IsPicEnabled =
true;
3479 if (Option ==
"nopic") {
3483 getTargetStreamer().emitDirectiveOptionNoPIC();
3484 ParserOptions.IsPicEnabled =
false;
3488 if (Option ==
"relax") {
3492 getTargetStreamer().emitDirectiveOptionRelax();
3493 setFeatureBits(RISCV::FeatureRelax,
"relax");
3497 if (Option ==
"norelax") {
3501 getTargetStreamer().emitDirectiveOptionNoRelax();
3502 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3508 "unknown option, expected 'push', 'pop', "
3509 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3510 "'exact', or 'noexact'");
3518bool RISCVAsmParser::parseDirectiveAttribute() {
3519 MCAsmParser &Parser = getParser();
3525 std::optional<unsigned> Ret =
3528 return Error(TagLoc,
"attribute name not recognised: " + Name);
3532 const MCExpr *AttrExpr;
3539 if (check(!CE, TagLoc,
"expected numeric constant"))
3542 Tag =
CE->getValue();
3548 StringRef StringValue;
3549 int64_t IntegerValue = 0;
3550 bool IsIntegerValue =
true;
3555 IsIntegerValue =
false;
3558 if (IsIntegerValue) {
3559 const MCExpr *ValueExpr;
3565 return Error(ValueExprLoc,
"expected numeric constant");
3566 IntegerValue =
CE->getValue();
3579 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3581 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3584 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3588 getTargetStreamer().emitTextAttribute(
Tag, Result);
3592 getTargetStreamer().setArchString(Result);
3600 .
Cases({
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s"},
true)
3601 .Cases({
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj"},
3603 .
Cases({
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es"},
3612bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3613 MCAsmParser &Parser = getParser();
3620 std::optional<int64_t>
Length;
3630 return Error(ErrorLoc,
3631 "instruction lengths must be a non-zero multiple of two");
3635 return Error(ErrorLoc,
3636 "instruction lengths over 64 bits are not supported");
3642 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3647 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3648 return Error(ErrorLoc,
3649 "instruction length does not match the encoding");
3652 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3655 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3658 if (!getSTI().
hasFeature(RISCV::FeatureStdExtZca) &&
3659 (EncodingDerivedLength == 2))
3660 return Error(ErrorLoc,
"compressed instructions are not allowed");
3662 if (getParser().parseEOL(
"invalid operand for instruction")) {
3663 getParser().eatToEndOfStatement();
3671 Opcode = RISCV::Insn16;
3674 Opcode = RISCV::Insn32;
3677 Opcode = RISCV::Insn48;
3680 Opcode = RISCV::Insn64;
3686 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3688 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3693 return Error(ErrorLoc,
"invalid instruction format");
3695 std::string FormatName = (
".insn_" +
Format).str();
3697 ParseInstructionInfo
Info;
3700 if (parseInstruction(Info, FormatName, L,
Operands))
3712bool RISCVAsmParser::parseDirectiveVariantCC() {
3714 if (getParser().parseIdentifier(Name))
3715 return TokError(
"expected symbol name");
3718 getTargetStreamer().emitDirectiveVariantCC(
3723void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3726 const MCSubtargetInfo &STI = getSTI();
3727 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3730 ++RISCVNumInstrsCompressed;
3734void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3739 for (MCInst &Inst : Seq) {
3740 emitToStreamer(Out, Inst);
3744void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3745 const MCExpr *Symbol,
3747 unsigned SecondOpcode, SMLoc IDLoc,
3755 Out.emitLabel(TmpLabel);
3759 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3764 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3767 .addExpr(RefToLinkTmpLabel));
3770void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3783 Out, MCInstBuilder(RISCV::QC_E_LI).addReg(DestReg).addExpr(Symbol));
3789void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3799 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3800 emitAuipcInstPair(DestReg, DestReg, Symbol,
RISCV::S_GOT_HI, SecondOpcode,
3804void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3813 if (ParserOptions.IsPicEnabled)
3814 emitLoadGlobalAddress(Inst, IDLoc, Out);
3816 emitLoadLocalAddress(Inst, IDLoc, Out);
3819void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3829 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3830 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3831 SecondOpcode, IDLoc, Out);
3834void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3844 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3845 RISCV::ADDI, IDLoc, Out);
3848void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3849 SMLoc IDLoc, MCStreamer &Out,
3858 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3860 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3864 if (getRISCVMCRegisterClass(RISCV::GPRPairRegClassID).
contains(TmpReg)) {
3865 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3866 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3874void RISCVAsmParser::emitQCELILoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3875 SMLoc IDLoc, MCStreamer &Out,
3885 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3889 MCInstBuilder(RISCV::QC_E_LI).addReg(AddrReg).addExpr(Symbol));
3892 const MCExpr *AccessExpr =
3898 struct CompressedForm {
3902 std::optional<CompressedForm> Compressed;
3906 case RISCV::PseudoQCAccessLBU:
3907 Compressed = {RISCV::PseudoQCAccessC_LBU, RISCV::FeatureStdExtZcb};
3909 case RISCV::PseudoQCAccessLH:
3910 Compressed = {RISCV::PseudoQCAccessC_LH, RISCV::FeatureStdExtZcb};
3912 case RISCV::PseudoQCAccessLHU:
3913 Compressed = {RISCV::PseudoQCAccessC_LHU, RISCV::FeatureStdExtZcb};
3915 case RISCV::PseudoQCAccessLW:
3916 Compressed = {RISCV::PseudoQCAccessC_LW, RISCV::FeatureStdExtZca};
3918 case RISCV::PseudoQCAccessSB:
3919 Compressed = {RISCV::PseudoQCAccessC_SB, RISCV::FeatureStdExtZcb};
3921 case RISCV::PseudoQCAccessSH:
3922 Compressed = {RISCV::PseudoQCAccessC_SH, RISCV::FeatureStdExtZcb};
3924 case RISCV::PseudoQCAccessSW:
3925 Compressed = {RISCV::PseudoQCAccessC_SW, RISCV::FeatureStdExtZca};
3932 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(AddrReg);
3933 if (HasTmpReg && CanUseGPRC) {
3936 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(DataReg);
3939 bool UseCompressed =
3940 Compressed && getSTI().hasFeature(Compressed->Feature) && CanUseGPRC;
3942 unsigned ActualOpcode = UseCompressed ? Compressed->Opcode : Opcode;
3945 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3949 .addExpr(AccessExpr));
3951 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3955 .addExpr(AccessExpr));
3959void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3960 int64_t Width, SMLoc IDLoc,
3969 const MCOperand &DestReg = Inst.
getOperand(0);
3970 const MCOperand &SourceReg = Inst.
getOperand(1);
3972 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3973 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3975 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3977 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3982 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3988void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
3995 emitToStreamer(Out, MCInstBuilder(Opcode)
3999 .addReg(MCRegister())
4001 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
4012 "The destination register should not be V0.");
4014 emitToStreamer(Out, MCInstBuilder(Opcode)
4020 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
4032 "The temporary vector register should not be V0.");
4033 emitToStreamer(Out, MCInstBuilder(Opcode)
4037 .addReg(MCRegister())
4039 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4051 "The temporary vector register should not be V0.");
4052 emitToStreamer(Out, MCInstBuilder(Opcode)
4056 .addReg(MCRegister())
4058 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4063 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4068 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
4076bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
4078 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
4081 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
4082 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
4083 "%tprel_add specifier");
4089bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
4091 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
4094 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
4095 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
4096 "%tlsdesc_call specifier");
4102std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
4103 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
4106std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
4107 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
4111std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
4112 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
4116std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultZeroOffset() {
4118 llvm::SMLoc(), llvm::SMLoc(), isRV64());
4125 case RISCV::VLOXSEG2EI8_V:
4126 case RISCV::VLOXSEG2EI16_V:
4127 case RISCV::VLOXSEG2EI32_V:
4128 case RISCV::VLOXSEG2EI64_V:
4129 case RISCV::VLUXSEG2EI8_V:
4130 case RISCV::VLUXSEG2EI16_V:
4131 case RISCV::VLUXSEG2EI32_V:
4132 case RISCV::VLUXSEG2EI64_V:
4134 case RISCV::VLOXSEG3EI8_V:
4135 case RISCV::VLOXSEG3EI16_V:
4136 case RISCV::VLOXSEG3EI32_V:
4137 case RISCV::VLOXSEG3EI64_V:
4138 case RISCV::VLUXSEG3EI8_V:
4139 case RISCV::VLUXSEG3EI16_V:
4140 case RISCV::VLUXSEG3EI32_V:
4141 case RISCV::VLUXSEG3EI64_V:
4143 case RISCV::VLOXSEG4EI8_V:
4144 case RISCV::VLOXSEG4EI16_V:
4145 case RISCV::VLOXSEG4EI32_V:
4146 case RISCV::VLOXSEG4EI64_V:
4147 case RISCV::VLUXSEG4EI8_V:
4148 case RISCV::VLUXSEG4EI16_V:
4149 case RISCV::VLUXSEG4EI32_V:
4150 case RISCV::VLUXSEG4EI64_V:
4152 case RISCV::VLOXSEG5EI8_V:
4153 case RISCV::VLOXSEG5EI16_V:
4154 case RISCV::VLOXSEG5EI32_V:
4155 case RISCV::VLOXSEG5EI64_V:
4156 case RISCV::VLUXSEG5EI8_V:
4157 case RISCV::VLUXSEG5EI16_V:
4158 case RISCV::VLUXSEG5EI32_V:
4159 case RISCV::VLUXSEG5EI64_V:
4161 case RISCV::VLOXSEG6EI8_V:
4162 case RISCV::VLOXSEG6EI16_V:
4163 case RISCV::VLOXSEG6EI32_V:
4164 case RISCV::VLOXSEG6EI64_V:
4165 case RISCV::VLUXSEG6EI8_V:
4166 case RISCV::VLUXSEG6EI16_V:
4167 case RISCV::VLUXSEG6EI32_V:
4168 case RISCV::VLUXSEG6EI64_V:
4170 case RISCV::VLOXSEG7EI8_V:
4171 case RISCV::VLOXSEG7EI16_V:
4172 case RISCV::VLOXSEG7EI32_V:
4173 case RISCV::VLOXSEG7EI64_V:
4174 case RISCV::VLUXSEG7EI8_V:
4175 case RISCV::VLUXSEG7EI16_V:
4176 case RISCV::VLUXSEG7EI32_V:
4177 case RISCV::VLUXSEG7EI64_V:
4179 case RISCV::VLOXSEG8EI8_V:
4180 case RISCV::VLOXSEG8EI16_V:
4181 case RISCV::VLOXSEG8EI32_V:
4182 case RISCV::VLOXSEG8EI64_V:
4183 case RISCV::VLUXSEG8EI8_V:
4184 case RISCV::VLUXSEG8EI16_V:
4185 case RISCV::VLUXSEG8EI32_V:
4186 case RISCV::VLUXSEG8EI64_V:
4192 if (getRISCVMCRegisterClass(RISCV::VRM2RegClassID).
contains(
Reg))
4194 if (getRISCVMCRegisterClass(RISCV::VRM4RegClassID).
contains(
Reg))
4196 if (getRISCVMCRegisterClass(RISCV::VRM8RegClassID).
contains(
Reg))
4203 case RISCV::VFWMMACC_VV_SCALE:
4204 case RISCV::VFQMMACC_VV_SCALE:
4205 case RISCV::VF8WMMACC_VV_SCALE:
4206 case RISCV::VFWIMMACC_VV:
4207 case RISCV::VFQIMMACC_VV:
4208 case RISCV::VF8WIMMACC_VV:
4215bool RISCVAsmParser::validateInstruction(MCInst &Inst,
4219 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
4220 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
4223 if (DestReg == TempReg) {
4224 SMLoc Loc =
Operands.back()->getStartLoc();
4225 return Error(Loc,
"the temporary vector register cannot be the same as "
4226 "the destination register");
4230 if (Opcode == RISCV::PseudoVMSGEU_VX_M || Opcode == RISCV::PseudoVMSGE_VX_M) {
4233 if (MaskReg == RISCV::V0 && DestReg == RISCV::V0) {
4234 SMLoc Loc =
Operands.back()->getStartLoc();
4235 return Error(Loc,
"the destination vector register cannot overlap the "
4236 "mask register unless a temporary register is "
4241 if (Opcode == RISCV::CV_INSERT &&
4244 "the sum of the immediate operands must be less than 32");
4246 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
4247 Opcode == RISCV::TH_LWD) {
4252 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
4253 SMLoc Loc =
Operands[1]->getStartLoc();
4254 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
4258 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
4262 SMLoc Loc =
Operands[1]->getStartLoc();
4263 return Error(Loc,
"rs1 and rs2 must be different");
4268 auto CheckOperandDoesNotOverlapV0 = [&](
int OperandIdx,
4269 unsigned ParsedIdx) {
4272 "vd, vs1, and vs2 cannot overlap v0.scale");
4277 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4279 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4281 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4282 assert(DestIdx >= 0 && VS1Idx >= 0 && VS2Idx >= 0 &&
4283 "Unexpected Zvvfmm scaled operand list");
4285 if (CheckOperandDoesNotOverlapV0(DestIdx, 1) ||
4286 CheckOperandDoesNotOverlapV0(VS1Idx, 2) ||
4287 CheckOperandDoesNotOverlapV0(VS2Idx, 3))
4291 const MCInstrDesc &MCID = MII.
get(Opcode);
4295 int DestIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4299 const MCParsedAsmOperand *ParsedOp =
Operands[1].get();
4300 if (!ParsedOp->
isReg()) {
4305 assert(ParsedOp->
getReg() == DestReg &&
"Can't find parsed dest operand");
4309 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4313 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4314 assert(VS2Idx >= 0 &&
"No vs2 operand?");
4315 unsigned CheckEncoding =
4318 for (
unsigned i = 0; i < std::max(NF, Lmul); i++) {
4319 if ((DestEncoding + i) == CheckEncoding)
4320 return Error(Loc,
"the destination vector register group cannot overlap"
4321 " the source vector register group");
4326 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4330 unsigned CheckEncoding =
4332 for (
unsigned i = 0; i < Lmul; i++) {
4333 if ((DestEncoding + i) == CheckEncoding)
4335 "the destination vector register group cannot overlap"
4336 " the source vector register group");
4342 int VMIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vm);
4343 assert(VMIdx >= 0 &&
"No vm operand?");
4345 if (DestReg == RISCV::V0) {
4348 return Error(Loc,
"the destination vector register group cannot be V0");
4356 "Unexpected mask operand register");
4358 return Error(Loc,
"the destination vector register group cannot overlap"
4359 " the mask register");
4367 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vmask);
4369 if (MaskReg != RISCV::V0 && MaskReg != RISCV::V1)
4371 "vmask operand only supports v0 or v1");
4374 RISCV::OpName RegOps[] = {RISCV::OpName::vd, RISCV::OpName::vs1,
4375 RISCV::OpName::vs2};
4376 for (RISCV::OpName OpN : RegOps) {
4377 int Idx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), OpN);
4383 for (
unsigned i = 0; i < RegLmul; i++) {
4384 if ((RegEnc + i) == MaskEnc) {
4385 SMLoc Loc =
Operands[Idx]->getStartLoc();
4386 return Error(Loc, Twine(
"register conflicts with vmask register ") +
4396bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
4404 case RISCV::MOP_RR_7: {
4416 case RISCV::MOP_R_28: {
4434 case RISCV::PseudoC_ADDI_NOP: {
4436 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
4446 if (getSTI().
hasFeature(RISCV::Feature64Bit))
4448 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV32)
4453 case RISCV::PACKW: {
4457 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV64)
4462 case RISCV::PseudoLLAImm:
4463 case RISCV::PseudoLAImm:
4464 case RISCV::PseudoLI: {
4470 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
4482 emitLoadImm(
Reg,
Imm, Out);
4485 case RISCV::PseudoLLA:
4486 emitLoadLocalAddress(Inst, IDLoc, Out);
4488 case RISCV::PseudoLGA:
4489 emitLoadGlobalAddress(Inst, IDLoc, Out);
4491 case RISCV::PseudoLA:
4492 emitLoadAddress(Inst, IDLoc, Out);
4494 case RISCV::PseudoLA_TLS_IE:
4495 emitLoadTLSIEAddress(Inst, IDLoc, Out);
4497 case RISCV::PseudoLA_TLS_GD:
4498 emitLoadTLSGDAddress(Inst, IDLoc, Out);
4500 case RISCV::PseudoLB:
4501 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
4503 case RISCV::PseudoLBU:
4504 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
4506 case RISCV::PseudoLH:
4507 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
4509 case RISCV::PseudoLHU:
4510 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
4512 case RISCV::PseudoLW:
4513 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
4515 case RISCV::PseudoLWU:
4516 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
4518 case RISCV::PseudoLD:
4519 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
4521 case RISCV::PseudoLD_RV32:
4522 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
4524 case RISCV::PseudoFLH:
4525 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
4527 case RISCV::PseudoFLW:
4528 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
4530 case RISCV::PseudoFLD:
4531 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
4533 case RISCV::PseudoFLQ:
4534 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
4536 case RISCV::PseudoSB:
4537 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
4539 case RISCV::PseudoSH:
4540 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
4542 case RISCV::PseudoSW:
4543 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
4545 case RISCV::PseudoSD:
4546 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
4548 case RISCV::PseudoSD_RV32:
4549 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
4551 case RISCV::PseudoQC_E_LB:
4552 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLB, IDLoc, Out,
4555 case RISCV::PseudoQC_E_LBU:
4556 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLBU, IDLoc, Out,
4559 case RISCV::PseudoQC_E_LH:
4560 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLH, IDLoc, Out,
4563 case RISCV::PseudoQC_E_LHU:
4564 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLHU, IDLoc, Out,
4567 case RISCV::PseudoQC_E_LW:
4568 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLW, IDLoc, Out,
4571 case RISCV::PseudoQC_E_SB:
4572 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSB, IDLoc, Out,
4575 case RISCV::PseudoQC_E_SH:
4576 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSH, IDLoc, Out,
4579 case RISCV::PseudoQC_E_SW:
4580 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSW, IDLoc, Out,
4583 case RISCV::PseudoFSH:
4584 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
4586 case RISCV::PseudoFSW:
4587 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
4589 case RISCV::PseudoFSD:
4590 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4592 case RISCV::PseudoFSQ:
4593 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4595 case RISCV::PseudoAddTPRel:
4596 if (checkPseudoAddTPRel(Inst,
Operands))
4599 case RISCV::PseudoTLSDESCCall:
4600 if (checkPseudoTLSDESCCall(Inst,
Operands))
4603 case RISCV::PseudoSEXT_B:
4604 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4606 case RISCV::PseudoSEXT_H:
4607 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4609 case RISCV::PseudoZEXT_H:
4610 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4612 case RISCV::PseudoZEXT_W:
4613 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4615 case RISCV::PseudoVMSGEU_VX_M:
4616 case RISCV::PseudoVMSGEU_VX_M_T:
4617 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4619 case RISCV::PseudoVMSGE_VX_M:
4620 case RISCV::PseudoVMSGE_VX_M_T:
4621 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4623 case RISCV::PseudoVMSGE_VI:
4624 case RISCV::PseudoVMSLT_VI: {
4628 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4630 emitToStreamer(Out, MCInstBuilder(
Opc)
4638 case RISCV::PseudoVMSGEU_VI:
4639 case RISCV::PseudoVMSLTU_VI: {
4646 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4649 emitToStreamer(Out, MCInstBuilder(
Opc)
4657 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4660 emitToStreamer(Out, MCInstBuilder(
Opc)
4670 case RISCV::PseudoCV_ELW:
4671 emitLoadStoreSymbol(Inst, RISCV::CV_ELW, IDLoc, Out,
false);
4675 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)
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...
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
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,...