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 {
348 if (getTargetStreamer().hasTargetABI())
351 Expected<RISCVABI::ABI> ABIOrErr =
355 getTargetStreamer().setTargetABI(
359 getTargetStreamer().setTargetABI(*ABIOrErr);
430 MCRegister OffsetReg;
433 SMLoc StartLoc, EndLoc;
449 RISCVOperand(KindTy K) : Kind(
K) {}
452 RISCVOperand(
const RISCVOperand &o) : MCParsedAsmOperand() {
454 StartLoc =
o.StartLoc;
457 case KindTy::Register:
460 case KindTy::Expression:
463 case KindTy::FPImmediate:
469 case KindTy::SystemRegister:
475 case KindTy::SMTVType:
476 SMTVType =
o.SMTVType;
484 case KindTy::RegList:
487 case KindTy::StackAdj:
488 StackAdj =
o.StackAdj;
496 bool isToken()
const override {
return Kind == KindTy::Token; }
497 bool isReg()
const override {
return Kind == KindTy::Register; }
498 bool isExpr()
const {
return Kind == KindTy::Expression; }
499 bool isV0Reg()
const {
500 return Kind == KindTy::Register &&
Reg.Reg == RISCV::V0;
502 bool isAnyReg()
const {
503 return Kind == KindTy::Register &&
504 (getRISCVMCRegisterClass(RISCV::GPRRegClassID).contains(
Reg.Reg) ||
505 getRISCVMCRegisterClass(RISCV::FPR64RegClassID).contains(
Reg.Reg) ||
506 getRISCVMCRegisterClass(RISCV::VRRegClassID).contains(
Reg.Reg));
508 bool isAnyRegC()
const {
509 return Kind == KindTy::Register &&
510 (getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(
Reg.Reg) ||
511 getRISCVMCRegisterClass(RISCV::FPR64CRegClassID).contains(
Reg.Reg));
513 bool isImm()
const override {
return isExpr(); }
514 bool isMem()
const override {
return false; }
515 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
516 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
517 bool isRegList()
const {
return Kind == KindTy::RegList; }
518 bool isRegListS0()
const {
519 return Kind == KindTy::RegList && RegList.Encoding !=
RISCVZC::RA;
521 bool isStackAdj()
const {
return Kind == KindTy::StackAdj; }
524 return Kind == KindTy::Register &&
525 getRISCVMCRegisterClass(RISCV::GPRRegClassID).contains(
Reg.Reg);
528 bool isYGPR()
const {
529 return Kind == KindTy::Register &&
530 getRISCVMCRegisterClass(RISCV::YGPRRegClassID).contains(
Reg.Reg);
533 bool isGPRPair()
const {
534 return Kind == KindTy::Register &&
535 getRISCVMCRegisterClass(RISCV::GPRPairRegClassID).contains(
Reg.Reg);
538 bool isGPRPairC()
const {
539 return Kind == KindTy::Register &&
540 getRISCVMCRegisterClass(RISCV::GPRPairCRegClassID).contains(
Reg.Reg);
543 bool isGPRPairNoX0()
const {
544 return Kind == KindTy::Register &&
545 getRISCVMCRegisterClass(RISCV::GPRPairNoX0RegClassID)
549 bool isGPRF16()
const {
550 return Kind == KindTy::Register &&
551 getRISCVMCRegisterClass(RISCV::GPRF16RegClassID).contains(
Reg.Reg);
554 bool isGPRF32()
const {
555 return Kind == KindTy::Register &&
556 getRISCVMCRegisterClass(RISCV::GPRF32RegClassID).contains(
Reg.Reg);
559 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
560 bool isGPRAsFPR16()
const {
return isGPRF16() &&
Reg.IsGPRAsFPR; }
561 bool isGPRAsFPR32()
const {
return isGPRF32() &&
Reg.IsGPRAsFPR; }
562 bool isGPRPairAsFPR64()
const {
return isGPRPair() &&
Reg.IsGPRAsFPR; }
564 static bool evaluateConstantExpr(
const MCExpr *Expr, int64_t &
Imm) {
566 Imm =
CE->getValue();
575 template <
int N>
bool isBareSimmNLsb0()
const {
584 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
590 template <
int N>
bool isBareSimmN()
const {
596 return isInt<N>(fixImmediateForRV32(
Imm, isRV64Expr()));
599 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
605 bool isBareSymbol()
const {
608 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
612 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
616 bool isCallSymbol()
const {
619 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
623 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
627 bool isTailCallSymbol()
const {
return isCallSymbol(); }
629 bool isPseudoJumpSymbol()
const {
632 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
636 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
640 bool isTPRelAddSymbol()
const {
643 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
647 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
648 VK == ELF::R_RISCV_TPREL_ADD;
651 bool isTLSDESCCallSymbol()
const {
654 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
658 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
659 VK == ELF::R_RISCV_TLSDESC_CALL;
662 bool isQCAccessSymbol()
const {
665 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
669 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
673 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
677 bool isVTypeI10()
const {
678 if (Kind == KindTy::VType)
682 bool isVTypeI11()
const {
683 if (Kind == KindTy::VType)
688 bool isXSfmmVType()
const {
692 bool isTileLambda()
const {
698 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
701 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
702 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
707 bool isSMTVType()
const {
708 return Kind == KindTy::SMTVType &&
712 bool isSMTI8()
const {
717 bool isLoadFPImm()
const {
720 if (Kind != KindTy::FPImmediate)
723 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
726 return Idx >= 0 && Idx != 1;
729 bool isImmXLenLI()
const {
738 return RISCVAsmParser::isSymbolDiff(
getExpr());
741 bool isImmXLenLI_Restricted()
const {
745 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
747 return IsConstantImm &&
751 template <
unsigned N>
bool isUImm()
const {
755 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
759 template <
unsigned N,
unsigned S>
bool isUImmShifted()
const {
763 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
767 template <
class Pred>
bool isUImmPred(Pred p)
const {
771 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
772 return IsConstantImm &&
p(
Imm);
775 bool isUImmLog2XLen()
const {
776 if (isExpr() && isRV64Expr())
781 bool isUImmLog2XLenNonZero()
const {
782 if (isExpr() && isRV64Expr())
787 bool isUImmLog2XLenHalf()
const {
788 if (isExpr() && isRV64Expr())
793 bool isUImm5NonZero()
const {
797 bool isUImm5GT3()
const {
801 bool isUImm4Plus1()
const {
806 bool isUImm5Plus1()
const {
811 bool isUImm6Plus1()
const {
816 bool isUImm5GE6Plus1()
const {
821 bool isUImm5Slist()
const {
822 return isUImmPred([](int64_t
Imm) {
823 return (
Imm == 0) || (
Imm == 1) || (
Imm == 2) || (
Imm == 4) ||
824 (
Imm == 8) || (
Imm == 16) || (
Imm == 15) || (
Imm == 31);
828 bool isUImm7EqXLen()
const {
830 [
this](int64_t
Imm) {
return isRV64Expr() ?
Imm == 64 :
Imm == 32; });
833 bool isUImm8GE32()
const {
837 bool isRnumArg()
const {
839 [](int64_t
Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(10); });
842 bool isRnumArg_0_7()
const {
844 [](int64_t
Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(7); });
847 bool isRnumArg_1_10()
const {
849 [](int64_t
Imm) {
return Imm >= INT64_C(1) &&
Imm <= INT64_C(10); });
852 bool isRnumArg_2_14()
const {
854 [](int64_t
Imm) {
return Imm >= INT64_C(2) &&
Imm <= INT64_C(14); });
857 template <
unsigned N>
bool isSImm()
const {
861 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
862 return IsConstantImm &&
isInt<N>(fixImmediateForRV32(
Imm, isRV64Expr()));
865 bool isYBNDSWImm()
const {
870 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
874 template <
class Pred>
bool isSImmPred(Pred p)
const {
878 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
879 return IsConstantImm &&
p(fixImmediateForRV32(
Imm, isRV64Expr()));
882 bool isSImm5NonZero()
const {
886 bool isSImm6NonZero()
const {
890 bool isCLUIImm()
const {
891 return isUImmPred([](int64_t
Imm) {
896 bool isUImm10Lsb00NonZero()
const {
903 static int64_t fixImmediateForRV32(int64_t
Imm,
bool IsRV64Imm) {
909 bool isSImm12LO()
const {
915 return isInt<12>(fixImmediateForRV32(
Imm, isRV64Expr()));
918 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
921 VK == ELF::R_RISCV_TLSDESC_ADD_LO12);
929 template <
bool (RISCVOperand::*Pred)() const>
930 DiagnosticPredicate isOptionalMemOffset()
const {
934 : DiagnosticPredicate::NearMatch;
937 bool isSImm12Lsb00000()
const {
941 bool isSImm10Lsb0000NonZero()
const {
946 bool isSImm16NonZero()
const {
950 bool isUImm16NonZero()
const {
954 bool isSImm20LI()
const {
960 return isInt<20>(fixImmediateForRV32(
Imm, isRV64Expr()));
963 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
967 bool isSImm8PLI_B()
const {
return isSImm<8>() || isUImm<8>(); }
968 bool isSImm10PLUI()
const {
return isSImm<10>() || isUImm<10>(); }
970 bool isSImm10PLI_H()
const {
971 return isSImm<10>() || isUImmPred([](int64_t
Imm) {
975 bool isSImm10PLI_W()
const {
976 return isSImm<10>() || isUImmPred([](int64_t
Imm) {
981 bool isUImm20LUI()
const {
990 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
991 (VK == ELF::R_RISCV_HI20 || VK == ELF::R_RISCV_TPREL_HI20);
994 bool isUImm20AUIPC()
const {
1003 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
1005 VK == ELF::R_RISCV_TLS_GOT_HI20 || VK == ELF::R_RISCV_TLS_GD_HI20 ||
1006 VK == ELF::R_RISCV_TLSDESC_HI20);
1009 bool isImmZero()
const {
1010 return isUImmPred([](int64_t
Imm) {
return 0 ==
Imm; });
1013 bool isImmThree()
const {
1014 return isUImmPred([](int64_t
Imm) {
return 3 ==
Imm; });
1017 bool isImmFour()
const {
1018 return isUImmPred([](int64_t
Imm) {
return 4 ==
Imm; });
1021 bool isImm5Zibi()
const {
1026 bool isSImm5Plus1()
const {
1031 bool isSImm18Lsb0()
const {
1035 bool isSImm19Lsb00()
const {
1039 bool isSImm20Lsb000()
const {
1043 bool isSImm32Lsb0()
const {
1048 SMLoc getStartLoc()
const override {
return StartLoc; }
1050 SMLoc getEndLoc()
const override {
return EndLoc; }
1053 bool isRV64Expr()
const {
1054 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1058 MCRegister
getReg()
const override {
1059 assert(Kind == KindTy::Register &&
"Invalid type access!");
1063 StringRef getSysReg()
const {
1064 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
1065 return StringRef(SysReg.Data, SysReg.Length);
1068 const MCExpr *
getExpr()
const {
1069 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1074 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1079 assert(Kind == KindTy::Token &&
"Invalid type access!");
1083 unsigned getVType()
const {
1084 assert(Kind == KindTy::VType &&
"Invalid type access!");
1089 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1093 unsigned getFence()
const {
1094 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1099 assert(Kind == KindTy::SMTVType &&
"Invalid type access!");
1100 return SMTVType.SMTVType;
1103 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1112 case KindTy::Expression:
1115 OS <<
' ' << (Expr.IsRV64 ?
"rv64" :
"rv32") <<
'>';
1117 case KindTy::FPImmediate:
1118 OS <<
"<fpimm: " << FPImm.Val <<
">";
1120 case KindTy::Register:
1122 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1127 case KindTy::SystemRegister:
1128 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1137 OS << roundingModeToString(getFRM());
1140 case KindTy::SMTVType:
1141 OS <<
"<smtvtype: ";
1142 OS << SMTVTypeModeToString(getSMTVType());
1150 case KindTy::RegList:
1155 case KindTy::StackAdj:
1156 OS <<
"<stackadj: ";
1160 case KindTy::RegReg:
1161 OS <<
"<RegReg: BaseReg " <<
RegName(
RegReg.BaseReg) <<
" OffsetReg "
1167 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1168 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1175 static std::unique_ptr<RISCVOperand>
1176 createReg(MCRegister
Reg, SMLoc S, SMLoc
E,
bool IsGPRAsFPR =
false) {
1177 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1179 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1185 static std::unique_ptr<RISCVOperand> createExpr(
const MCExpr *Val, SMLoc S,
1186 SMLoc
E,
bool IsRV64) {
1187 auto Op = std::make_unique<RISCVOperand>(KindTy::Expression);
1188 Op->Expr.Expr = Val;
1189 Op->Expr.IsRV64 = IsRV64;
1195 static std::unique_ptr<RISCVOperand> createFPImm(
uint64_t Val, SMLoc S) {
1196 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1197 Op->FPImm.Val = Val;
1203 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1204 unsigned Encoding) {
1205 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1206 Op->SysReg.Data = Str.data();
1207 Op->SysReg.Length = Str.size();
1214 static std::unique_ptr<RISCVOperand>
1216 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1223 static std::unique_ptr<RISCVOperand>
1225 auto Op = std::make_unique<RISCVOperand>(KindTy::SMTVType);
1226 Op->SMTVType.SMTVType = VType;
1232 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val, SMLoc S) {
1233 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1234 Op->Fence.Val = Val;
1240 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI, SMLoc S) {
1241 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1242 Op->VType.Val = VTypeI;
1248 static std::unique_ptr<RISCVOperand> createRegList(
unsigned RlistEncode,
1250 auto Op = std::make_unique<RISCVOperand>(KindTy::RegList);
1256 static std::unique_ptr<RISCVOperand>
1257 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {
1258 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1260 Op->RegReg.OffsetReg = OffsetReg;
1266 static std::unique_ptr<RISCVOperand> createStackAdj(
unsigned StackAdj, SMLoc S) {
1267 auto Op = std::make_unique<RISCVOperand>(KindTy::StackAdj);
1268 Op->StackAdj.Val = StackAdj;
1273 static void addExpr(MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1274 assert(Expr &&
"Expr shouldn't be null!");
1286 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1287 assert(
N == 1 &&
"Invalid number of operands!");
1291 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1292 assert(
N == 1 &&
"Invalid number of operands!");
1293 addExpr(Inst,
getExpr(), isRV64Expr());
1296 template <
unsigned Bits>
1297 void addSExtImmOperands(MCInst &Inst,
unsigned N)
const {
1298 assert(
N == 1 &&
"Invalid number of operands!");
1305 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
1306 assert(
N == 1 &&
"Invalid number of operands!");
1308 addExpr(Inst,
getExpr(), isRV64Expr());
1313 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1317 void addFenceArgOperands(MCInst &Inst,
unsigned N)
const {
1318 assert(
N == 1 &&
"Invalid number of operands!");
1322 void addCSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
1323 assert(
N == 1 &&
"Invalid number of operands!");
1330 void addVTypeIOperands(MCInst &Inst,
unsigned N)
const {
1331 assert(
N == 1 &&
"Invalid number of operands!");
1333 if (Kind == KindTy::Expression) {
1334 [[maybe_unused]]
bool IsConstantImm =
1336 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1343 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1344 assert(
N == 1 &&
"Invalid number of operands!");
1348 void addRegRegOperands(MCInst &Inst,
unsigned N)
const {
1349 assert(
N == 2 &&
"Invalid number of operands!");
1354 void addStackAdjOperands(MCInst &Inst,
unsigned N)
const {
1355 assert(
N == 1 &&
"Invalid number of operands!");
1359 void addFRMArgOperands(MCInst &Inst,
unsigned N)
const {
1360 assert(
N == 1 &&
"Invalid number of operands!");
1364 void addSMTVTypeOperand(MCInst &Inst,
unsigned N)
const {
1365 assert(
N == 1 &&
"Invalid number of operands!");
1371#define GET_REGISTER_MATCHER
1372#define GET_SUBTARGET_FEATURE_NAME
1373#define GET_MATCHER_IMPLEMENTATION
1374#define GET_MNEMONIC_SPELL_CHECKER
1375#include "RISCVGenAsmMatcher.inc"
1378 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1379 return Reg - RISCV::F0_D + RISCV::F0_H;
1383 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1384 return Reg - RISCV::F0_D + RISCV::F0_F;
1388 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1389 return Reg - RISCV::F0_D + RISCV::F0_Q;
1393 assert(
Reg >= RISCV::X0 &&
Reg <= RISCV::X31 &&
"Invalid register");
1394 return Reg - RISCV::X0 + RISCV::X0_Y;
1399 unsigned RegClassID;
1400 if (Kind == MCK_VRM2)
1401 RegClassID = RISCV::VRM2RegClassID;
1402 else if (Kind == MCK_VRM4)
1403 RegClassID = RISCV::VRM4RegClassID;
1404 else if (Kind == MCK_VRM8)
1405 RegClassID = RISCV::VRM8RegClassID;
1409 &getRISCVMCRegisterClass(RegClassID));
1413 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1414 return Reg - RISCV::F0_D + RISCV::F0_Q2;
1419 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1421 return Match_InvalidOperand;
1423 MCRegister
Reg =
Op.getReg();
1425 getRISCVMCRegisterClass(RISCV::FPR64RegClassID).contains(
Reg);
1427 getRISCVMCRegisterClass(RISCV::FPR64CRegClassID).contains(
Reg);
1428 bool IsRegVR = getRISCVMCRegisterClass(RISCV::VRRegClassID).contains(
Reg);
1430 if (
Op.isGPR() && Kind == MCK_YGPR) {
1433 return Match_Success;
1435 if (IsRegFPR64 && Kind == MCK_FPR256) {
1437 return Match_Success;
1439 if (IsRegFPR64 && Kind == MCK_FPR128) {
1441 return Match_Success;
1445 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1446 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1448 return Match_Success;
1452 if (IsRegFPR64 && Kind == MCK_FPR16) {
1454 return Match_Success;
1456 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1457 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_H;
1458 return Match_Success;
1460 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1461 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_W;
1462 return Match_Success;
1469 if (getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg) &&
1470 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1472 return Match_Success;
1476 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1479 return Match_InvalidOperand;
1480 return Match_Success;
1482 return Match_InvalidOperand;
1485bool RISCVAsmParser::generateImmOutOfRangeError(
1486 SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
1487 const Twine &
Msg =
"immediate must be an integer in the range") {
1494std::string RISCVAsmParser::getCustomOperandDiag(
unsigned MatchError) {
1496 StringRef
Msg =
"immediate must be an integer in the range") {
1497 return (
Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]").str();
1500 switch (MatchError) {
1504 if (
const char *Diag = getMatchKindDiag((RISCVMatchResultTy)MatchError))
1506 return std::string();
1507 case Match_InvalidImmXLenLI:
1509 return "operand must be a constant 64-bit integer";
1510 return Range(std::numeric_limits<int32_t>::min(),
1511 std::numeric_limits<uint32_t>::max());
1512 case Match_InvalidImmXLenLI_Restricted:
1514 return "operand either must be a constant 64-bit integer "
1515 "or a bare symbol name";
1516 return Range(std::numeric_limits<int32_t>::min(),
1517 std::numeric_limits<uint32_t>::max(),
1518 "operand either must be a bare symbol name or an immediate "
1519 "integer in the range");
1520 case Match_InvalidUImmLog2XLen:
1522 return Range(0, (1 << 6) - 1);
1523 return Range(0, (1 << 5) - 1);
1524 case Match_InvalidUImmLog2XLenNonZero:
1526 return Range(1, (1 << 6) - 1);
1527 return Range(1, (1 << 5) - 1);
1528 case Match_InvalidUImm1:
1529 return Range(0, (1 << 1) - 1);
1530 case Match_InvalidUImm2:
1531 return Range(0, (1 << 2) - 1);
1532 case Match_InvalidUImm2Lsb0:
1533 return Range(0, 2,
"immediate must be one of");
1534 case Match_InvalidUImm3:
1535 return Range(0, (1 << 3) - 1);
1536 case Match_InvalidUImm4:
1537 return Range(0, (1 << 4) - 1);
1538 case Match_InvalidUImm4Plus1:
1539 return Range(1, (1 << 4));
1540 case Match_InvalidUImm5:
1541 return Range(0, (1 << 5) - 1);
1542 case Match_InvalidUImm5NonZero:
1543 return Range(1, (1 << 5) - 1);
1544 case Match_InvalidUImm5GT3:
1545 return Range(4, (1 << 5) - 1);
1546 case Match_InvalidUImm5Plus1:
1547 return Range(1, (1 << 5));
1548 case Match_InvalidUImm5GE6Plus1:
1549 return Range(6, (1 << 5));
1550 case Match_InvalidUImm5Slist:
1551 return "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31";
1552 case Match_InvalidUImm6:
1553 return Range(0, (1 << 6) - 1);
1554 case Match_InvalidUImm6Plus1:
1555 return Range(1, (1 << 6));
1556 case Match_InvalidUImm7:
1557 return Range(0, (1 << 7) - 1);
1558 case Match_InvalidUImm8:
1559 return Range(0, (1 << 8) - 1);
1560 case Match_InvalidUImm8GE32:
1561 return Range(32, (1 << 8) - 1);
1562 case Match_InvalidSImm5:
1563 return Range(-(1 << 4), (1 << 4) - 1);
1564 case Match_InvalidSImm5NonZero:
1565 return Range(-(1 << 4), (1 << 4) - 1,
1566 "immediate must be non-zero in the range");
1567 case Match_InvalidSImm6:
1568 return Range(-(1 << 5), (1 << 5) - 1);
1569 case Match_InvalidSImm6NonZero:
1570 return Range(-(1 << 5), (1 << 5) - 1,
1571 "immediate must be non-zero in the range");
1572 case Match_InvalidCLUIImm:
1573 return Range(1, (1 << 5) - 1,
"immediate must be in [0xfffe0, 0xfffff] or");
1574 case Match_InvalidUImm5Lsb0:
1575 return Range(0, (1 << 5) - 2,
1576 "immediate must be a multiple of 2 bytes in the range");
1577 case Match_InvalidUImm6Lsb0:
1578 return Range(0, (1 << 6) - 2,
1579 "immediate must be a multiple of 2 bytes in the range");
1580 case Match_InvalidUImm6Lsb000:
1581 return Range(0, (1 << 6) - 8,
1582 "immediate must be a multiple of 8 in the range");
1583 case Match_InvalidUImm7Lsb00:
1584 return Range(0, (1 << 7) - 4,
1585 "immediate must be a multiple of 4 bytes in the range");
1586 case Match_InvalidUImm8Lsb00:
1587 return Range(0, (1 << 8) - 4,
1588 "immediate must be a multiple of 4 bytes in the range");
1589 case Match_InvalidUImm8Lsb000:
1590 return Range(0, (1 << 8) - 8,
1591 "immediate must be a multiple of 8 bytes in the range");
1592 case Match_InvalidUImm9:
1593 return Range(0, (1 << 9) - 1,
"immediate offset must be in the range");
1594 case Match_InvalidBareSImm9Lsb0:
1595 return Range(-(1 << 8), (1 << 8) - 2,
1596 "immediate must be a multiple of 2 bytes in the range");
1597 case Match_InvalidUImm9Lsb000:
1598 return Range(0, (1 << 9) - 8,
1599 "immediate must be a multiple of 8 bytes in the range");
1600 case Match_InvalidSImm8PLI_B:
1601 return Range(-(1 << 7), (1 << 8) - 1);
1602 case Match_InvalidSImm10:
1603 case Match_InvalidSImm10PLI_H:
1604 case Match_InvalidSImm10PLI_W:
1605 return Range(-(1 << 9), (1 << 9) - 1);
1606 case Match_InvalidSImm10PLUI:
1607 return Range(-(1 << 9), (1 << 10) - 1);
1608 case Match_InvalidUImm10Lsb00NonZero:
1609 return Range(4, (1 << 10) - 4,
1610 "immediate must be a multiple of 4 bytes in the range");
1611 case Match_InvalidSImm10Lsb0000NonZero:
1613 -(1 << 9), (1 << 9) - 16,
1614 "immediate must be a multiple of 16 bytes and non-zero in the range");
1615 case Match_InvalidSImm11:
1616 return Range(-(1 << 10), (1 << 10) - 1);
1617 case Match_InvalidBareSImm11Lsb0:
1618 return Range(-(1 << 10), (1 << 10) - 2,
1619 "immediate must be a multiple of 2 bytes in the range");
1620 case Match_InvalidUImm10:
1621 return Range(0, (1 << 10) - 1);
1622 case Match_InvalidUImm11:
1623 return Range(0, (1 << 11) - 1);
1624 case Match_InvalidUImm14Lsb00:
1625 return Range(0, (1 << 14) - 4,
1626 "immediate must be a multiple of 4 bytes in the range");
1627 case Match_InvalidUImm16NonZero:
1628 return Range(1, (1 << 16) - 1);
1629 case Match_InvalidSImm12:
1630 return Range(-(1 << 11), (1 << 11) - 1);
1631 case Match_InvalidSImm12LO:
1632 return Range(-(1 << 11), (1 << 11) - 1,
1633 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo "
1634 "specifier or an integer in the range");
1635 case Match_InvalidBareSImm12Lsb0:
1636 return Range(-(1 << 11), (1 << 11) - 2,
1637 "immediate must be a multiple of 2 bytes in the range");
1638 case Match_InvalidSImm12Lsb00000:
1639 return Range(-(1 << 11), (1 << 11) - 32,
1640 "immediate must be a multiple of 32 bytes in the range");
1641 case Match_InvalidBareSImm13Lsb0:
1642 return Range(-(1 << 12), (1 << 12) - 2,
1643 "immediate must be a multiple of 2 bytes in the range");
1644 case Match_InvalidSImm16:
1645 return Range(-(1 << 15), (1 << 15) - 1);
1646 case Match_InvalidSImm16NonZero:
1647 return Range(-(1 << 15), (1 << 15) - 1,
1648 "immediate must be non-zero in the range");
1649 case Match_InvalidSImm20LI:
1650 return Range(-(1 << 19), (1 << 19) - 1,
1651 "operand must be a symbol with a %qc.abs20 specifier or an "
1652 "integer in the range");
1653 case Match_InvalidUImm20LUI:
1654 return Range(0, (1 << 20) - 1,
1655 "operand must be a symbol with %hi/%tprel_hi specifier or an "
1656 "integer in the range");
1657 case Match_InvalidUImm20:
1658 return Range(0, (1 << 20) - 1);
1659 case Match_InvalidUImm20AUIPC:
1662 "operand must be a symbol with a "
1663 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
1664 "or an integer in the range");
1665 case Match_InvalidBareSImm21Lsb0:
1666 return Range(-(1 << 20), (1 << 20) - 2,
1667 "immediate must be a multiple of 2 bytes in the range");
1668 case Match_InvalidCSRSystemRegister:
1669 return Range(0, (1 << 12) - 1,
1670 "operand must be a valid system register name or an integer "
1672 case Match_InvalidImm5Zibi:
1673 return Range(-1, (1 << 5) - 1,
"immediate must be non-zero in the range");
1674 case Match_InvalidVTypeI:
1675 return "operand must be "
1676 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]";
1677 case Match_InvalidSImm5Plus1:
1678 return Range(-(1 << 4) + 1, (1 << 4),
"immediate must be in the range");
1679 case Match_InvalidSImm18:
1680 return Range(-(1 << 17), (1 << 17) - 1);
1681 case Match_InvalidSImm18Lsb0:
1682 return Range(-(1 << 17), (1 << 17) - 2,
1683 "immediate must be a multiple of 2 bytes in the range");
1684 case Match_InvalidSImm19Lsb00:
1685 return Range(-(1 << 18), (1 << 18) - 4,
1686 "immediate must be a multiple of 4 bytes in the range");
1687 case Match_InvalidSImm20Lsb000:
1688 return Range(-(1 << 19), (1 << 19) - 8,
1689 "immediate must be a multiple of 8 bytes in the range");
1690 case Match_InvalidSImm26:
1691 return Range(-(1 << 25), (1 << 25) - 1);
1693 case Match_InvalidBareSymbolQC_E_LI:
1696 case Match_InvalidBareSImm32:
1697 return Range(std::numeric_limits<int32_t>::min(),
1698 std::numeric_limits<uint32_t>::max());
1699 case Match_InvalidBareSImm32Lsb0:
1700 return Range(std::numeric_limits<int32_t>::min(),
1701 std::numeric_limits<int32_t>::max() - 1,
1702 "operand must be a multiple of 2 bytes in the range");
1703 case Match_InvalidRnumArg:
1704 return Range(0, 10);
1705 case Match_InvalidStackAdj:
1706 return "stack adjustment is invalid for this instruction and register "
1708 case Match_InvalidYBNDSWImm:
1709 return "immediate must be an integer in the range "
1710 "[1, 255], a multiple of 8 in the range [256, 504], "
1711 "or a multiple of 16 in the range [512, 4096]";
1712 case Match_InvalidUImm7EqXLen:
1713 return (
"immediate must be an integer equal to XLEN (" +
1714 Twine(isRV64() ?
"64" :
"32") +
")")
1722void RISCVAsmParser::FilterNearMisses(
1723 SmallVectorImpl<NearMissInfo> &NearMissesIn,
1724 SmallVectorImpl<NearMissMessage> &NearMissesOut, SMLoc IDLoc,
1728 std::multimap<unsigned, unsigned> OperandMissesSeen;
1729 SmallSet<FeatureBitset, 4> FeatureMissesSeen;
1730 bool ReportedTooFewOperands =
false;
1731 bool ReportedTooManyOperands =
false;
1733 for (NearMissInfo &
I : NearMissesIn) {
1734 switch (
I.getKind()) {
1737 ((RISCVOperand &)*
Operands[
I.getOperandIndex()]).getStartLoc();
1742 if (
I.getOperandClass() == InvalidMatchClass) {
1743 if (!ReportedTooManyOperands) {
1745 OperandLoc,
"unexpected extra operand for instruction"});
1746 ReportedTooManyOperands =
true;
1751 std::string OperandDiag = getCustomOperandDiag(
I.getOperandError());
1755 unsigned DupCheckMatchClass =
1756 OperandDiag.empty() ? ~0
U :
I.getOperandClass();
1757 auto PrevReports = OperandMissesSeen.equal_range(
I.getOperandIndex());
1759 PrevReports.first, PrevReports.second,
1760 [DupCheckMatchClass](
const std::pair<unsigned, unsigned> Pair) {
1761 if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
1762 return Pair.second == DupCheckMatchClass;
1763 return isSubclass((MatchClassKind)DupCheckMatchClass,
1764 (MatchClassKind)Pair.second);
1767 OperandMissesSeen.insert(
1768 std::make_pair(
I.getOperandIndex(), DupCheckMatchClass));
1770 NearMissMessage Message;
1771 Message.Loc = OperandLoc;
1772 if (!OperandDiag.empty()) {
1773 Message.Message = OperandDiag;
1775 Message.Message =
"invalid operand for instruction";
1777 dbgs() <<
"Missing diagnostic string for operand class "
1778 << getMatchClassName((MatchClassKind)
I.getOperandClass())
1779 <<
I.getOperandClass() <<
", error " <<
I.getOperandError()
1780 <<
", opcode " << MII.
getName(
I.getOpcode()) <<
"\n");
1786 const FeatureBitset &MissingFeatures =
I.getFeatures();
1788 if (!FeatureMissesSeen.
insert(MissingFeatures).second)
1791 NearMissMessage Message;
1792 Message.Loc = IDLoc;
1793 bool FirstFeature =
true;
1794 Message.Message =
"instruction requires the following:";
1795 for (
unsigned Feature : MissingFeatures) {
1796 Message.Message += FirstFeature ?
" " :
", ";
1798 FirstFeature =
false;
1808 if (!ReportedTooFewOperands) {
1809 SMLoc EndLoc = ((RISCVOperand &)*
Operands.back()).getEndLoc();
1811 NearMissMessage{EndLoc,
"too few operands for instruction"});
1812 ReportedTooFewOperands =
true;
1824void RISCVAsmParser::ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses,
1827 FilterNearMisses(NearMisses, Messages, IDLoc,
Operands);
1832 Error(IDLoc,
"invalid instruction");
1835 Error(Messages[0].Loc, Messages[0].Message);
1840 "invalid instruction, any one of the following would fix this:");
1841 for (
auto &M : Messages)
1846bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1850 bool MatchingInlineAsm) {
1855 MatchInstructionImpl(
Operands, Inst, &NearMisses, MatchingInlineAsm);
1860 if (validateInstruction(Inst,
Operands))
1862 return processInstruction(Inst, IDLoc,
Operands, Out);
1863 case Match_MnemonicFail: {
1864 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1865 std::string Suggestion = RISCVMnemonicSpellCheck(
1867 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1869 case Match_NearMisses:
1870 ReportNearMisses(NearMisses, IDLoc,
Operands);
1881MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name)
const {
1890 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1891 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1892 static_assert(RISCV::F0_D < RISCV::F0_Q,
"FPR matching must be updated");
1895 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1900bool RISCVAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1902 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1903 return Error(StartLoc,
"invalid register name");
1907ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1909 const AsmToken &Tok = getParser().getTok();
1912 StringRef
Name = getLexer().getTok().getIdentifier();
1924 SMLoc FirstS = getLoc();
1925 bool HadParens =
false;
1932 size_t ReadCount = getLexer().peekTokens(Buf);
1935 LParen = getParser().getTok();
1940 switch (getLexer().getKind()) {
1943 getLexer().UnLex(LParen);
1946 StringRef
Name = getLexer().getTok().getIdentifier();
1951 getLexer().UnLex(LParen);
1955 Operands.push_back(RISCVOperand::createToken(
"(", FirstS));
1957 SMLoc
E = getTok().getEndLoc();
1959 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
1964 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
1975 switch (getLexer().getKind()) {
1985 if (getParser().parseExpression(Res,
E))
1990 int64_t
Imm =
CE->getValue();
1992 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2001 if (getParser().parseIdentifier(Identifier))
2004 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
2007 "Unexpected opcode");
2010 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2020 return generateImmOutOfRangeError(
2022 "opcode must be a valid opcode name or an immediate in the range");
2030 switch (getLexer().getKind()) {
2040 if (getParser().parseExpression(Res,
E))
2045 int64_t
Imm =
CE->getValue();
2046 if (
Imm >= 0 &&
Imm <= 2) {
2047 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2056 if (getParser().parseIdentifier(Identifier))
2060 if (Identifier ==
"C0")
2062 else if (Identifier ==
"C1")
2064 else if (Identifier ==
"C2")
2071 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2080 return generateImmOutOfRangeError(
2082 "opcode must be a valid opcode name or an immediate in the range");
2089 auto SysRegFromConstantInt = [
this](
const MCExpr *
E, SMLoc S) {
2091 int64_t
Imm =
CE->getValue();
2093 auto Range = RISCVSysReg::lookupSysRegByEncoding(
Imm);
2097 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2100 return RISCVOperand::createSysReg(
2101 RISCVSysReg::getSysRegStr(
Reg.Name), S,
Imm);
2105 return RISCVOperand::createSysReg(
"", S,
Imm);
2108 return std::unique_ptr<RISCVOperand>();
2111 switch (getLexer().getKind()) {
2121 if (getParser().parseExpression(Res))
2124 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
2125 Operands.push_back(std::move(SysOpnd));
2129 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2133 if (getParser().parseIdentifier(Identifier))
2136 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
2139 if (SysReg->IsDeprecatedName) {
2141 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
2143 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2145 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
2146 RISCVSysReg::getSysRegStr(
Reg.Name) +
"'");
2151 const auto &FeatureBits = getSTI().getFeatureBits();
2152 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
2153 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
2154 const auto *Feature =
2156 return SysReg->FeaturesRequired[Feature.Value];
2158 std::string ErrorMsg =
2159 std::string(
"system register '") +
2160 std::string(RISCVSysReg::getSysRegStr(SysReg->Name)) +
"' ";
2161 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
2162 ErrorMsg +=
"is RV32 only";
2164 ErrorMsg +=
" and ";
2168 "requires '" + std::string(Feature->key()) +
"' to be enabled";
2171 return Error(S, ErrorMsg);
2174 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
2184 Operands.push_back(std::move(SysOpnd));
2189 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2190 "operand must be a valid system register "
2191 "name or an integer in the range");
2195 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2207 StringRef
Identifier = getTok().getIdentifier();
2208 if (
Identifier.compare_insensitive(
"inf") == 0) {
2211 getTok().getEndLoc(), isRV64()));
2212 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2215 getTok().getEndLoc(), isRV64()));
2216 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2219 getTok().getEndLoc(), isRV64()));
2221 return TokError(
"invalid floating point literal");
2232 const AsmToken &Tok = getTok();
2234 return TokError(
"invalid floating point immediate");
2237 APFloat RealVal(APFloat::IEEEdouble());
2239 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2241 return TokError(
"invalid floating point representation");
2244 RealVal.changeSign();
2246 Operands.push_back(RISCVOperand::createFPImm(
2247 RealVal.bitcastToAPInt().getZExtValue(), S));
2259 switch (getLexer().getKind()) {
2271 if (getParser().parseExpression(Res,
E))
2275 return parseOperandWithSpecifier(
Operands);
2278 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2288 const MCExpr *Expr =
nullptr;
2289 bool Failed = parseExprWithSpecifier(Expr,
E);
2291 Operands.push_back(RISCVOperand::createExpr(Expr, S,
E, isRV64()));
2295bool RISCVAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
2296 SMLoc Loc = getLoc();
2298 return TokError(
"expected '%' relocation specifier");
2299 StringRef
Identifier = getParser().getTok().getIdentifier();
2302 return TokError(
"invalid relocation specifier");
2308 const MCExpr *SubExpr;
2309 if (getParser().parseParenExpression(SubExpr,
E))
2316bool RISCVAsmParser::parseDataExpr(
const MCExpr *&Res) {
2319 return parseExprWithSpecifier(Res,
E);
2320 return getParser().parseExpression(Res);
2330 StringRef
Identifier = getTok().getIdentifier();
2340 if (getParser().parseExpression(Res,
E))
2343 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2353 std::string
Identifier(getTok().getIdentifier());
2359 SMLoc Loc = getLoc();
2360 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2361 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2375 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2387 std::string
Identifier(getTok().getIdentifier());
2393 SMLoc Loc = getLoc();
2394 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2395 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2409 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2418 if (getParser().parseExpression(Res,
E))
2421 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef)
2422 return Error(S,
"operand must be a valid jump target");
2425 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2446bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2447 unsigned &Sew,
unsigned &Lmul,
2448 bool &Fractional,
bool &TailAgnostic,
2449 bool &MaskAgnostic,
bool &AltFmt) {
2454 if (State < VTypeState::SeenSew &&
Identifier.consume_front(
"e")) {
2456 if (Identifier ==
"16alt") {
2459 }
else if (Identifier ==
"8alt") {
2469 State = VTypeState::SeenSew;
2473 if (State < VTypeState::SeenLmul &&
Identifier.consume_front(
"m")) {
2476 if (Identifier ==
"a" || Identifier ==
"u") {
2478 State = VTypeState::SeenMaskPolicy;
2489 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2490 unsigned MinLMUL = ELEN / 8;
2493 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2494 Twine(MinLMUL) +
" is reserved");
2497 State = VTypeState::SeenLmul;
2501 if (State < VTypeState::SeenTailPolicy &&
Identifier.starts_with(
"t")) {
2502 if (Identifier ==
"ta")
2503 TailAgnostic =
true;
2504 else if (Identifier ==
"tu")
2505 TailAgnostic =
false;
2509 State = VTypeState::SeenTailPolicy;
2513 if (State < VTypeState::SeenMaskPolicy &&
Identifier.starts_with(
"m")) {
2514 if (Identifier ==
"ma")
2515 MaskAgnostic =
true;
2516 else if (Identifier ==
"mu")
2517 MaskAgnostic =
false;
2521 State = VTypeState::SeenMaskPolicy;
2534 bool Fractional =
false;
2535 bool TailAgnostic =
false;
2536 bool MaskAgnostic =
false;
2539 VTypeState State = VTypeState::SeenNothingYet;
2541 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2542 MaskAgnostic, AltFmt)) {
2544 if (State == VTypeState::SeenNothingYet)
2553 State == VTypeState::SeenNothingYet)
2554 return generateVTypeError(S);
2558 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2559 unsigned MaxSEW = ELEN / Lmul;
2561 if (MaxSEW >= 8 && Sew > MaxSEW)
2562 Warning(S,
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2563 " and LMUL == mf" + Twine(Lmul) +
2564 " may not be compatible with all RVV implementations");
2569 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2573bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2574 return Error(ErrorLoc,
2576 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2596 if (Identifier !=
"16alt")
2625 Operands.push_back(RISCVOperand::createVType(
2631 return generateXSfmmVTypeError(S);
2634bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
2635 return Error(ErrorLoc,
"operand must be e[8|16|16alt|32|64],w[1|2|4]");
2642 StringRef
Name = getLexer().getTok().getIdentifier();
2643 if (!
Name.consume_back(
".t")) {
2647 return Error(getLoc(),
"expected '.t' suffix");
2654 if (
Reg != RISCV::V0)
2657 SMLoc
E = getTok().getEndLoc();
2659 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2667 StringRef
Name = getLexer().getTok().getIdentifier();
2668 if (!
Name.consume_back(
".scale"))
2669 return Error(getLoc(),
"expected '.scale' suffix");
2674 if (
Reg != RISCV::V0)
2677 SMLoc
E = getTok().getEndLoc();
2679 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2688 StringRef
Name = getLexer().getTok().getIdentifier();
2689 if (!
Name.consume_front(
"L") && !
Name.consume_front(
"l"))
2694 return Error(S,
"operand must be L1, L2, L4, L8, L16, L32, or L64");
2696 unsigned EncodedLambda =
Log2_32(Lambda) + 1;
2698 SMLoc
E = getTok().getEndLoc();
2700 Operands.push_back(RISCVOperand::createExpr(
2706 if (!isRV64() || getSTI().
hasFeature(RISCV::FeatureStdExtF))
2716 StringRef
Name = getLexer().getTok().getIdentifier();
2722 SMLoc
E = getTok().getEndLoc();
2724 Operands.push_back(RISCVOperand::createReg(
2730 if (isRV64() || getSTI().
hasFeature(RISCV::FeatureStdExtF))
2736 StringRef
Name = getLexer().getTok().getIdentifier();
2742 if (!getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg))
2745 if ((
Reg - RISCV::X0) & 1) {
2748 if (getSTI().
hasFeature(RISCV::FeatureStdExtZfinx))
2749 return TokError(
"double precision floating point operands must use even "
2750 "numbered X register");
2755 SMLoc
E = getTok().getEndLoc();
2758 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2760 Reg, RISCV::sub_gpr_even,
2761 &getRISCVMCRegisterClass(RISCV::GPRPairRegClassID));
2762 Operands.push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2766template <
bool IsRV64>
2768 return parseGPRPair(
Operands, IsRV64);
2778 if (!IsRV64Inst && isRV64())
2784 StringRef
Name = getLexer().getTok().getIdentifier();
2790 if (!getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg))
2793 if ((
Reg - RISCV::X0) & 1)
2794 return TokError(
"register must be even");
2797 SMLoc
E = getTok().getEndLoc();
2800 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2802 Reg, RISCV::sub_gpr_even,
2803 &getRISCVMCRegisterClass(RISCV::GPRPairRegClassID));
2804 Operands.push_back(RISCVOperand::createReg(Pair, S,
E));
2811 "operand must be a valid SpacemiT's Integer Matrix VType mnemonic");
2813 StringRef Str = getLexer().getTok().getIdentifier();
2816 if (!isValidSMTVTypeMode(VType))
2817 return TokError(
"SpacemiT's Integer Matrix only supports [i4|i8] mode");
2819 Operands.push_back(RISCVOperand::createSMTVType(VType, getLoc()));
2827 "operand must be a valid floating point rounding mode mnemonic");
2829 StringRef Str = getLexer().getTok().getIdentifier();
2834 "operand must be a valid floating point rounding mode mnemonic");
2836 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2841std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultSMTVType() {
2842 return RISCVOperand::createSMTVType(XSMTVTypeMode::SMTVTypeMode::SMT_I8,
2847 const AsmToken &Tok = getLexer().getTok();
2853 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2867 for (
char c : Str) {
2896 Operands.push_back(RISCVOperand::createFenceArg(
Imm, getLoc()));
2902 return TokError(
"operand must be formed of letters selected in-order from "
2909 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
2911 if (!parseRegister(
Operands).isSuccess())
2912 return Error(getLoc(),
"expected register");
2916 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2940 std::unique_ptr<RISCVOperand> OptionalImmOp;
2947 SMLoc ImmStart = getLoc();
2948 if (getParser().parseIntToken(ImmVal,
2949 "expected '(' or optional integer offset"))
2954 SMLoc ImmEnd = getLoc();
2957 ImmStart, ImmEnd, isRV64());
2961 OptionalImmOp ?
"expected '(' after optional integer offset"
2962 :
"expected '(' or optional integer offset"))
2965 if (!parseRegister(
Operands).isSuccess())
2966 return Error(getLoc(),
"expected register");
2972 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2974 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2975 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2986 StringRef OffsetRegName = getLexer().getTok().getIdentifier();
2989 !getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(OffsetReg))
2990 return Error(getLoc(),
"expected GPR register");
2997 return Error(getLoc(),
"expected GPR register");
2999 StringRef BaseRegName = getLexer().getTok().getIdentifier();
3002 !getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(BaseReg))
3003 return Error(getLoc(),
"expected GPR register");
3009 Operands.push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));
3022 bool MustIncludeS0) {
3034 return Error(getLoc(),
"invalid register");
3036 StringRef
RegName = getTok().getIdentifier();
3039 return Error(getLoc(),
"invalid register");
3042 UsesXRegs =
RegName[0] ==
'x';
3043 if (
Reg != RISCV::X1)
3044 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
3045 }
else if (RegEnd == RISCV::X1) {
3046 if (
Reg != RISCV::X8 || (UsesXRegs != (
RegName[0] ==
'x')))
3047 return Error(getLoc(), Twine(
"register must be '") +
3048 (UsesXRegs ?
"x8" :
"s0") +
"'");
3049 }
else if (RegEnd == RISCV::X9 && UsesXRegs) {
3050 if (
Reg != RISCV::X18 || (
RegName[0] !=
'x'))
3051 return Error(getLoc(),
"register must be 'x18'");
3053 return Error(getLoc(),
"too many register ranges");
3060 SMLoc MinusLoc = getLoc();
3062 if (RegEnd == RISCV::X1)
3063 return Error(MinusLoc, Twine(
"register '") + (UsesXRegs ?
"x1" :
"ra") +
3064 "' cannot start a multiple register range");
3067 return Error(getLoc(),
"invalid register");
3069 StringRef
RegName = getTok().getIdentifier();
3072 return Error(getLoc(),
"invalid register");
3074 if (RegEnd == RISCV::X8) {
3075 if ((
Reg != RISCV::X9 &&
3077 (UsesXRegs != (
RegName[0] ==
'x'))) {
3079 return Error(getLoc(),
"register must be 'x9'");
3080 return Error(getLoc(),
"register must be in the range 's1' to 's11'");
3082 }
else if (RegEnd == RISCV::X18) {
3084 return Error(getLoc(),
3085 "register must be in the range 'x19' to 'x27'");
3098 if (RegEnd == RISCV::X26)
3099 return Error(S,
"invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "
3100 "x18-x26}' is not supported");
3106 return Error(S,
"register list must include 's0' or 'x8'");
3108 Operands.push_back(RISCVOperand::createRegList(Encode, S));
3114 bool ExpectNegative) {
3123 auto *RegListOp =
static_cast<RISCVOperand *
>(
Operands.back().
get());
3124 if (!RegListOp->isRegList())
3127 unsigned RlistEncode = RegListOp->RegList.Encoding;
3131 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||
3132 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {
3133 int64_t
Lower = StackAdjBase;
3134 int64_t
Upper = StackAdjBase + 48;
3135 if (ExpectNegative) {
3140 return generateImmOutOfRangeError(S,
Lower,
Upper,
3141 "stack adjustment for register list must "
3142 "be a multiple of 16 bytes in the range");
3146 Operands.push_back(RISCVOperand::createStackAdj(StackAdj, S));
3158 MatchOperandParserImpl(
Operands, Mnemonic,
true);
3165 if (parseRegister(
Operands,
true).isSuccess())
3169 if (parseExpression(
Operands).isSuccess()) {
3172 return !parseMemOpBaseReg(
Operands).isSuccess();
3177 Error(getLoc(),
"unknown operand");
3181bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &Info,
3182 StringRef Name, SMLoc NameLoc,
3188 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
3192 Operands.push_back(RISCVOperand::createToken(Name, NameLoc));
3211 if (getParser().parseEOL(
"unexpected token")) {
3212 getParser().eatToEndOfStatement();
3218bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
3222 Kind = RE->getSpecifier();
3223 Expr = RE->getSubExpr();
3232bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
3241ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
3242 StringRef IDVal = DirectiveID.
getString();
3244 if (IDVal ==
".option")
3245 return parseDirectiveOption();
3246 if (IDVal ==
".attribute")
3247 return parseDirectiveAttribute();
3248 if (IDVal ==
".insn")
3249 return parseDirectiveInsn(DirectiveID.
getLoc());
3250 if (IDVal ==
".variant_cc")
3251 return parseDirectiveVariantCC();
3256bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
3257 bool FromOptionDirective) {
3258 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
3261 clearFeatureBits(Feature.Value, Feature.key());
3268 raw_string_ostream OutputErrMsg(Buffer);
3269 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3270 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
3271 << ErrMsg.getMessage();
3274 return Error(Loc, OutputErrMsg.str());
3276 auto &ISAInfo = *ParseResult;
3279 if (ISAInfo->hasExtension(Feature.key()))
3280 setFeatureBits(Feature.Value, Feature.key());
3282 if (FromOptionDirective) {
3283 if (ISAInfo->getXLen() == 32 && isRV64())
3284 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3285 else if (ISAInfo->getXLen() == 64 && !isRV64())
3286 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3289 if (ISAInfo->getXLen() == 32)
3290 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
3291 else if (ISAInfo->getXLen() == 64)
3292 setFeatureBits(RISCV::Feature64Bit,
"64bit");
3294 return Error(Loc,
"bad arch string " + Arch);
3296 Result = ISAInfo->toString();
3300bool RISCVAsmParser::parseDirectiveOption() {
3301 MCAsmParser &Parser = getParser();
3303 AsmToken Tok = Parser.
getTok();
3311 if (Option ==
"push") {
3315 getTargetStreamer().emitDirectiveOptionPush();
3320 if (Option ==
"pop") {
3325 getTargetStreamer().emitDirectiveOptionPop();
3326 if (popFeatureBits())
3327 return Error(StartLoc,
".option pop with no .option push");
3332 if (Option ==
"arch") {
3340 Type = RISCVOptionArchArgType::Plus;
3342 Type = RISCVOptionArchArgType::Minus;
3343 else if (!
Args.empty())
3345 "unexpected token, expected + or -");
3347 Type = RISCVOptionArchArgType::Full;
3351 "unexpected token, expected identifier");
3357 if (
Type == RISCVOptionArchArgType::Full) {
3359 if (resetToArch(Arch, Loc, Result,
true))
3368 Loc,
"extension version number parsing not currently implemented");
3371 if (!enableExperimentalExtension() &&
3373 return Error(Loc,
"unexpected experimental extensions");
3374 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
3376 if (Ext == std::end(
AllFeatures) || StringRef(Ext->key()) != Feature)
3377 return Error(Loc,
"unknown extension feature");
3381 if (
Type == RISCVOptionArchArgType::Plus) {
3384 setFeatureBits(Ext->Value, Ext->key());
3387 copySTI().setFeatureBits(OldFeatureBits);
3388 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3391 raw_string_ostream OutputErrMsg(Buffer);
3392 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3393 OutputErrMsg << ErrMsg.getMessage();
3396 return Error(Loc, OutputErrMsg.str());
3399 assert(
Type == RISCVOptionArchArgType::Minus);
3405 Feature.Implies.test(Ext->Value))
3406 return Error(Loc, Twine(
"can't disable ") + Ext->key() +
3407 " extension; " + Feature.key() +
3408 " extension requires " + Ext->key() +
3412 clearFeatureBits(Ext->Value, Ext->key());
3419 getTargetStreamer().emitDirectiveOptionArch(Args);
3422 getTargetStreamer().setArchString((*ParseResult)->toString());
3426 if (Option ==
"exact") {
3430 getTargetStreamer().emitDirectiveOptionExact();
3431 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3432 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3436 if (Option ==
"noexact") {
3440 getTargetStreamer().emitDirectiveOptionNoExact();
3441 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3442 setFeatureBits(RISCV::FeatureRelax,
"relax");
3446 if (Option ==
"rvc") {
3450 getTargetStreamer().emitDirectiveOptionRVC();
3451 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3453 getTargetStreamer().setArchString((*ParseResult)->toString());
3457 if (Option ==
"norvc") {
3461 getTargetStreamer().emitDirectiveOptionNoRVC();
3462 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3463 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3465 getTargetStreamer().setArchString((*ParseResult)->toString());
3469 if (Option ==
"pic") {
3473 getTargetStreamer().emitDirectiveOptionPIC();
3474 ParserOptions.IsPicEnabled =
true;
3478 if (Option ==
"nopic") {
3482 getTargetStreamer().emitDirectiveOptionNoPIC();
3483 ParserOptions.IsPicEnabled =
false;
3487 if (Option ==
"relax") {
3491 getTargetStreamer().emitDirectiveOptionRelax();
3492 setFeatureBits(RISCV::FeatureRelax,
"relax");
3496 if (Option ==
"norelax") {
3500 getTargetStreamer().emitDirectiveOptionNoRelax();
3501 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3507 "unknown option, expected 'push', 'pop', "
3508 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3509 "'exact', or 'noexact'");
3517bool RISCVAsmParser::parseDirectiveAttribute() {
3518 MCAsmParser &Parser = getParser();
3524 std::optional<unsigned> Ret =
3527 return Error(TagLoc,
"attribute name not recognised: " + Name);
3531 const MCExpr *AttrExpr;
3538 if (check(!CE, TagLoc,
"expected numeric constant"))
3541 Tag =
CE->getValue();
3547 StringRef StringValue;
3548 int64_t IntegerValue = 0;
3549 bool IsIntegerValue =
true;
3554 IsIntegerValue =
false;
3557 if (IsIntegerValue) {
3558 const MCExpr *ValueExpr;
3564 return Error(ValueExprLoc,
"expected numeric constant");
3565 IntegerValue =
CE->getValue();
3578 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3580 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3583 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3587 getTargetStreamer().emitTextAttribute(
Tag, Result);
3591 getTargetStreamer().setArchString(Result);
3599 .
Cases({
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s"},
true)
3600 .Cases({
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj"},
3602 .
Cases({
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es"},
3611bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3612 MCAsmParser &Parser = getParser();
3619 std::optional<int64_t>
Length;
3629 return Error(ErrorLoc,
3630 "instruction lengths must be a non-zero multiple of two");
3634 return Error(ErrorLoc,
3635 "instruction lengths over 64 bits are not supported");
3641 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3646 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3647 return Error(ErrorLoc,
3648 "instruction length does not match the encoding");
3651 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3654 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3657 if (!getSTI().
hasFeature(RISCV::FeatureStdExtZca) &&
3658 (EncodingDerivedLength == 2))
3659 return Error(ErrorLoc,
"compressed instructions are not allowed");
3661 if (getParser().parseEOL(
"invalid operand for instruction")) {
3662 getParser().eatToEndOfStatement();
3670 Opcode = RISCV::Insn16;
3673 Opcode = RISCV::Insn32;
3676 Opcode = RISCV::Insn48;
3679 Opcode = RISCV::Insn64;
3685 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3687 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3692 return Error(ErrorLoc,
"invalid instruction format");
3694 std::string FormatName = (
".insn_" +
Format).str();
3696 ParseInstructionInfo
Info;
3699 if (parseInstruction(Info, FormatName, L,
Operands))
3711bool RISCVAsmParser::parseDirectiveVariantCC() {
3713 if (getParser().parseIdentifier(Name))
3714 return TokError(
"expected symbol name");
3717 getTargetStreamer().emitDirectiveVariantCC(
3722void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3725 const MCSubtargetInfo &STI = getSTI();
3726 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3729 ++RISCVNumInstrsCompressed;
3733void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3738 for (MCInst &Inst : Seq) {
3739 emitToStreamer(Out, Inst);
3743void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3744 const MCExpr *Symbol,
3746 unsigned SecondOpcode, SMLoc IDLoc,
3754 Out.emitLabel(TmpLabel);
3758 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3763 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3766 .addExpr(RefToLinkTmpLabel));
3769void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3782 Out, MCInstBuilder(RISCV::QC_E_LI).addReg(DestReg).addExpr(Symbol));
3788void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3798 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3799 emitAuipcInstPair(DestReg, DestReg, Symbol,
RISCV::S_GOT_HI, SecondOpcode,
3803void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3812 if (ParserOptions.IsPicEnabled)
3813 emitLoadGlobalAddress(Inst, IDLoc, Out);
3815 emitLoadLocalAddress(Inst, IDLoc, Out);
3818void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3828 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3829 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3830 SecondOpcode, IDLoc, Out);
3833void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3843 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3844 RISCV::ADDI, IDLoc, Out);
3847void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3848 SMLoc IDLoc, MCStreamer &Out,
3857 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3859 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3863 if (getRISCVMCRegisterClass(RISCV::GPRPairRegClassID).
contains(TmpReg)) {
3864 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3865 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3873void RISCVAsmParser::emitQCELILoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3874 SMLoc IDLoc, MCStreamer &Out,
3884 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3888 MCInstBuilder(RISCV::QC_E_LI).addReg(AddrReg).addExpr(Symbol));
3891 const MCExpr *AccessExpr =
3897 struct CompressedForm {
3901 std::optional<CompressedForm> Compressed;
3905 case RISCV::PseudoQCAccessLBU:
3906 Compressed = {RISCV::PseudoQCAccessC_LBU, RISCV::FeatureStdExtZcb};
3908 case RISCV::PseudoQCAccessLH:
3909 Compressed = {RISCV::PseudoQCAccessC_LH, RISCV::FeatureStdExtZcb};
3911 case RISCV::PseudoQCAccessLHU:
3912 Compressed = {RISCV::PseudoQCAccessC_LHU, RISCV::FeatureStdExtZcb};
3914 case RISCV::PseudoQCAccessLW:
3915 Compressed = {RISCV::PseudoQCAccessC_LW, RISCV::FeatureStdExtZca};
3917 case RISCV::PseudoQCAccessSB:
3918 Compressed = {RISCV::PseudoQCAccessC_SB, RISCV::FeatureStdExtZcb};
3920 case RISCV::PseudoQCAccessSH:
3921 Compressed = {RISCV::PseudoQCAccessC_SH, RISCV::FeatureStdExtZcb};
3923 case RISCV::PseudoQCAccessSW:
3924 Compressed = {RISCV::PseudoQCAccessC_SW, RISCV::FeatureStdExtZca};
3931 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(AddrReg);
3932 if (HasTmpReg && CanUseGPRC) {
3935 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(DataReg);
3938 bool UseCompressed =
3939 Compressed && getSTI().hasFeature(Compressed->Feature) && CanUseGPRC;
3941 unsigned ActualOpcode = UseCompressed ? Compressed->Opcode : Opcode;
3944 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3948 .addExpr(AccessExpr));
3950 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3954 .addExpr(AccessExpr));
3958void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3959 int64_t Width, SMLoc IDLoc,
3968 const MCOperand &DestReg = Inst.
getOperand(0);
3969 const MCOperand &SourceReg = Inst.
getOperand(1);
3971 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3972 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3974 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3976 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3981 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3987void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
3994 emitToStreamer(Out, MCInstBuilder(Opcode)
3998 .addReg(MCRegister())
4000 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
4011 "The destination register should not be V0.");
4013 emitToStreamer(Out, MCInstBuilder(Opcode)
4019 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
4031 "The temporary vector register should not be V0.");
4032 emitToStreamer(Out, MCInstBuilder(Opcode)
4036 .addReg(MCRegister())
4038 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4050 "The temporary vector register should not be V0.");
4051 emitToStreamer(Out, MCInstBuilder(Opcode)
4055 .addReg(MCRegister())
4057 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4062 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4067 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
4075bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
4077 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
4080 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
4081 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
4082 "%tprel_add specifier");
4088bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
4090 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
4093 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
4094 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
4095 "%tlsdesc_call specifier");
4101std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
4102 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
4105std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
4106 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
4110std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
4111 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
4115std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultZeroOffset() {
4117 llvm::SMLoc(), llvm::SMLoc(), isRV64());
4124 case RISCV::VLOXSEG2EI8_V:
4125 case RISCV::VLOXSEG2EI16_V:
4126 case RISCV::VLOXSEG2EI32_V:
4127 case RISCV::VLOXSEG2EI64_V:
4128 case RISCV::VLUXSEG2EI8_V:
4129 case RISCV::VLUXSEG2EI16_V:
4130 case RISCV::VLUXSEG2EI32_V:
4131 case RISCV::VLUXSEG2EI64_V:
4133 case RISCV::VLOXSEG3EI8_V:
4134 case RISCV::VLOXSEG3EI16_V:
4135 case RISCV::VLOXSEG3EI32_V:
4136 case RISCV::VLOXSEG3EI64_V:
4137 case RISCV::VLUXSEG3EI8_V:
4138 case RISCV::VLUXSEG3EI16_V:
4139 case RISCV::VLUXSEG3EI32_V:
4140 case RISCV::VLUXSEG3EI64_V:
4142 case RISCV::VLOXSEG4EI8_V:
4143 case RISCV::VLOXSEG4EI16_V:
4144 case RISCV::VLOXSEG4EI32_V:
4145 case RISCV::VLOXSEG4EI64_V:
4146 case RISCV::VLUXSEG4EI8_V:
4147 case RISCV::VLUXSEG4EI16_V:
4148 case RISCV::VLUXSEG4EI32_V:
4149 case RISCV::VLUXSEG4EI64_V:
4151 case RISCV::VLOXSEG5EI8_V:
4152 case RISCV::VLOXSEG5EI16_V:
4153 case RISCV::VLOXSEG5EI32_V:
4154 case RISCV::VLOXSEG5EI64_V:
4155 case RISCV::VLUXSEG5EI8_V:
4156 case RISCV::VLUXSEG5EI16_V:
4157 case RISCV::VLUXSEG5EI32_V:
4158 case RISCV::VLUXSEG5EI64_V:
4160 case RISCV::VLOXSEG6EI8_V:
4161 case RISCV::VLOXSEG6EI16_V:
4162 case RISCV::VLOXSEG6EI32_V:
4163 case RISCV::VLOXSEG6EI64_V:
4164 case RISCV::VLUXSEG6EI8_V:
4165 case RISCV::VLUXSEG6EI16_V:
4166 case RISCV::VLUXSEG6EI32_V:
4167 case RISCV::VLUXSEG6EI64_V:
4169 case RISCV::VLOXSEG7EI8_V:
4170 case RISCV::VLOXSEG7EI16_V:
4171 case RISCV::VLOXSEG7EI32_V:
4172 case RISCV::VLOXSEG7EI64_V:
4173 case RISCV::VLUXSEG7EI8_V:
4174 case RISCV::VLUXSEG7EI16_V:
4175 case RISCV::VLUXSEG7EI32_V:
4176 case RISCV::VLUXSEG7EI64_V:
4178 case RISCV::VLOXSEG8EI8_V:
4179 case RISCV::VLOXSEG8EI16_V:
4180 case RISCV::VLOXSEG8EI32_V:
4181 case RISCV::VLOXSEG8EI64_V:
4182 case RISCV::VLUXSEG8EI8_V:
4183 case RISCV::VLUXSEG8EI16_V:
4184 case RISCV::VLUXSEG8EI32_V:
4185 case RISCV::VLUXSEG8EI64_V:
4191 if (getRISCVMCRegisterClass(RISCV::VRM2RegClassID).
contains(
Reg))
4193 if (getRISCVMCRegisterClass(RISCV::VRM4RegClassID).
contains(
Reg))
4195 if (getRISCVMCRegisterClass(RISCV::VRM8RegClassID).
contains(
Reg))
4202 case RISCV::VFWMMACC_VV_SCALE:
4203 case RISCV::VFQMMACC_VV_SCALE:
4204 case RISCV::VF8WMMACC_VV_SCALE:
4205 case RISCV::VFWIMMACC_VV:
4206 case RISCV::VFQIMMACC_VV:
4207 case RISCV::VF8WIMMACC_VV:
4214bool RISCVAsmParser::validateInstruction(MCInst &Inst,
4218 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
4219 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
4222 if (DestReg == TempReg) {
4223 SMLoc Loc =
Operands.back()->getStartLoc();
4224 return Error(Loc,
"the temporary vector register cannot be the same as "
4225 "the destination register");
4229 if (Opcode == RISCV::PseudoVMSGEU_VX_M || Opcode == RISCV::PseudoVMSGE_VX_M) {
4232 if (MaskReg == RISCV::V0 && DestReg == RISCV::V0) {
4233 SMLoc Loc =
Operands.back()->getStartLoc();
4234 return Error(Loc,
"the destination vector register cannot overlap the "
4235 "mask register unless a temporary register is "
4240 if (Opcode == RISCV::CV_INSERT &&
4243 "the sum of the immediate operands must be less than 32");
4248 case RISCV::TH_LBIA:
4249 case RISCV::TH_LBIB:
4250 case RISCV::TH_LBUIA:
4251 case RISCV::TH_LBUIB:
4252 case RISCV::TH_LHIA:
4253 case RISCV::TH_LHIB:
4254 case RISCV::TH_LHUIA:
4255 case RISCV::TH_LHUIB:
4256 case RISCV::TH_LWIA:
4257 case RISCV::TH_LWIB:
4258 case RISCV::TH_LWUIA:
4259 case RISCV::TH_LWUIB:
4260 case RISCV::TH_LDIA:
4261 case RISCV::TH_LDIB:
4263 return Error(
Operands[1]->getStartLoc(),
"rd and rs1 must be different");
4266 case RISCV::TH_LWUD:
4267 case RISCV::TH_LWD: {
4273 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
4274 SMLoc Loc =
Operands[1]->getStartLoc();
4275 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
4281 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
4285 SMLoc Loc =
Operands[1]->getStartLoc();
4286 return Error(Loc,
"rs1 and rs2 must be different");
4291 auto CheckOperandDoesNotOverlapV0 = [&](
int OperandIdx,
4292 unsigned ParsedIdx) {
4295 "vd, vs1, and vs2 cannot overlap v0.scale");
4300 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4302 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4304 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4305 assert(DestIdx >= 0 && VS1Idx >= 0 && VS2Idx >= 0 &&
4306 "Unexpected Zvvfmm scaled operand list");
4308 if (CheckOperandDoesNotOverlapV0(DestIdx, 1) ||
4309 CheckOperandDoesNotOverlapV0(VS1Idx, 2) ||
4310 CheckOperandDoesNotOverlapV0(VS2Idx, 3))
4314 const MCInstrDesc &MCID = MII.
get(Opcode);
4318 int DestIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4322 const MCParsedAsmOperand *ParsedOp =
Operands[1].get();
4323 if (!ParsedOp->
isReg()) {
4328 assert(ParsedOp->
getReg() == DestReg &&
"Can't find parsed dest operand");
4332 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4336 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4337 assert(VS2Idx >= 0 &&
"No vs2 operand?");
4338 unsigned CheckEncoding =
4341 for (
unsigned i = 0; i < std::max(NF, Lmul); i++) {
4342 if ((DestEncoding + i) == CheckEncoding)
4343 return Error(Loc,
"the destination vector register group cannot overlap"
4344 " the source vector register group");
4349 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4353 unsigned CheckEncoding =
4355 for (
unsigned i = 0; i < Lmul; i++) {
4356 if ((DestEncoding + i) == CheckEncoding)
4358 "the destination vector register group cannot overlap"
4359 " the source vector register group");
4365 int VMIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vm);
4366 assert(VMIdx >= 0 &&
"No vm operand?");
4368 if (DestReg == RISCV::V0) {
4371 return Error(Loc,
"the destination vector register group cannot be V0");
4379 "Unexpected mask operand register");
4381 return Error(Loc,
"the destination vector register group cannot overlap"
4382 " the mask register");
4390 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vmask);
4392 if (MaskReg != RISCV::V0 && MaskReg != RISCV::V1)
4394 "vmask operand only supports v0 or v1");
4397 RISCV::OpName RegOps[] = {RISCV::OpName::vd, RISCV::OpName::vs1,
4398 RISCV::OpName::vs2};
4399 for (RISCV::OpName OpN : RegOps) {
4400 int Idx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), OpN);
4406 for (
unsigned i = 0; i < RegLmul; i++) {
4407 if ((RegEnc + i) == MaskEnc) {
4408 SMLoc Loc =
Operands[Idx]->getStartLoc();
4409 return Error(Loc, Twine(
"register conflicts with vmask register ") +
4419bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
4427 case RISCV::MOP_RR_7: {
4439 case RISCV::MOP_R_28: {
4457 case RISCV::PseudoC_ADDI_NOP: {
4459 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
4469 if (getSTI().
hasFeature(RISCV::Feature64Bit))
4471 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV32)
4476 case RISCV::PACKW: {
4480 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV64)
4485 case RISCV::PseudoLLAImm:
4486 case RISCV::PseudoLAImm:
4487 case RISCV::PseudoLI: {
4493 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
4505 emitLoadImm(
Reg,
Imm, Out);
4508 case RISCV::PseudoLLA:
4509 emitLoadLocalAddress(Inst, IDLoc, Out);
4511 case RISCV::PseudoLGA:
4512 emitLoadGlobalAddress(Inst, IDLoc, Out);
4514 case RISCV::PseudoLA:
4515 emitLoadAddress(Inst, IDLoc, Out);
4517 case RISCV::PseudoLA_TLS_IE:
4518 emitLoadTLSIEAddress(Inst, IDLoc, Out);
4520 case RISCV::PseudoLA_TLS_GD:
4521 emitLoadTLSGDAddress(Inst, IDLoc, Out);
4523 case RISCV::PseudoLB:
4524 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
4526 case RISCV::PseudoLBU:
4527 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
4529 case RISCV::PseudoLH:
4530 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
4532 case RISCV::PseudoLHU:
4533 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
4535 case RISCV::PseudoLW:
4536 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
4538 case RISCV::PseudoLWU:
4539 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
4541 case RISCV::PseudoLD:
4542 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
4544 case RISCV::PseudoLD_RV32:
4545 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
4547 case RISCV::PseudoFLH:
4548 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
4550 case RISCV::PseudoFLW:
4551 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
4553 case RISCV::PseudoFLD:
4554 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
4556 case RISCV::PseudoFLQ:
4557 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
4559 case RISCV::PseudoSB:
4560 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
4562 case RISCV::PseudoSH:
4563 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
4565 case RISCV::PseudoSW:
4566 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
4568 case RISCV::PseudoSD:
4569 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
4571 case RISCV::PseudoSD_RV32:
4572 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
4574 case RISCV::PseudoQC_E_LB:
4575 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLB, IDLoc, Out,
4578 case RISCV::PseudoQC_E_LBU:
4579 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLBU, IDLoc, Out,
4582 case RISCV::PseudoQC_E_LH:
4583 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLH, IDLoc, Out,
4586 case RISCV::PseudoQC_E_LHU:
4587 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLHU, IDLoc, Out,
4590 case RISCV::PseudoQC_E_LW:
4591 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLW, IDLoc, Out,
4594 case RISCV::PseudoQC_E_SB:
4595 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSB, IDLoc, Out,
4598 case RISCV::PseudoQC_E_SH:
4599 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSH, IDLoc, Out,
4602 case RISCV::PseudoQC_E_SW:
4603 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSW, IDLoc, Out,
4606 case RISCV::PseudoFSH:
4607 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
4609 case RISCV::PseudoFSW:
4610 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
4612 case RISCV::PseudoFSD:
4613 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4615 case RISCV::PseudoFSQ:
4616 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4618 case RISCV::PseudoAddTPRel:
4619 if (checkPseudoAddTPRel(Inst,
Operands))
4622 case RISCV::PseudoTLSDESCCall:
4623 if (checkPseudoTLSDESCCall(Inst,
Operands))
4626 case RISCV::PseudoSEXT_B:
4627 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4629 case RISCV::PseudoSEXT_H:
4630 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4632 case RISCV::PseudoZEXT_H:
4633 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4635 case RISCV::PseudoZEXT_W:
4636 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4638 case RISCV::PseudoVMSGEU_VX_M:
4639 case RISCV::PseudoVMSGEU_VX_M_T:
4640 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4642 case RISCV::PseudoVMSGE_VX_M:
4643 case RISCV::PseudoVMSGE_VX_M_T:
4644 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4646 case RISCV::PseudoVMSGE_VI:
4647 case RISCV::PseudoVMSLT_VI: {
4651 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4653 emitToStreamer(Out, MCInstBuilder(
Opc)
4661 case RISCV::PseudoVMSGEU_VI:
4662 case RISCV::PseudoVMSLTU_VI: {
4669 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4672 emitToStreamer(Out, MCInstBuilder(
Opc)
4680 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4683 emitToStreamer(Out, MCInstBuilder(
Opc)
4693 case RISCV::PseudoCV_ELW:
4694 emitLoadStoreSymbol(Inst, RISCV::CV_ELW, IDLoc, Out,
false);
4698 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,...