52#define DEBUG_TYPE "riscv-asm-parser"
55 "Number of RISC-V Compressed instructions emitted");
60struct ParserOptionsSet {
65 const RISCVMCOptions &CLOpts;
69 enum class VTypeState {
80 ParserOptionsSet ParserOptions;
82 SMLoc getLoc()
const {
return getParser().
getTok().
getLoc(); }
83 bool isRV64()
const {
return getSTI().hasFeature(RISCV::Feature64Bit); }
84 bool isRVE()
const {
return getSTI().hasFeature(RISCV::FeatureStdExtE); }
85 bool enableExperimentalExtension()
const {
86 return getSTI().hasFeature(RISCV::Experimental);
89 RISCVTargetStreamer &getTargetStreamer() {
90 assert(getParser().getStreamer().getTargetStreamer() &&
91 "do not have a target streamer");
92 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
93 return static_cast<RISCVTargetStreamer &
>(TS);
96 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
97 unsigned Kind)
override;
99 bool generateImmOutOfRangeError(SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
102 struct NearMissMessage {
107 std::string getCustomOperandDiag(
unsigned MatchError);
109 void FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
110 SmallVectorImpl<NearMissMessage> &NearMissesOut,
112 void ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses, SMLoc IDLoc,
115 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
118 bool MatchingInlineAsm)
override;
121 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
122 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
123 SMLoc &EndLoc)
override;
125 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
128 ParseStatus parseDirective(AsmToken DirectiveID)
override;
130 bool parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
unsigned &Sew,
131 unsigned &Lmul,
bool &Fractional,
bool &TailAgnostic,
132 bool &MaskAgnostic,
bool &AltFmt);
133 bool generateVTypeError(SMLoc ErrorLoc);
135 bool generateXSfmmVTypeError(SMLoc ErrorLoc);
138 void emitToStreamer(MCStreamer &S,
const MCInst &Inst);
142 void emitLoadImm(MCRegister DestReg, int64_t
Value, MCStreamer &Out);
146 void emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
148 unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out);
151 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
154 void emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
157 void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
161 void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
165 void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
168 void emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
169 MCStreamer &Out,
bool HasTmpReg);
174 void emitQCELILoadStoreSymbol(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
175 MCStreamer &Out,
bool HasTmpReg);
178 void emitPseudoExtend(MCInst &Inst,
bool SignExtend, int64_t Width,
179 SMLoc IDLoc, MCStreamer &Out);
182 void emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc, MCStreamer &Out);
207#define GET_ASSEMBLER_HEADER
208#include "RISCVGenAsmMatcher.inc"
238 return parseRegList(
Operands,
true);
244 bool ExpectNegative =
false);
246 return parseZcmpStackAdj(
Operands,
true);
250 bool parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
251 bool parseDataExpr(
const MCExpr *&Res)
override;
253 bool parseDirectiveOption();
254 bool parseDirectiveAttribute();
255 bool parseDirectiveInsn(SMLoc L);
256 bool parseDirectiveVariantCC();
261 bool resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
262 bool FromOptionDirective);
264 void setFeatureBits(
uint64_t Feature, StringRef FeatureString) {
266 MCSubtargetInfo &STI = copySTI();
272 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
276 void clearFeatureBits(
uint64_t Feature, StringRef FeatureString) {
278 MCSubtargetInfo &STI = copySTI();
279 setAvailableFeatures(
284 void pushFeatureBits() {
285 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
286 "These two stacks must be kept synchronized");
287 FeatureBitStack.push_back(getSTI().getFeatureBits());
288 ParserOptionsStack.push_back(ParserOptions);
291 bool popFeatureBits() {
292 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
293 "These two stacks must be kept synchronized");
294 if (FeatureBitStack.empty())
297 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
298 copySTI().setFeatureBits(FeatureBits);
299 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
301 ParserOptions = ParserOptionsStack.pop_back_val();
306 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
307 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
308 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
309 std::unique_ptr<RISCVOperand> defaultSMTVType();
310 std::unique_ptr<RISCVOperand> defaultZeroOffset();
313 enum RISCVMatchResultTy :
unsigned {
314 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
315#define GET_OPERAND_DIAGNOSTIC_TYPES
316#include "RISCVGenAsmMatcher.inc"
317#undef GET_OPERAND_DIAGNOSTIC_TYPES
321 static bool isSymbolDiff(
const MCExpr *Expr);
323 RISCVAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
324 const MCInstrInfo &MII)
325 : MCTargetAsmParser(STI, MII),
333 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
338 if (CLOpts.add_build_attributes)
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 isUImm8GE32()
const {
832 bool isRnumArg()
const {
834 [](int64_t
Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(10); });
837 bool isRnumArg_0_7()
const {
839 [](int64_t
Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(7); });
842 bool isRnumArg_1_10()
const {
844 [](int64_t
Imm) {
return Imm >= INT64_C(1) &&
Imm <= INT64_C(10); });
847 bool isRnumArg_2_14()
const {
849 [](int64_t
Imm) {
return Imm >= INT64_C(2) &&
Imm <= INT64_C(14); });
852 template <
unsigned N>
bool isSImm()
const {
856 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
857 return IsConstantImm &&
isInt<N>(fixImmediateForRV32(
Imm, isRV64Expr()));
860 bool isYBNDSWImm()
const {
865 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
869 template <
class Pred>
bool isSImmPred(
Pred p)
const {
873 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
874 return IsConstantImm &&
p(fixImmediateForRV32(
Imm, isRV64Expr()));
877 bool isSImm5NonZero()
const {
881 bool isSImm6NonZero()
const {
885 bool isCLUIImm()
const {
886 return isUImmPred([](int64_t
Imm) {
891 bool isUImm10Lsb00NonZero()
const {
898 static int64_t fixImmediateForRV32(int64_t
Imm,
bool IsRV64Imm) {
904 bool isSImm12LO()
const {
910 return isInt<12>(fixImmediateForRV32(
Imm, isRV64Expr()));
913 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
916 VK == ELF::R_RISCV_TLSDESC_ADD_LO12);
924 template <
bool (RISCVOperand::*Pred)() const>
925 DiagnosticPredicate isOptionalMemOffset()
const {
929 : DiagnosticPredicate::NearMatch;
932 bool isSImm12Lsb00000()
const {
936 bool isSImm10Lsb0000NonZero()
const {
941 bool isSImm16NonZero()
const {
945 bool isUImm16NonZero()
const {
949 bool isSImm20LI()
const {
955 return isInt<20>(fixImmediateForRV32(
Imm, isRV64Expr()));
958 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
962 bool isSImm8PLI_B()
const {
return isSImm<8>() || isUImm<8>(); }
963 bool isSImm10PLUI()
const {
return isSImm<10>() || isUImm<10>(); }
965 bool isSImm10PLI_H()
const {
966 return isSImm<10>() || isUImmPred([](int64_t
Imm) {
970 bool isSImm10PLI_W()
const {
971 return isSImm<10>() || isUImmPred([](int64_t
Imm) {
976 bool isUImm20LUI()
const {
985 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
986 (VK == ELF::R_RISCV_HI20 || VK == ELF::R_RISCV_TPREL_HI20);
989 bool isUImm20AUIPC()
const {
998 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
1000 VK == ELF::R_RISCV_TLS_GOT_HI20 || VK == ELF::R_RISCV_TLS_GD_HI20 ||
1001 VK == ELF::R_RISCV_TLSDESC_HI20);
1004 bool isImmZero()
const {
1005 return isUImmPred([](int64_t
Imm) {
return 0 ==
Imm; });
1008 bool isImmThree()
const {
1009 return isUImmPred([](int64_t
Imm) {
return 3 ==
Imm; });
1012 bool isImmFour()
const {
1013 return isUImmPred([](int64_t
Imm) {
return 4 ==
Imm; });
1016 bool isImm5Zibi()
const {
1021 bool isSImm5Plus1()
const {
1026 bool isSImm18Lsb0()
const {
1030 bool isSImm19Lsb00()
const {
1034 bool isSImm20Lsb000()
const {
1038 bool isSImm32Lsb0()
const {
1043 SMLoc getStartLoc()
const override {
return StartLoc; }
1045 SMLoc getEndLoc()
const override {
return EndLoc; }
1048 bool isRV64Expr()
const {
1049 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1053 MCRegister
getReg()
const override {
1054 assert(Kind == KindTy::Register &&
"Invalid type access!");
1058 StringRef getSysReg()
const {
1059 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
1060 return StringRef(SysReg.Data, SysReg.Length);
1063 const MCExpr *
getExpr()
const {
1064 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1069 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1074 assert(Kind == KindTy::Token &&
"Invalid type access!");
1078 unsigned getVType()
const {
1079 assert(Kind == KindTy::VType &&
"Invalid type access!");
1084 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1088 unsigned getFence()
const {
1089 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1094 assert(Kind == KindTy::SMTVType &&
"Invalid type access!");
1095 return SMTVType.SMTVType;
1098 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1108 case KindTy::Expression:
1111 OS <<
' ' << (Expr.IsRV64 ?
"rv64" :
"rv32") <<
'>';
1113 case KindTy::FPImmediate:
1114 OS <<
"<fpimm: " << FPImm.Val <<
">";
1116 case KindTy::Register:
1118 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1123 case KindTy::SystemRegister:
1124 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1133 OS << roundingModeToString(getFRM());
1136 case KindTy::SMTVType:
1137 OS <<
"<smtvtype: ";
1138 OS << SMTVTypeModeToString(getSMTVType());
1146 case KindTy::RegList:
1151 case KindTy::StackAdj:
1152 OS <<
"<stackadj: ";
1156 case KindTy::RegReg:
1157 OS <<
"<RegReg: BaseReg " <<
RegName(
RegReg.BaseReg) <<
" OffsetReg "
1163 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1164 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1171 static std::unique_ptr<RISCVOperand>
1172 createReg(MCRegister
Reg, SMLoc S, SMLoc
E,
bool IsGPRAsFPR =
false) {
1173 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1175 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1181 static std::unique_ptr<RISCVOperand> createExpr(
const MCExpr *Val, SMLoc S,
1182 SMLoc
E,
bool IsRV64) {
1183 auto Op = std::make_unique<RISCVOperand>(KindTy::Expression);
1184 Op->Expr.Expr = Val;
1185 Op->Expr.IsRV64 = IsRV64;
1191 static std::unique_ptr<RISCVOperand> createFPImm(
uint64_t Val, SMLoc S) {
1192 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1193 Op->FPImm.Val = Val;
1199 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1200 unsigned Encoding) {
1201 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1202 Op->SysReg.Data = Str.data();
1203 Op->SysReg.Length = Str.size();
1210 static std::unique_ptr<RISCVOperand>
1212 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1219 static std::unique_ptr<RISCVOperand>
1221 auto Op = std::make_unique<RISCVOperand>(KindTy::SMTVType);
1222 Op->SMTVType.SMTVType = VType;
1228 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val, SMLoc S) {
1229 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1230 Op->Fence.Val = Val;
1236 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI, SMLoc S) {
1237 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1238 Op->VType.Val = VTypeI;
1244 static std::unique_ptr<RISCVOperand> createRegList(
unsigned RlistEncode,
1246 auto Op = std::make_unique<RISCVOperand>(KindTy::RegList);
1252 static std::unique_ptr<RISCVOperand>
1253 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {
1254 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1256 Op->RegReg.OffsetReg = OffsetReg;
1262 static std::unique_ptr<RISCVOperand> createStackAdj(
unsigned StackAdj, SMLoc S) {
1263 auto Op = std::make_unique<RISCVOperand>(KindTy::StackAdj);
1264 Op->StackAdj.Val = StackAdj;
1269 static void addExpr(MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1270 assert(Expr &&
"Expr shouldn't be null!");
1282 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1283 assert(
N == 1 &&
"Invalid number of operands!");
1287 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1288 assert(
N == 1 &&
"Invalid number of operands!");
1289 addExpr(Inst,
getExpr(), isRV64Expr());
1292 template <
unsigned Bits>
1293 void addSExtImmOperands(MCInst &Inst,
unsigned N)
const {
1294 assert(
N == 1 &&
"Invalid number of operands!");
1301 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
1302 assert(
N == 1 &&
"Invalid number of operands!");
1304 addExpr(Inst,
getExpr(), isRV64Expr());
1309 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1313 void addFenceArgOperands(MCInst &Inst,
unsigned N)
const {
1314 assert(
N == 1 &&
"Invalid number of operands!");
1318 void addCSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
1319 assert(
N == 1 &&
"Invalid number of operands!");
1326 void addVTypeIOperands(MCInst &Inst,
unsigned N)
const {
1327 assert(
N == 1 &&
"Invalid number of operands!");
1329 if (Kind == KindTy::Expression) {
1330 [[maybe_unused]]
bool IsConstantImm =
1332 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1339 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1340 assert(
N == 1 &&
"Invalid number of operands!");
1344 void addRegRegOperands(MCInst &Inst,
unsigned N)
const {
1345 assert(
N == 2 &&
"Invalid number of operands!");
1350 void addStackAdjOperands(MCInst &Inst,
unsigned N)
const {
1351 assert(
N == 1 &&
"Invalid number of operands!");
1355 void addFRMArgOperands(MCInst &Inst,
unsigned N)
const {
1356 assert(
N == 1 &&
"Invalid number of operands!");
1360 void addSMTVTypeOperand(MCInst &Inst,
unsigned N)
const {
1361 assert(
N == 1 &&
"Invalid number of operands!");
1367#define GET_REGISTER_MATCHER
1368#define GET_SUBTARGET_FEATURE_NAME
1369#define GET_MATCHER_IMPLEMENTATION
1370#define GET_MNEMONIC_SPELL_CHECKER
1371#include "RISCVGenAsmMatcher.inc"
1374 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1375 return Reg - RISCV::F0_D + RISCV::F0_H;
1379 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1380 return Reg - RISCV::F0_D + RISCV::F0_F;
1384 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1385 return Reg - RISCV::F0_D + RISCV::F0_Q;
1389 assert(
Reg >= RISCV::X0 &&
Reg <= RISCV::X31 &&
"Invalid register");
1390 return Reg - RISCV::X0 + RISCV::X0_Y;
1395 unsigned RegClassID;
1396 if (Kind == MCK_VRM2)
1397 RegClassID = RISCV::VRM2RegClassID;
1398 else if (Kind == MCK_VRM4)
1399 RegClassID = RISCV::VRM4RegClassID;
1400 else if (Kind == MCK_VRM8)
1401 RegClassID = RISCV::VRM8RegClassID;
1405 &getRISCVMCRegisterClass(RegClassID));
1409 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1410 return Reg - RISCV::F0_D + RISCV::F0_Q2;
1415 return getRISCVMCRegisterClass(RISCV::YGPRRegClassID).contains(*RC.
begin());
1420 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1422 return Match_InvalidOperand;
1424 MCRegister
Reg =
Op.getReg();
1426 getRISCVMCRegisterClass(RISCV::FPR64RegClassID).contains(
Reg);
1428 getRISCVMCRegisterClass(RISCV::FPR64CRegClassID).contains(
Reg);
1429 bool IsRegVR = getRISCVMCRegisterClass(RISCV::VRRegClassID).contains(
Reg);
1434 const MCRegisterClass *RC =
1435 getRegClassFromMatchKind(
static_cast<MatchClassKind
>(Kind));
1440 return Match_Success;
1444 if (IsRegFPR64 && Kind == MCK_FPR256) {
1446 return Match_Success;
1448 if (IsRegFPR64 && Kind == MCK_FPR128) {
1450 return Match_Success;
1454 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1455 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1457 return Match_Success;
1461 if (IsRegFPR64 && Kind == MCK_FPR16) {
1463 return Match_Success;
1465 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1466 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_H;
1467 return Match_Success;
1469 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1470 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_W;
1471 return Match_Success;
1478 if (getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg) &&
1479 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1481 return Match_Success;
1485 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1488 return Match_InvalidOperand;
1489 return Match_Success;
1491 return Match_InvalidOperand;
1494bool RISCVAsmParser::generateImmOutOfRangeError(
1495 SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
1496 const Twine &
Msg =
"immediate must be an integer in the range") {
1503std::string RISCVAsmParser::getCustomOperandDiag(
unsigned MatchError) {
1505 StringRef
Msg =
"immediate must be an integer in the range") {
1506 return (
Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]").str();
1509 switch (MatchError) {
1513 if (
const char *Diag = getMatchKindDiag((RISCVMatchResultTy)MatchError))
1515 return std::string();
1516 case Match_InvalidImmXLenLI:
1518 return "operand must be a constant 64-bit integer";
1519 return Range(std::numeric_limits<int32_t>::min(),
1520 std::numeric_limits<uint32_t>::max());
1521 case Match_InvalidImmXLenLI_Restricted:
1523 return "operand either must be a constant 64-bit integer "
1524 "or a bare symbol name";
1525 return Range(std::numeric_limits<int32_t>::min(),
1526 std::numeric_limits<uint32_t>::max(),
1527 "operand either must be a bare symbol name or an immediate "
1528 "integer in the range");
1529 case Match_InvalidUImmLog2XLen:
1531 return Range(0, (1 << 6) - 1);
1532 return Range(0, (1 << 5) - 1);
1533 case Match_InvalidUImmLog2XLenNonZero:
1535 return Range(1, (1 << 6) - 1);
1536 return Range(1, (1 << 5) - 1);
1537 case Match_InvalidUImm1:
1538 return Range(0, (1 << 1) - 1);
1539 case Match_InvalidUImm2:
1540 return Range(0, (1 << 2) - 1);
1541 case Match_InvalidUImm2Lsb0:
1542 return Range(0, 2,
"immediate must be one of");
1543 case Match_InvalidUImm3:
1544 return Range(0, (1 << 3) - 1);
1545 case Match_InvalidUImm4:
1546 return Range(0, (1 << 4) - 1);
1547 case Match_InvalidUImm4Plus1:
1548 return Range(1, (1 << 4));
1549 case Match_InvalidUImm5:
1550 return Range(0, (1 << 5) - 1);
1551 case Match_InvalidUImm5NonZero:
1552 return Range(1, (1 << 5) - 1);
1553 case Match_InvalidUImm5GT3:
1554 return Range(4, (1 << 5) - 1);
1555 case Match_InvalidUImm5Plus1:
1556 return Range(1, (1 << 5));
1557 case Match_InvalidUImm5GE6Plus1:
1558 return Range(6, (1 << 5));
1559 case Match_InvalidUImm5Slist:
1560 return "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31";
1561 case Match_InvalidUImm6:
1562 return Range(0, (1 << 6) - 1);
1563 case Match_InvalidUImm6Plus1:
1564 return Range(1, (1 << 6));
1565 case Match_InvalidUImm7:
1566 return Range(0, (1 << 7) - 1);
1567 case Match_InvalidUImm8:
1568 return Range(0, (1 << 8) - 1);
1569 case Match_InvalidUImm8GE32:
1570 return Range(32, (1 << 8) - 1);
1571 case Match_InvalidSImm5:
1572 return Range(-(1 << 4), (1 << 4) - 1);
1573 case Match_InvalidSImm5NonZero:
1574 return Range(-(1 << 4), (1 << 4) - 1,
1575 "immediate must be non-zero in the range");
1576 case Match_InvalidSImm6:
1577 return Range(-(1 << 5), (1 << 5) - 1);
1578 case Match_InvalidSImm6NonZero:
1579 return Range(-(1 << 5), (1 << 5) - 1,
1580 "immediate must be non-zero in the range");
1581 case Match_InvalidCLUIImm:
1582 return Range(1, (1 << 5) - 1,
"immediate must be in [0xfffe0, 0xfffff] or");
1583 case Match_InvalidUImm5Lsb0:
1584 return Range(0, (1 << 5) - 2,
1585 "immediate must be a multiple of 2 bytes in the range");
1586 case Match_InvalidUImm6Lsb0:
1587 return Range(0, (1 << 6) - 2,
1588 "immediate must be a multiple of 2 bytes in the range");
1589 case Match_InvalidUImm6Lsb000:
1590 return Range(0, (1 << 6) - 8,
1591 "immediate must be a multiple of 8 in the range");
1592 case Match_InvalidUImm7Lsb00:
1593 return Range(0, (1 << 7) - 4,
1594 "immediate must be a multiple of 4 bytes in the range");
1595 case Match_InvalidUImm8Lsb00:
1596 return Range(0, (1 << 8) - 4,
1597 "immediate must be a multiple of 4 bytes in the range");
1598 case Match_InvalidUImm8Lsb000:
1599 return Range(0, (1 << 8) - 8,
1600 "immediate must be a multiple of 8 bytes in the range");
1601 case Match_InvalidUImm9:
1602 return Range(0, (1 << 9) - 1,
"immediate offset must be in the range");
1603 case Match_InvalidBareSImm9Lsb0:
1604 return Range(-(1 << 8), (1 << 8) - 2,
1605 "immediate must be a multiple of 2 bytes in the range");
1606 case Match_InvalidUImm9Lsb000:
1607 return Range(0, (1 << 9) - 8,
1608 "immediate must be a multiple of 8 bytes in the range");
1609 case Match_InvalidSImm8PLI_B:
1610 return Range(-(1 << 7), (1 << 8) - 1);
1611 case Match_InvalidSImm10:
1612 case Match_InvalidSImm10PLI_H:
1613 case Match_InvalidSImm10PLI_W:
1614 return Range(-(1 << 9), (1 << 9) - 1);
1615 case Match_InvalidSImm10PLUI:
1616 return Range(-(1 << 9), (1 << 10) - 1);
1617 case Match_InvalidUImm10Lsb00NonZero:
1618 return Range(4, (1 << 10) - 4,
1619 "immediate must be a multiple of 4 bytes in the range");
1620 case Match_InvalidSImm10Lsb0000NonZero:
1622 -(1 << 9), (1 << 9) - 16,
1623 "immediate must be a multiple of 16 bytes and non-zero in the range");
1624 case Match_InvalidSImm11:
1625 return Range(-(1 << 10), (1 << 10) - 1);
1626 case Match_InvalidBareSImm11Lsb0:
1627 return Range(-(1 << 10), (1 << 10) - 2,
1628 "immediate must be a multiple of 2 bytes in the range");
1629 case Match_InvalidUImm10:
1630 return Range(0, (1 << 10) - 1);
1631 case Match_InvalidUImm11:
1632 return Range(0, (1 << 11) - 1);
1633 case Match_InvalidUImm14Lsb00:
1634 return Range(0, (1 << 14) - 4,
1635 "immediate must be a multiple of 4 bytes in the range");
1636 case Match_InvalidUImm16NonZero:
1637 return Range(1, (1 << 16) - 1);
1638 case Match_InvalidSImm12:
1639 return Range(-(1 << 11), (1 << 11) - 1);
1640 case Match_InvalidSImm12LO:
1641 return Range(-(1 << 11), (1 << 11) - 1,
1642 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo "
1643 "specifier or an integer in the range");
1644 case Match_InvalidBareSImm12Lsb0:
1645 return Range(-(1 << 11), (1 << 11) - 2,
1646 "immediate must be a multiple of 2 bytes in the range");
1647 case Match_InvalidSImm12Lsb00000:
1648 return Range(-(1 << 11), (1 << 11) - 32,
1649 "immediate must be a multiple of 32 bytes in the range");
1650 case Match_InvalidBareSImm13Lsb0:
1651 return Range(-(1 << 12), (1 << 12) - 2,
1652 "immediate must be a multiple of 2 bytes in the range");
1653 case Match_InvalidSImm16:
1654 return Range(-(1 << 15), (1 << 15) - 1);
1655 case Match_InvalidSImm16NonZero:
1656 return Range(-(1 << 15), (1 << 15) - 1,
1657 "immediate must be non-zero in the range");
1658 case Match_InvalidSImm20LI:
1659 return Range(-(1 << 19), (1 << 19) - 1,
1660 "operand must be a symbol with a %qc.abs20 specifier or an "
1661 "integer in the range");
1662 case Match_InvalidUImm20LUI:
1663 return Range(0, (1 << 20) - 1,
1664 "operand must be a symbol with %hi/%tprel_hi specifier or an "
1665 "integer in the range");
1666 case Match_InvalidUImm20:
1667 return Range(0, (1 << 20) - 1);
1668 case Match_InvalidUImm20AUIPC:
1671 "operand must be a symbol with a "
1672 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
1673 "or an integer in the range");
1674 case Match_InvalidBareSImm21Lsb0:
1675 return Range(-(1 << 20), (1 << 20) - 2,
1676 "immediate must be a multiple of 2 bytes in the range");
1677 case Match_InvalidCSRSystemRegister:
1678 return Range(0, (1 << 12) - 1,
1679 "operand must be a valid system register name or an integer "
1681 case Match_InvalidImm5Zibi:
1682 return Range(-1, (1 << 5) - 1,
"immediate must be non-zero in the range");
1683 case Match_InvalidVTypeI:
1684 return "operand must be "
1685 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]";
1686 case Match_InvalidSImm5Plus1:
1687 return Range(-(1 << 4) + 1, (1 << 4),
"immediate must be in the range");
1688 case Match_InvalidSImm18:
1689 return Range(-(1 << 17), (1 << 17) - 1);
1690 case Match_InvalidSImm18Lsb0:
1691 return Range(-(1 << 17), (1 << 17) - 2,
1692 "immediate must be a multiple of 2 bytes in the range");
1693 case Match_InvalidSImm19Lsb00:
1694 return Range(-(1 << 18), (1 << 18) - 4,
1695 "immediate must be a multiple of 4 bytes in the range");
1696 case Match_InvalidSImm20Lsb000:
1697 return Range(-(1 << 19), (1 << 19) - 8,
1698 "immediate must be a multiple of 8 bytes in the range");
1699 case Match_InvalidSImm26:
1700 return Range(-(1 << 25), (1 << 25) - 1);
1702 case Match_InvalidBareSymbolQC_E_LI:
1705 case Match_InvalidBareSImm32:
1706 return Range(std::numeric_limits<int32_t>::min(),
1707 std::numeric_limits<uint32_t>::max());
1708 case Match_InvalidBareSImm32Lsb0:
1709 return Range(std::numeric_limits<int32_t>::min(),
1710 std::numeric_limits<int32_t>::max() - 1,
1711 "operand must be a multiple of 2 bytes in the range");
1712 case Match_InvalidRnumArg:
1713 return Range(0, 10);
1714 case Match_InvalidStackAdj:
1715 return "stack adjustment is invalid for this instruction and register "
1717 case Match_InvalidYBNDSWImm:
1718 return "immediate must be an integer in the range "
1719 "[1, 255], a multiple of 8 in the range [256, 504], "
1720 "or a multiple of 16 in the range [512, 4096]";
1727void RISCVAsmParser::FilterNearMisses(
1728 SmallVectorImpl<NearMissInfo> &NearMissesIn,
1729 SmallVectorImpl<NearMissMessage> &NearMissesOut, SMLoc IDLoc,
1733 std::multimap<unsigned, unsigned> OperandMissesSeen;
1734 SmallSet<FeatureBitset, 4> FeatureMissesSeen;
1735 bool ReportedTooFewOperands =
false;
1736 bool ReportedTooManyOperands =
false;
1738 for (NearMissInfo &
I : NearMissesIn) {
1739 switch (
I.getKind()) {
1742 ((RISCVOperand &)*
Operands[
I.getOperandIndex()]).getStartLoc();
1747 if (
I.getOperandClass() == InvalidMatchClass) {
1748 if (!ReportedTooManyOperands) {
1750 OperandLoc,
"unexpected extra operand for instruction"});
1751 ReportedTooManyOperands =
true;
1756 std::string OperandDiag = getCustomOperandDiag(
I.getOperandError());
1760 unsigned DupCheckMatchClass =
1761 OperandDiag.empty() ? ~0
U :
I.getOperandClass();
1762 auto PrevReports = OperandMissesSeen.equal_range(
I.getOperandIndex());
1764 PrevReports.first, PrevReports.second,
1765 [DupCheckMatchClass](
const std::pair<unsigned, unsigned> Pair) {
1766 if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
1767 return Pair.second == DupCheckMatchClass;
1768 return isSubclass((MatchClassKind)DupCheckMatchClass,
1769 (MatchClassKind)Pair.second);
1772 OperandMissesSeen.insert(
1773 std::make_pair(
I.getOperandIndex(), DupCheckMatchClass));
1775 NearMissMessage Message;
1776 Message.Loc = OperandLoc;
1777 if (!OperandDiag.empty()) {
1778 Message.Message = OperandDiag;
1780 Message.Message =
"invalid operand for instruction";
1782 dbgs() <<
"Missing diagnostic string for operand class "
1783 << getMatchClassName((MatchClassKind)
I.getOperandClass())
1784 <<
I.getOperandClass() <<
", error " <<
I.getOperandError()
1785 <<
", opcode " << MII.
getName(
I.getOpcode()) <<
"\n");
1791 const FeatureBitset &MissingFeatures =
I.getFeatures();
1793 if (!FeatureMissesSeen.
insert(MissingFeatures).second)
1796 NearMissMessage Message;
1797 Message.Loc = IDLoc;
1798 bool FirstFeature =
true;
1799 Message.Message =
"instruction requires the following:";
1800 for (
unsigned Feature : MissingFeatures) {
1801 Message.Message += FirstFeature ?
" " :
", ";
1803 FirstFeature =
false;
1813 if (!ReportedTooFewOperands) {
1814 SMLoc EndLoc = ((RISCVOperand &)*
Operands.back()).getEndLoc();
1816 NearMissMessage{EndLoc,
"too few operands for instruction"});
1817 ReportedTooFewOperands =
true;
1829void RISCVAsmParser::ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses,
1832 FilterNearMisses(NearMisses, Messages, IDLoc,
Operands);
1837 Error(IDLoc,
"invalid instruction");
1840 Error(Messages[0].Loc, Messages[0].Message);
1845 "invalid instruction, any one of the following would fix this:");
1846 for (
auto &M : Messages)
1851bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1855 bool MatchingInlineAsm) {
1860 MatchInstructionImpl(
Operands, Inst, &NearMisses, MatchingInlineAsm);
1865 if (validateInstruction(Inst,
Operands))
1867 return processInstruction(Inst, IDLoc,
Operands, Out);
1868 case Match_MnemonicFail: {
1869 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1870 std::string Suggestion = RISCVMnemonicSpellCheck(
1872 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1874 case Match_NearMisses:
1875 ReportNearMisses(NearMisses, IDLoc,
Operands);
1886MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name)
const {
1895 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1896 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1897 static_assert(RISCV::F0_D < RISCV::F0_Q,
"FPR matching must be updated");
1900 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1905bool RISCVAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1907 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1908 return Error(StartLoc,
"invalid register name");
1912ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1914 const AsmToken &Tok = getParser().getTok();
1917 StringRef
Name = getLexer().getTok().getIdentifier();
1929 SMLoc FirstS = getLoc();
1930 bool HadParens =
false;
1937 size_t ReadCount = getLexer().peekTokens(Buf);
1940 LParen = getParser().getTok();
1945 switch (getLexer().getKind()) {
1948 getLexer().UnLex(LParen);
1951 StringRef
Name = getLexer().getTok().getIdentifier();
1956 getLexer().UnLex(LParen);
1960 Operands.push_back(RISCVOperand::createToken(
"(", FirstS));
1962 SMLoc
E = getTok().getEndLoc();
1964 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
1969 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
1980 switch (getLexer().getKind()) {
1990 if (getParser().parseExpression(Res,
E))
1995 int64_t
Imm =
CE->getValue();
1997 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2006 if (getParser().parseIdentifier(Identifier))
2009 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
2012 "Unexpected opcode");
2015 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2025 return generateImmOutOfRangeError(
2027 "opcode must be a valid opcode name or an immediate in the range");
2035 switch (getLexer().getKind()) {
2045 if (getParser().parseExpression(Res,
E))
2050 int64_t
Imm =
CE->getValue();
2051 if (
Imm >= 0 &&
Imm <= 2) {
2052 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2061 if (getParser().parseIdentifier(Identifier))
2065 if (Identifier ==
"C0")
2067 else if (Identifier ==
"C1")
2069 else if (Identifier ==
"C2")
2076 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2085 return generateImmOutOfRangeError(
2087 "opcode must be a valid opcode name or an immediate in the range");
2094 auto SysRegFromConstantInt = [
this](
const MCExpr *
E, SMLoc S) {
2096 int64_t
Imm =
CE->getValue();
2098 auto Range = RISCVSysReg::lookupSysRegByEncoding(
Imm);
2102 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2105 return RISCVOperand::createSysReg(
2106 RISCVSysReg::getSysRegStr(
Reg.Name), S,
Imm);
2110 return RISCVOperand::createSysReg(
"", S,
Imm);
2113 return std::unique_ptr<RISCVOperand>();
2116 switch (getLexer().getKind()) {
2126 if (getParser().parseExpression(Res))
2129 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
2130 Operands.push_back(std::move(SysOpnd));
2134 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2138 if (getParser().parseIdentifier(Identifier))
2141 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
2144 if (SysReg->IsDeprecatedName) {
2146 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
2148 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2150 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
2151 RISCVSysReg::getSysRegStr(
Reg.Name) +
"'");
2156 const auto &FeatureBits = getSTI().getFeatureBits();
2157 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
2158 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
2159 const auto *Feature =
2161 return SysReg->FeaturesRequired[Feature.Value];
2163 std::string ErrorMsg =
2164 std::string(
"system register '") +
2165 std::string(RISCVSysReg::getSysRegStr(SysReg->Name)) +
"' ";
2166 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
2167 ErrorMsg +=
"is RV32 only";
2169 ErrorMsg +=
" and ";
2173 "requires '" + std::string(Feature->key()) +
"' to be enabled";
2176 return Error(S, ErrorMsg);
2179 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
2189 Operands.push_back(std::move(SysOpnd));
2194 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2195 "operand must be a valid system register "
2196 "name or an integer in the range");
2200 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2212 StringRef
Identifier = getTok().getIdentifier();
2213 if (
Identifier.compare_insensitive(
"inf") == 0) {
2216 getTok().getEndLoc(), isRV64()));
2217 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2220 getTok().getEndLoc(), isRV64()));
2221 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2224 getTok().getEndLoc(), isRV64()));
2226 return TokError(
"invalid floating point literal");
2237 const AsmToken &Tok = getTok();
2239 return TokError(
"invalid floating point immediate");
2242 APFloat RealVal(APFloat::IEEEdouble());
2244 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2246 return TokError(
"invalid floating point representation");
2249 RealVal.changeSign();
2251 Operands.push_back(RISCVOperand::createFPImm(
2252 RealVal.bitcastToAPInt().getZExtValue(), S));
2264 switch (getLexer().getKind()) {
2276 if (getParser().parseExpression(Res,
E))
2280 return parseOperandWithSpecifier(
Operands);
2283 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2293 const MCExpr *Expr =
nullptr;
2294 bool Failed = parseExprWithSpecifier(Expr,
E);
2296 Operands.push_back(RISCVOperand::createExpr(Expr, S,
E, isRV64()));
2300bool RISCVAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
2301 SMLoc Loc = getLoc();
2303 return TokError(
"expected '%' relocation specifier");
2304 StringRef
Identifier = getParser().getTok().getIdentifier();
2307 return TokError(
"invalid relocation specifier");
2313 const MCExpr *SubExpr;
2314 if (getParser().parseParenExpression(SubExpr,
E))
2321bool RISCVAsmParser::parseDataExpr(
const MCExpr *&Res) {
2324 return parseExprWithSpecifier(Res,
E);
2325 return getParser().parseExpression(Res);
2335 StringRef
Identifier = getTok().getIdentifier();
2345 if (getParser().parseExpression(Res,
E))
2348 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2358 std::string
Identifier(getTok().getIdentifier());
2364 SMLoc Loc = getLoc();
2365 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2366 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2380 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2392 std::string
Identifier(getTok().getIdentifier());
2398 SMLoc Loc = getLoc();
2399 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2400 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2414 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2423 if (getParser().parseExpression(Res,
E))
2426 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef)
2427 return Error(S,
"operand must be a valid jump target");
2430 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2451bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2452 unsigned &Sew,
unsigned &Lmul,
2453 bool &Fractional,
bool &TailAgnostic,
2454 bool &MaskAgnostic,
bool &AltFmt) {
2459 if (State < VTypeState::SeenSew &&
Identifier.consume_front(
"e")) {
2461 if (Identifier ==
"16alt") {
2464 }
else if (Identifier ==
"8alt") {
2474 State = VTypeState::SeenSew;
2478 if (State < VTypeState::SeenLmul &&
Identifier.consume_front(
"m")) {
2481 if (Identifier ==
"a" || Identifier ==
"u") {
2483 State = VTypeState::SeenMaskPolicy;
2494 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2495 unsigned MinLMUL = ELEN / 8;
2498 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2499 Twine(MinLMUL) +
" is reserved");
2502 State = VTypeState::SeenLmul;
2506 if (State < VTypeState::SeenTailPolicy &&
Identifier.starts_with(
"t")) {
2507 if (Identifier ==
"ta")
2508 TailAgnostic =
true;
2509 else if (Identifier ==
"tu")
2510 TailAgnostic =
false;
2514 State = VTypeState::SeenTailPolicy;
2518 if (State < VTypeState::SeenMaskPolicy &&
Identifier.starts_with(
"m")) {
2519 if (Identifier ==
"ma")
2520 MaskAgnostic =
true;
2521 else if (Identifier ==
"mu")
2522 MaskAgnostic =
false;
2526 State = VTypeState::SeenMaskPolicy;
2539 bool Fractional =
false;
2540 bool TailAgnostic =
false;
2541 bool MaskAgnostic =
false;
2544 VTypeState State = VTypeState::SeenNothingYet;
2546 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2547 MaskAgnostic, AltFmt)) {
2549 if (State == VTypeState::SeenNothingYet)
2558 State == VTypeState::SeenNothingYet)
2559 return generateVTypeError(S);
2563 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2564 unsigned MaxSEW = ELEN / Lmul;
2566 if (MaxSEW >= 8 && Sew > MaxSEW)
2567 Warning(S,
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2568 " and LMUL == mf" + Twine(Lmul) +
2569 " may not be compatible with all RVV implementations");
2574 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2578bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2579 return Error(ErrorLoc,
2581 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2601 if (Identifier !=
"16alt")
2630 Operands.push_back(RISCVOperand::createVType(
2636 return generateXSfmmVTypeError(S);
2639bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
2640 return Error(ErrorLoc,
"operand must be e[8|16|16alt|32|64],w[1|2|4]");
2647 StringRef
Name = getLexer().getTok().getIdentifier();
2648 if (!
Name.consume_back(
".t")) {
2652 return Error(getLoc(),
"expected '.t' suffix");
2659 if (
Reg != RISCV::V0)
2662 SMLoc
E = getTok().getEndLoc();
2664 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2672 StringRef
Name = getLexer().getTok().getIdentifier();
2673 if (!
Name.consume_back(
".scale"))
2674 return Error(getLoc(),
"expected '.scale' suffix");
2679 if (
Reg != RISCV::V0)
2682 SMLoc
E = getTok().getEndLoc();
2684 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2693 StringRef
Name = getLexer().getTok().getIdentifier();
2694 if (!
Name.consume_front(
"L") && !
Name.consume_front(
"l"))
2699 return Error(S,
"operand must be L1, L2, L4, L8, L16, L32, or L64");
2701 unsigned EncodedLambda =
Log2_32(Lambda) + 1;
2703 SMLoc
E = getTok().getEndLoc();
2705 Operands.push_back(RISCVOperand::createExpr(
2711 if (!isRV64() || getSTI().
hasFeature(RISCV::FeatureStdExtF))
2721 StringRef
Name = getLexer().getTok().getIdentifier();
2727 SMLoc
E = getTok().getEndLoc();
2729 Operands.push_back(RISCVOperand::createReg(
2735 if (isRV64() || getSTI().
hasFeature(RISCV::FeatureStdExtF))
2741 StringRef
Name = getLexer().getTok().getIdentifier();
2747 if (!getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg))
2750 if ((
Reg - RISCV::X0) & 1) {
2753 if (getSTI().
hasFeature(RISCV::FeatureStdExtZfinx))
2754 return TokError(
"double precision floating point operands must use even "
2755 "numbered X register");
2760 SMLoc
E = getTok().getEndLoc();
2763 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2765 Reg, RISCV::sub_gpr_even,
2766 &getRISCVMCRegisterClass(RISCV::GPRPairRegClassID));
2767 Operands.push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2771template <
bool IsRV64>
2773 return parseGPRPair(
Operands, IsRV64);
2783 if (!IsRV64Inst && isRV64())
2789 StringRef
Name = getLexer().getTok().getIdentifier();
2795 if (!getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg))
2798 if ((
Reg - RISCV::X0) & 1)
2799 return TokError(
"register must be even");
2802 SMLoc
E = getTok().getEndLoc();
2805 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2807 Reg, RISCV::sub_gpr_even,
2808 &getRISCVMCRegisterClass(RISCV::GPRPairRegClassID));
2809 Operands.push_back(RISCVOperand::createReg(Pair, S,
E));
2816 "operand must be a valid SpacemiT's Integer Matrix VType mnemonic");
2818 StringRef Str = getLexer().getTok().getIdentifier();
2821 if (!isValidSMTVTypeMode(VType))
2822 return TokError(
"SpacemiT's Integer Matrix only supports [i4|i8] mode");
2824 Operands.push_back(RISCVOperand::createSMTVType(VType, getLoc()));
2832 "operand must be a valid floating point rounding mode mnemonic");
2834 StringRef Str = getLexer().getTok().getIdentifier();
2839 "operand must be a valid floating point rounding mode mnemonic");
2841 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2846std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultSMTVType() {
2847 return RISCVOperand::createSMTVType(XSMTVTypeMode::SMTVTypeMode::SMT_I8,
2852 const AsmToken &Tok = getLexer().getTok();
2858 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2872 for (
char c : Str) {
2901 Operands.push_back(RISCVOperand::createFenceArg(
Imm, getLoc()));
2907 return TokError(
"operand must be formed of letters selected in-order from "
2914 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
2916 if (!parseRegister(
Operands).isSuccess())
2917 return Error(getLoc(),
"expected register");
2921 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2945 std::unique_ptr<RISCVOperand> OptionalImmOp;
2952 SMLoc ImmStart = getLoc();
2953 if (getParser().parseIntToken(ImmVal,
2954 "expected '(' or optional integer offset"))
2959 SMLoc ImmEnd = getLoc();
2962 ImmStart, ImmEnd, isRV64());
2966 OptionalImmOp ?
"expected '(' after optional integer offset"
2967 :
"expected '(' or optional integer offset"))
2970 if (!parseRegister(
Operands).isSuccess())
2971 return Error(getLoc(),
"expected register");
2977 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2979 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2980 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2991 StringRef OffsetRegName = getLexer().getTok().getIdentifier();
2994 !getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(OffsetReg))
2995 return Error(getLoc(),
"expected GPR register");
3002 return Error(getLoc(),
"expected GPR register");
3004 StringRef BaseRegName = getLexer().getTok().getIdentifier();
3007 !getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(BaseReg))
3008 return Error(getLoc(),
"expected GPR register");
3014 Operands.push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));
3027 bool MustIncludeS0) {
3039 return Error(getLoc(),
"invalid register");
3041 StringRef
RegName = getTok().getIdentifier();
3044 return Error(getLoc(),
"invalid register");
3047 UsesXRegs =
RegName[0] ==
'x';
3048 if (
Reg != RISCV::X1)
3049 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
3050 }
else if (RegEnd == RISCV::X1) {
3051 if (
Reg != RISCV::X8 || (UsesXRegs != (
RegName[0] ==
'x')))
3052 return Error(getLoc(), Twine(
"register must be '") +
3053 (UsesXRegs ?
"x8" :
"s0") +
"'");
3054 }
else if (RegEnd == RISCV::X9 && UsesXRegs) {
3055 if (
Reg != RISCV::X18 || (
RegName[0] !=
'x'))
3056 return Error(getLoc(),
"register must be 'x18'");
3058 return Error(getLoc(),
"too many register ranges");
3065 SMLoc MinusLoc = getLoc();
3067 if (RegEnd == RISCV::X1)
3068 return Error(MinusLoc, Twine(
"register '") + (UsesXRegs ?
"x1" :
"ra") +
3069 "' cannot start a multiple register range");
3072 return Error(getLoc(),
"invalid register");
3074 StringRef
RegName = getTok().getIdentifier();
3077 return Error(getLoc(),
"invalid register");
3079 if (RegEnd == RISCV::X8) {
3080 if ((
Reg != RISCV::X9 &&
3082 (UsesXRegs != (
RegName[0] ==
'x'))) {
3084 return Error(getLoc(),
"register must be 'x9'");
3085 return Error(getLoc(),
"register must be in the range 's1' to 's11'");
3087 }
else if (RegEnd == RISCV::X18) {
3089 return Error(getLoc(),
3090 "register must be in the range 'x19' to 'x27'");
3103 if (RegEnd == RISCV::X26)
3104 return Error(S,
"invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "
3105 "x18-x26}' is not supported");
3111 return Error(S,
"register list must include 's0' or 'x8'");
3113 Operands.push_back(RISCVOperand::createRegList(Encode, S));
3119 bool ExpectNegative) {
3128 auto *RegListOp =
static_cast<RISCVOperand *
>(
Operands.back().
get());
3129 if (!RegListOp->isRegList())
3132 unsigned RlistEncode = RegListOp->RegList.Encoding;
3136 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||
3137 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {
3138 int64_t
Lower = StackAdjBase;
3139 int64_t
Upper = StackAdjBase + 48;
3140 if (ExpectNegative) {
3145 return generateImmOutOfRangeError(S,
Lower,
Upper,
3146 "stack adjustment for register list must "
3147 "be a multiple of 16 bytes in the range");
3151 Operands.push_back(RISCVOperand::createStackAdj(StackAdj, S));
3163 MatchOperandParserImpl(
Operands, Mnemonic,
true);
3170 if (parseRegister(
Operands,
true).isSuccess())
3174 if (parseExpression(
Operands).isSuccess()) {
3177 return !parseMemOpBaseReg(
Operands).isSuccess();
3182 Error(getLoc(),
"unknown operand");
3186bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &Info,
3187 StringRef Name, SMLoc NameLoc,
3193 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
3197 Operands.push_back(RISCVOperand::createToken(Name, NameLoc));
3216 if (getParser().parseEOL(
"unexpected token")) {
3217 getParser().eatToEndOfStatement();
3223bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
3227 Kind = RE->getSpecifier();
3228 Expr = RE->getSubExpr();
3237bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
3246ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
3247 StringRef IDVal = DirectiveID.
getString();
3249 if (IDVal ==
".option")
3250 return parseDirectiveOption();
3251 if (IDVal ==
".attribute")
3252 return parseDirectiveAttribute();
3253 if (IDVal ==
".insn")
3254 return parseDirectiveInsn(DirectiveID.
getLoc());
3255 if (IDVal ==
".variant_cc")
3256 return parseDirectiveVariantCC();
3261bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
3262 bool FromOptionDirective) {
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;
3278 if (FromOptionDirective) {
3279 if (ISAInfo->getXLen() == 32 && isRV64())
3280 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3281 else if (ISAInfo->getXLen() == 64 && !isRV64())
3282 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3284 if (ISAInfo->getXLen() != 32 && ISAInfo->getXLen() != 64)
3285 return Error(Loc,
"bad arch string " + Arch);
3291 MCSubtargetInfo &STI = copySTI();
3295 if (ISAInfo->hasExtension(Feature.key()) != STI.
hasFeature(Feature.Value))
3298 if ((ISAInfo->getXLen() == 64) != STI.
hasFeature(RISCV::Feature64Bit))
3300 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
3302 Result = ISAInfo->toString();
3306bool RISCVAsmParser::parseDirectiveOption() {
3307 MCAsmParser &Parser = getParser();
3309 AsmToken Tok = Parser.
getTok();
3317 if (Option ==
"push") {
3321 getTargetStreamer().emitDirectiveOptionPush();
3326 if (Option ==
"pop") {
3331 getTargetStreamer().emitDirectiveOptionPop();
3332 if (popFeatureBits())
3333 return Error(StartLoc,
".option pop with no .option push");
3338 if (Option ==
"arch") {
3346 Type = RISCVOptionArchArgType::Plus;
3348 Type = RISCVOptionArchArgType::Minus;
3349 else if (!
Args.empty())
3351 "unexpected token, expected + or -");
3353 Type = RISCVOptionArchArgType::Full;
3357 "unexpected token, expected identifier");
3363 if (
Type == RISCVOptionArchArgType::Full) {
3365 if (resetToArch(Arch, Loc, Result,
true))
3374 Loc,
"extension version number parsing not currently implemented");
3377 if (!enableExperimentalExtension() &&
3379 return Error(Loc,
"unexpected experimental extensions");
3380 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
3382 if (Ext == std::end(
AllFeatures) || StringRef(Ext->key()) != Feature)
3383 return Error(Loc,
"unknown extension feature");
3385 if (Ext->Value == RISCV::FeatureStdExtY)
3386 return Error(Loc,
"passing '+y'/'-y' is not supported yet; specify a "
3387 "full arch string instead");
3391 if (
Type == RISCVOptionArchArgType::Plus) {
3394 setFeatureBits(Ext->Value, Ext->key());
3397 copySTI().setFeatureBits(OldFeatureBits);
3398 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3401 raw_string_ostream OutputErrMsg(Buffer);
3402 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3403 OutputErrMsg << ErrMsg.getMessage();
3406 return Error(Loc, OutputErrMsg.str());
3409 assert(
Type == RISCVOptionArchArgType::Minus);
3415 Feature.Implies.test(Ext->Value))
3416 return Error(Loc, Twine(
"can't disable ") + Ext->key() +
3417 " extension; " + Feature.key() +
3418 " extension requires " + Ext->key() +
3422 clearFeatureBits(Ext->Value, Ext->key());
3429 getTargetStreamer().emitDirectiveOptionArch(Args);
3432 getTargetStreamer().setArchString((*ParseResult)->toString());
3436 if (Option ==
"exact") {
3440 getTargetStreamer().emitDirectiveOptionExact();
3441 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3442 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3446 if (Option ==
"noexact") {
3450 getTargetStreamer().emitDirectiveOptionNoExact();
3451 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3452 setFeatureBits(RISCV::FeatureRelax,
"relax");
3456 if (Option ==
"rvc") {
3460 getTargetStreamer().emitDirectiveOptionRVC();
3461 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3463 getTargetStreamer().setArchString((*ParseResult)->toString());
3467 if (Option ==
"norvc") {
3471 getTargetStreamer().emitDirectiveOptionNoRVC();
3472 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3473 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3475 getTargetStreamer().setArchString((*ParseResult)->toString());
3479 if (Option ==
"pic") {
3483 getTargetStreamer().emitDirectiveOptionPIC();
3484 ParserOptions.IsPicEnabled =
true;
3488 if (Option ==
"nopic") {
3492 getTargetStreamer().emitDirectiveOptionNoPIC();
3493 ParserOptions.IsPicEnabled =
false;
3497 if (Option ==
"relax") {
3501 getTargetStreamer().emitDirectiveOptionRelax();
3502 setFeatureBits(RISCV::FeatureRelax,
"relax");
3506 if (Option ==
"norelax") {
3510 getTargetStreamer().emitDirectiveOptionNoRelax();
3511 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3517 "unknown option, expected 'push', 'pop', "
3518 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3519 "'exact', or 'noexact'");
3527bool RISCVAsmParser::parseDirectiveAttribute() {
3528 MCAsmParser &Parser = getParser();
3534 std::optional<unsigned> Ret =
3537 return Error(TagLoc,
"attribute name not recognised: " + Name);
3541 const MCExpr *AttrExpr;
3548 if (check(!CE, TagLoc,
"expected numeric constant"))
3551 Tag =
CE->getValue();
3557 StringRef StringValue;
3558 int64_t IntegerValue = 0;
3559 bool IsIntegerValue =
true;
3564 IsIntegerValue =
false;
3567 if (IsIntegerValue) {
3568 const MCExpr *ValueExpr;
3574 return Error(ValueExprLoc,
"expected numeric constant");
3575 IntegerValue =
CE->getValue();
3588 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3590 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3593 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3597 getTargetStreamer().emitTextAttribute(
Tag, Result);
3601 getTargetStreamer().setArchString(Result);
3609 .
Cases({
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s"},
true)
3610 .Cases({
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj"},
3612 .
Cases({
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es"},
3621bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3622 MCAsmParser &Parser = getParser();
3629 std::optional<int64_t>
Length;
3639 return Error(ErrorLoc,
3640 "instruction lengths must be a non-zero multiple of two");
3644 return Error(ErrorLoc,
3645 "instruction lengths over 64 bits are not supported");
3651 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3656 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3657 return Error(ErrorLoc,
3658 "instruction length does not match the encoding");
3661 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3664 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3667 if (!getSTI().
hasFeature(RISCV::FeatureStdExtZca) &&
3668 (EncodingDerivedLength == 2))
3669 return Error(ErrorLoc,
"compressed instructions are not allowed");
3671 if (getParser().parseEOL(
"invalid operand for instruction")) {
3672 getParser().eatToEndOfStatement();
3680 Opcode = RISCV::Insn16;
3683 Opcode = RISCV::Insn32;
3686 Opcode = RISCV::Insn48;
3689 Opcode = RISCV::Insn64;
3695 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3697 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3702 return Error(ErrorLoc,
"invalid instruction format");
3704 std::string FormatName = (
".insn_" +
Format).str();
3706 ParseInstructionInfo
Info;
3709 if (parseInstruction(Info, FormatName, L,
Operands))
3721bool RISCVAsmParser::parseDirectiveVariantCC() {
3723 if (getParser().parseIdentifier(Name))
3724 return TokError(
"expected symbol name");
3727 getTargetStreamer().emitDirectiveVariantCC(
3732void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3735 const MCSubtargetInfo &STI = getSTI();
3736 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3739 ++RISCVNumInstrsCompressed;
3743void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3748 for (MCInst &Inst : Seq) {
3749 emitToStreamer(Out, Inst);
3753void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3754 const MCExpr *Symbol,
3756 unsigned SecondOpcode, SMLoc IDLoc,
3764 Out.emitLabel(TmpLabel);
3768 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3773 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3776 .addExpr(RefToLinkTmpLabel));
3779void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3790 STI->
hasFeature(RISCV::FeatureVendorXqcili) &&
3791 !ParserOptions.IsPicEnabled)
3793 Out, MCInstBuilder(RISCV::QC_E_LI).addReg(DestReg).addExpr(Symbol));
3799void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3809 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3810 emitAuipcInstPair(DestReg, DestReg, Symbol,
RISCV::S_GOT_HI, SecondOpcode,
3814void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3823 if (ParserOptions.IsPicEnabled)
3824 emitLoadGlobalAddress(Inst, IDLoc, Out);
3826 emitLoadLocalAddress(Inst, IDLoc, Out);
3829void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3839 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3840 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3841 SecondOpcode, IDLoc, Out);
3844void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3854 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3855 RISCV::ADDI, IDLoc, Out);
3858void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3859 SMLoc IDLoc, MCStreamer &Out,
3868 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3870 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3874 if (getRISCVMCRegisterClass(RISCV::GPRPairRegClassID).
contains(TmpReg)) {
3875 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3876 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3884void RISCVAsmParser::emitQCELILoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3885 SMLoc IDLoc, MCStreamer &Out,
3895 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3899 MCInstBuilder(RISCV::QC_E_LI).addReg(AddrReg).addExpr(Symbol));
3902 const MCExpr *AccessExpr =
3908 struct CompressedForm {
3912 std::optional<CompressedForm> Compressed;
3916 case RISCV::PseudoQCAccessLBU:
3917 Compressed = {RISCV::PseudoQCAccessC_LBU, RISCV::FeatureStdExtZcb};
3919 case RISCV::PseudoQCAccessLH:
3920 Compressed = {RISCV::PseudoQCAccessC_LH, RISCV::FeatureStdExtZcb};
3922 case RISCV::PseudoQCAccessLHU:
3923 Compressed = {RISCV::PseudoQCAccessC_LHU, RISCV::FeatureStdExtZcb};
3925 case RISCV::PseudoQCAccessLW:
3926 Compressed = {RISCV::PseudoQCAccessC_LW, RISCV::FeatureStdExtZca};
3928 case RISCV::PseudoQCAccessSB:
3929 Compressed = {RISCV::PseudoQCAccessC_SB, RISCV::FeatureStdExtZcb};
3931 case RISCV::PseudoQCAccessSH:
3932 Compressed = {RISCV::PseudoQCAccessC_SH, RISCV::FeatureStdExtZcb};
3934 case RISCV::PseudoQCAccessSW:
3935 Compressed = {RISCV::PseudoQCAccessC_SW, RISCV::FeatureStdExtZca};
3942 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(AddrReg);
3943 if (HasTmpReg && CanUseGPRC) {
3946 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(DataReg);
3949 bool UseCompressed =
3950 Compressed && getSTI().hasFeature(Compressed->Feature) && CanUseGPRC;
3952 unsigned ActualOpcode = UseCompressed ? Compressed->Opcode : Opcode;
3955 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3959 .addExpr(AccessExpr));
3961 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3965 .addExpr(AccessExpr));
3969void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3970 int64_t Width, SMLoc IDLoc,
3979 const MCOperand &DestReg = Inst.
getOperand(0);
3980 const MCOperand &SourceReg = Inst.
getOperand(1);
3982 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3983 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3985 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3987 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3992 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3998void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
4005 emitToStreamer(Out, MCInstBuilder(Opcode)
4009 .addReg(MCRegister())
4011 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
4022 "The destination register should not be V0.");
4024 emitToStreamer(Out, MCInstBuilder(Opcode)
4030 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
4042 "The temporary vector register should not be V0.");
4043 emitToStreamer(Out, MCInstBuilder(Opcode)
4047 .addReg(MCRegister())
4049 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4061 "The temporary vector register should not be V0.");
4062 emitToStreamer(Out, MCInstBuilder(Opcode)
4066 .addReg(MCRegister())
4068 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4073 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4078 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
4086bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
4088 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
4091 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
4092 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
4093 "%tprel_add specifier");
4099bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
4101 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
4104 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
4105 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
4106 "%tlsdesc_call specifier");
4112std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
4113 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
4116std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
4117 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
4121std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
4122 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
4126std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultZeroOffset() {
4128 llvm::SMLoc(), llvm::SMLoc(), isRV64());
4135 case RISCV::VLOXSEG2EI8_V:
4136 case RISCV::VLOXSEG2EI16_V:
4137 case RISCV::VLOXSEG2EI32_V:
4138 case RISCV::VLOXSEG2EI64_V:
4139 case RISCV::VLUXSEG2EI8_V:
4140 case RISCV::VLUXSEG2EI16_V:
4141 case RISCV::VLUXSEG2EI32_V:
4142 case RISCV::VLUXSEG2EI64_V:
4144 case RISCV::VLOXSEG3EI8_V:
4145 case RISCV::VLOXSEG3EI16_V:
4146 case RISCV::VLOXSEG3EI32_V:
4147 case RISCV::VLOXSEG3EI64_V:
4148 case RISCV::VLUXSEG3EI8_V:
4149 case RISCV::VLUXSEG3EI16_V:
4150 case RISCV::VLUXSEG3EI32_V:
4151 case RISCV::VLUXSEG3EI64_V:
4153 case RISCV::VLOXSEG4EI8_V:
4154 case RISCV::VLOXSEG4EI16_V:
4155 case RISCV::VLOXSEG4EI32_V:
4156 case RISCV::VLOXSEG4EI64_V:
4157 case RISCV::VLUXSEG4EI8_V:
4158 case RISCV::VLUXSEG4EI16_V:
4159 case RISCV::VLUXSEG4EI32_V:
4160 case RISCV::VLUXSEG4EI64_V:
4162 case RISCV::VLOXSEG5EI8_V:
4163 case RISCV::VLOXSEG5EI16_V:
4164 case RISCV::VLOXSEG5EI32_V:
4165 case RISCV::VLOXSEG5EI64_V:
4166 case RISCV::VLUXSEG5EI8_V:
4167 case RISCV::VLUXSEG5EI16_V:
4168 case RISCV::VLUXSEG5EI32_V:
4169 case RISCV::VLUXSEG5EI64_V:
4171 case RISCV::VLOXSEG6EI8_V:
4172 case RISCV::VLOXSEG6EI16_V:
4173 case RISCV::VLOXSEG6EI32_V:
4174 case RISCV::VLOXSEG6EI64_V:
4175 case RISCV::VLUXSEG6EI8_V:
4176 case RISCV::VLUXSEG6EI16_V:
4177 case RISCV::VLUXSEG6EI32_V:
4178 case RISCV::VLUXSEG6EI64_V:
4180 case RISCV::VLOXSEG7EI8_V:
4181 case RISCV::VLOXSEG7EI16_V:
4182 case RISCV::VLOXSEG7EI32_V:
4183 case RISCV::VLOXSEG7EI64_V:
4184 case RISCV::VLUXSEG7EI8_V:
4185 case RISCV::VLUXSEG7EI16_V:
4186 case RISCV::VLUXSEG7EI32_V:
4187 case RISCV::VLUXSEG7EI64_V:
4189 case RISCV::VLOXSEG8EI8_V:
4190 case RISCV::VLOXSEG8EI16_V:
4191 case RISCV::VLOXSEG8EI32_V:
4192 case RISCV::VLOXSEG8EI64_V:
4193 case RISCV::VLUXSEG8EI8_V:
4194 case RISCV::VLUXSEG8EI16_V:
4195 case RISCV::VLUXSEG8EI32_V:
4196 case RISCV::VLUXSEG8EI64_V:
4202 if (getRISCVMCRegisterClass(RISCV::VRM2RegClassID).
contains(
Reg))
4204 if (getRISCVMCRegisterClass(RISCV::VRM4RegClassID).
contains(
Reg))
4206 if (getRISCVMCRegisterClass(RISCV::VRM8RegClassID).
contains(
Reg))
4213 case RISCV::VFWMMACC_VV_SCALE:
4214 case RISCV::VFQMMACC_VV_SCALE:
4215 case RISCV::VF8WMMACC_VV_SCALE:
4216 case RISCV::VFWIMMACC_VV:
4217 case RISCV::VFQIMMACC_VV:
4218 case RISCV::VF8WIMMACC_VV:
4225bool RISCVAsmParser::validateInstruction(MCInst &Inst,
4229 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
4230 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
4233 if (DestReg == TempReg) {
4234 SMLoc Loc =
Operands.back()->getStartLoc();
4235 return Error(Loc,
"the temporary vector register cannot be the same as "
4236 "the destination register");
4240 if (Opcode == RISCV::PseudoVMSGEU_VX_M || Opcode == RISCV::PseudoVMSGE_VX_M) {
4243 if (MaskReg == RISCV::V0 && DestReg == RISCV::V0) {
4244 SMLoc Loc =
Operands.back()->getStartLoc();
4245 return Error(Loc,
"the destination vector register cannot overlap the "
4246 "mask register unless a temporary register is "
4251 if (Opcode == RISCV::CV_INSERT &&
4254 "the sum of the immediate operands must be less than 32");
4259 case RISCV::TH_LBIA:
4260 case RISCV::TH_LBIB:
4261 case RISCV::TH_LBUIA:
4262 case RISCV::TH_LBUIB:
4263 case RISCV::TH_LHIA:
4264 case RISCV::TH_LHIB:
4265 case RISCV::TH_LHUIA:
4266 case RISCV::TH_LHUIB:
4267 case RISCV::TH_LWIA:
4268 case RISCV::TH_LWIB:
4269 case RISCV::TH_LWUIA:
4270 case RISCV::TH_LWUIB:
4271 case RISCV::TH_LDIA:
4272 case RISCV::TH_LDIB:
4274 return Error(
Operands[1]->getStartLoc(),
"rd and rs1 must be different");
4277 case RISCV::TH_LWUD:
4278 case RISCV::TH_LWD: {
4284 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
4285 SMLoc Loc =
Operands[1]->getStartLoc();
4286 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
4292 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
4296 SMLoc Loc =
Operands[1]->getStartLoc();
4297 return Error(Loc,
"rs1 and rs2 must be different");
4302 auto CheckOperandDoesNotOverlapV0 = [&](
int OperandIdx,
4303 unsigned ParsedIdx) {
4306 "vd, vs1, and vs2 cannot overlap v0.scale");
4311 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4313 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4315 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4316 assert(DestIdx >= 0 && VS1Idx >= 0 && VS2Idx >= 0 &&
4317 "Unexpected Zvvfmm scaled operand list");
4319 if (CheckOperandDoesNotOverlapV0(DestIdx, 1) ||
4320 CheckOperandDoesNotOverlapV0(VS1Idx, 2) ||
4321 CheckOperandDoesNotOverlapV0(VS2Idx, 3))
4325 const MCInstrDesc &MCID = MII.
get(Opcode);
4329 int DestIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4333 const MCParsedAsmOperand *ParsedOp =
Operands[1].get();
4334 if (!ParsedOp->
isReg()) {
4339 assert(ParsedOp->
getReg() == DestReg &&
"Can't find parsed dest operand");
4343 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4347 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4348 assert(VS2Idx >= 0 &&
"No vs2 operand?");
4349 unsigned CheckEncoding =
4352 for (
unsigned i = 0; i < std::max(NF, Lmul); i++) {
4353 if ((DestEncoding + i) == CheckEncoding)
4354 return Error(Loc,
"the destination vector register group cannot overlap"
4355 " the source vector register group");
4360 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4364 unsigned CheckEncoding =
4366 for (
unsigned i = 0; i < Lmul; i++) {
4367 if ((DestEncoding + i) == CheckEncoding)
4369 "the destination vector register group cannot overlap"
4370 " the source vector register group");
4376 int VMIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vm);
4377 assert(VMIdx >= 0 &&
"No vm operand?");
4379 if (DestReg == RISCV::V0) {
4382 return Error(Loc,
"the destination vector register group cannot be V0");
4390 "Unexpected mask operand register");
4392 return Error(Loc,
"the destination vector register group cannot overlap"
4393 " the mask register");
4401 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vmask);
4403 if (MaskReg != RISCV::V0 && MaskReg != RISCV::V1)
4405 "vmask operand only supports v0 or v1");
4408 RISCV::OpName RegOps[] = {RISCV::OpName::vd, RISCV::OpName::vs1,
4409 RISCV::OpName::vs2};
4410 for (RISCV::OpName OpN : RegOps) {
4411 int Idx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), OpN);
4417 for (
unsigned i = 0; i < RegLmul; i++) {
4418 if ((RegEnc + i) == MaskEnc) {
4421 Twine(
"register conflicts with vmask register ") +
4431bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
4439 case RISCV::MOP_RR_7: {
4451 case RISCV::MOP_R_28: {
4469 case RISCV::PseudoC_ADDI_NOP: {
4471 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
4481 if (getSTI().
hasFeature(RISCV::Feature64Bit))
4483 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV32)
4488 case RISCV::PACKW: {
4492 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV64)
4497 case RISCV::PseudoLLAImm:
4498 case RISCV::PseudoLAImm:
4499 case RISCV::PseudoLI: {
4505 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
4517 emitLoadImm(
Reg,
Imm, Out);
4520 case RISCV::PseudoLLA:
4521 emitLoadLocalAddress(Inst, IDLoc, Out);
4523 case RISCV::PseudoLGA:
4524 emitLoadGlobalAddress(Inst, IDLoc, Out);
4526 case RISCV::PseudoLA:
4527 emitLoadAddress(Inst, IDLoc, Out);
4529 case RISCV::PseudoLA_TLS_IE:
4530 emitLoadTLSIEAddress(Inst, IDLoc, Out);
4532 case RISCV::PseudoLA_TLS_GD:
4533 emitLoadTLSGDAddress(Inst, IDLoc, Out);
4535 case RISCV::PseudoLB:
4536 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
4538 case RISCV::PseudoLBU:
4539 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
4541 case RISCV::PseudoLH:
4542 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
4544 case RISCV::PseudoLHU:
4545 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
4547 case RISCV::PseudoLW:
4548 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
4550 case RISCV::PseudoLWU:
4551 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
4553 case RISCV::PseudoLD:
4554 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
4556 case RISCV::PseudoLD_RV32:
4557 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
4559 case RISCV::PseudoFLH:
4560 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
4562 case RISCV::PseudoFLW:
4563 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
4565 case RISCV::PseudoFLD:
4566 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
4568 case RISCV::PseudoFLQ:
4569 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
4571 case RISCV::PseudoSB:
4572 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
4574 case RISCV::PseudoSH:
4575 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
4577 case RISCV::PseudoSW:
4578 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
4580 case RISCV::PseudoSD:
4581 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
4583 case RISCV::PseudoSD_RV32:
4584 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
4586 case RISCV::PseudoQC_E_LB:
4587 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLB, IDLoc, Out,
4590 case RISCV::PseudoQC_E_LBU:
4591 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLBU, IDLoc, Out,
4594 case RISCV::PseudoQC_E_LH:
4595 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLH, IDLoc, Out,
4598 case RISCV::PseudoQC_E_LHU:
4599 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLHU, IDLoc, Out,
4602 case RISCV::PseudoQC_E_LW:
4603 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLW, IDLoc, Out,
4606 case RISCV::PseudoQC_E_SB:
4607 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSB, IDLoc, Out,
4610 case RISCV::PseudoQC_E_SH:
4611 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSH, IDLoc, Out,
4614 case RISCV::PseudoQC_E_SW:
4615 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSW, IDLoc, Out,
4618 case RISCV::PseudoFSH:
4619 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
4621 case RISCV::PseudoFSW:
4622 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
4624 case RISCV::PseudoFSD:
4625 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4627 case RISCV::PseudoFSQ:
4628 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4630 case RISCV::PseudoAddTPRel:
4631 if (checkPseudoAddTPRel(Inst,
Operands))
4634 case RISCV::PseudoTLSDESCCall:
4635 if (checkPseudoTLSDESCCall(Inst,
Operands))
4638 case RISCV::PseudoSEXT_B:
4639 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4641 case RISCV::PseudoSEXT_H:
4642 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4644 case RISCV::PseudoZEXT_H:
4645 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4647 case RISCV::PseudoZEXT_W:
4648 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4650 case RISCV::PseudoVMSGEU_VX_M:
4651 case RISCV::PseudoVMSGEU_VX_M_T:
4652 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4654 case RISCV::PseudoVMSGE_VX_M:
4655 case RISCV::PseudoVMSGE_VX_M_T:
4656 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4658 case RISCV::PseudoVMSGE_VI:
4659 case RISCV::PseudoVMSLT_VI: {
4663 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4665 emitToStreamer(Out, MCInstBuilder(
Opc)
4673 case RISCV::PseudoVMSGEU_VI:
4674 case RISCV::PseudoVMSLTU_VI: {
4681 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4684 emitToStreamer(Out, MCInstBuilder(
Opc)
4692 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4695 emitToStreamer(Out, MCInstBuilder(
Opc)
4705 case RISCV::PseudoCV_ELW:
4706 emitLoadStoreSymbol(Inst, RISCV::CV_ELW, IDLoc, Out,
false);
4710 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 bool regClassIsYGPR(const MCRegisterClass &RC)
static MCRegister convertFPR64ToFPR128(MCRegister Reg)
static MCRegister convertFPR64ToFPR32(MCRegister Reg)
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 MCTargetOptions & getTargetOptions() 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
MCRegisterClass - Base class of TargetRegisterClass.
unsigned getNumRegs() const
getNumRegs - Return the number of registers in this class.
iterator begin() const
begin/end - Return all of the registers in this class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
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.
ArrayRef< SubtargetFeatureKV > getAllProcessorFeatures() const
Return processor features.
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(const RISCVMCOptions &CLOpts, 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.
const AArch64MCOptions & getCLOpts(const MCTargetOptions &Options)
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)
const RISCVMCOptions & getCLOpts(const MCTargetOptions &Options)
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.
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,...