52#define DEBUG_TYPE "riscv-asm-parser"
55 "Number of RISC-V Compressed instructions emitted");
60struct ParserOptionsSet {
67 enum class VTypeState {
78 ParserOptionsSet ParserOptions;
80 SMLoc getLoc()
const {
return getParser().
getTok().
getLoc(); }
81 bool isRV64()
const {
return getSTI().hasFeature(RISCV::Feature64Bit); }
82 bool isRVE()
const {
return getSTI().hasFeature(RISCV::FeatureStdExtE); }
83 bool enableExperimentalExtension()
const {
84 return getSTI().hasFeature(RISCV::Experimental);
87 RISCVTargetStreamer &getTargetStreamer() {
88 assert(getParser().getStreamer().getTargetStreamer() &&
89 "do not have a target streamer");
90 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
91 return static_cast<RISCVTargetStreamer &
>(TS);
94 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
95 unsigned Kind)
override;
97 bool generateImmOutOfRangeError(SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
100 struct NearMissMessage {
105 std::string getCustomOperandDiag(
unsigned MatchError);
107 void FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
108 SmallVectorImpl<NearMissMessage> &NearMissesOut,
110 void ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses, SMLoc IDLoc,
113 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
116 bool MatchingInlineAsm)
override;
119 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
120 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
121 SMLoc &EndLoc)
override;
123 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
126 ParseStatus parseDirective(AsmToken DirectiveID)
override;
128 bool parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
unsigned &Sew,
129 unsigned &Lmul,
bool &Fractional,
bool &TailAgnostic,
130 bool &MaskAgnostic,
bool &AltFmt);
131 bool generateVTypeError(SMLoc ErrorLoc);
133 bool generateXSfmmVTypeError(SMLoc ErrorLoc);
136 void emitToStreamer(MCStreamer &S,
const MCInst &Inst);
140 void emitLoadImm(MCRegister DestReg, int64_t
Value, MCStreamer &Out);
144 void emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
146 unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out);
149 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
152 void emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
155 void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
159 void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
163 void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
166 void emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
167 MCStreamer &Out,
bool HasTmpReg);
172 void emitQCELILoadStoreSymbol(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
173 MCStreamer &Out,
bool HasTmpReg);
176 void emitPseudoExtend(MCInst &Inst,
bool SignExtend, int64_t Width,
177 SMLoc IDLoc, MCStreamer &Out);
180 void emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc, MCStreamer &Out);
205#define GET_ASSEMBLER_HEADER
206#include "RISCVGenAsmMatcher.inc"
236 return parseRegList(
Operands,
true);
242 bool ExpectNegative =
false);
244 return parseZcmpStackAdj(
Operands,
true);
248 bool parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
249 bool parseDataExpr(
const MCExpr *&Res)
override;
251 bool parseDirectiveOption();
252 bool parseDirectiveAttribute();
253 bool parseDirectiveInsn(SMLoc L);
254 bool parseDirectiveVariantCC();
259 bool resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
260 bool FromOptionDirective);
262 void setFeatureBits(
uint64_t Feature, StringRef FeatureString) {
264 MCSubtargetInfo &STI = copySTI();
270 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
274 void clearFeatureBits(
uint64_t Feature, StringRef FeatureString) {
276 MCSubtargetInfo &STI = copySTI();
277 setAvailableFeatures(
282 void pushFeatureBits() {
283 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
284 "These two stacks must be kept synchronized");
285 FeatureBitStack.push_back(getSTI().getFeatureBits());
286 ParserOptionsStack.push_back(ParserOptions);
289 bool popFeatureBits() {
290 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
291 "These two stacks must be kept synchronized");
292 if (FeatureBitStack.empty())
295 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
296 copySTI().setFeatureBits(FeatureBits);
297 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
299 ParserOptions = ParserOptionsStack.pop_back_val();
304 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
305 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
306 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
307 std::unique_ptr<RISCVOperand> defaultSMTVType();
308 std::unique_ptr<RISCVOperand> defaultZeroOffset();
311 enum RISCVMatchResultTy :
unsigned {
312 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
313#define GET_OPERAND_DIAGNOSTIC_TYPES
314#include "RISCVGenAsmMatcher.inc"
315#undef GET_OPERAND_DIAGNOSTIC_TYPES
319 static bool isSymbolDiff(
const MCExpr *Expr);
321 RISCVAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
322 const MCInstrInfo &MII)
323 : MCTargetAsmParser(STI, MII) {
330 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
335 if (RISCVMCOptions::Global.add_build_attributes)
336 getTargetStreamer().emitTargetAttributes(STI,
false);
342 void onBeginOfFile()
override {
345 if (getTargetStreamer().hasTargetABI())
348 Expected<RISCVABI::ABI> ABIOrErr =
352 getTargetStreamer().setTargetABI(
356 getTargetStreamer().setTargetABI(*ABIOrErr);
427 MCRegister OffsetReg;
430 SMLoc StartLoc, EndLoc;
446 RISCVOperand(KindTy K) : Kind(
K) {}
449 RISCVOperand(
const RISCVOperand &o) : MCParsedAsmOperand() {
451 StartLoc =
o.StartLoc;
454 case KindTy::Register:
457 case KindTy::Expression:
460 case KindTy::FPImmediate:
466 case KindTy::SystemRegister:
472 case KindTy::SMTVType:
473 SMTVType =
o.SMTVType;
481 case KindTy::RegList:
484 case KindTy::StackAdj:
485 StackAdj =
o.StackAdj;
493 bool isToken()
const override {
return Kind == KindTy::Token; }
494 bool isReg()
const override {
return Kind == KindTy::Register; }
495 bool isExpr()
const {
return Kind == KindTy::Expression; }
496 bool isV0Reg()
const {
497 return Kind == KindTy::Register &&
Reg.Reg == RISCV::V0;
499 bool isAnyReg()
const {
500 return Kind == KindTy::Register &&
501 (getRISCVMCRegisterClass(RISCV::GPRRegClassID).contains(
Reg.Reg) ||
502 getRISCVMCRegisterClass(RISCV::FPR64RegClassID).contains(
Reg.Reg) ||
503 getRISCVMCRegisterClass(RISCV::VRRegClassID).contains(
Reg.Reg));
505 bool isAnyRegC()
const {
506 return Kind == KindTy::Register &&
507 (getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(
Reg.Reg) ||
508 getRISCVMCRegisterClass(RISCV::FPR64CRegClassID).contains(
Reg.Reg));
510 bool isImm()
const override {
return isExpr(); }
511 bool isMem()
const override {
return false; }
512 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
513 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
514 bool isRegList()
const {
return Kind == KindTy::RegList; }
515 bool isRegListS0()
const {
516 return Kind == KindTy::RegList && RegList.Encoding !=
RISCVZC::RA;
518 bool isStackAdj()
const {
return Kind == KindTy::StackAdj; }
521 return Kind == KindTy::Register &&
522 getRISCVMCRegisterClass(RISCV::GPRRegClassID).contains(
Reg.Reg);
525 bool isYGPR()
const {
526 return Kind == KindTy::Register &&
527 getRISCVMCRegisterClass(RISCV::YGPRRegClassID).contains(
Reg.Reg);
530 bool isGPRPair()
const {
531 return Kind == KindTy::Register &&
532 getRISCVMCRegisterClass(RISCV::GPRPairRegClassID).contains(
Reg.Reg);
535 bool isGPRPairC()
const {
536 return Kind == KindTy::Register &&
537 getRISCVMCRegisterClass(RISCV::GPRPairCRegClassID).contains(
Reg.Reg);
540 bool isGPRPairNoX0()
const {
541 return Kind == KindTy::Register &&
542 getRISCVMCRegisterClass(RISCV::GPRPairNoX0RegClassID)
546 bool isGPRF16()
const {
547 return Kind == KindTy::Register &&
548 getRISCVMCRegisterClass(RISCV::GPRF16RegClassID).contains(
Reg.Reg);
551 bool isGPRF32()
const {
552 return Kind == KindTy::Register &&
553 getRISCVMCRegisterClass(RISCV::GPRF32RegClassID).contains(
Reg.Reg);
556 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
557 bool isGPRAsFPR16()
const {
return isGPRF16() &&
Reg.IsGPRAsFPR; }
558 bool isGPRAsFPR32()
const {
return isGPRF32() &&
Reg.IsGPRAsFPR; }
559 bool isGPRPairAsFPR64()
const {
return isGPRPair() &&
Reg.IsGPRAsFPR; }
561 static bool evaluateConstantExpr(
const MCExpr *Expr, int64_t &
Imm) {
563 Imm =
CE->getValue();
572 template <
int N>
bool isBareSimmNLsb0()
const {
581 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
587 template <
int N>
bool isBareSimmN()
const {
593 return isInt<N>(fixImmediateForRV32(
Imm, isRV64Expr()));
596 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
602 bool isBareSymbol()
const {
605 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
609 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
613 bool isCallSymbol()
const {
616 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
620 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
624 bool isTailCallSymbol()
const {
return isCallSymbol(); }
626 bool isPseudoJumpSymbol()
const {
629 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
633 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
637 bool isTPRelAddSymbol()
const {
640 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
644 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
645 VK == ELF::R_RISCV_TPREL_ADD;
648 bool isTLSDESCCallSymbol()
const {
651 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
655 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
656 VK == ELF::R_RISCV_TLSDESC_CALL;
659 bool isQCAccessSymbol()
const {
662 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
666 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
670 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
674 bool isVTypeI10()
const {
675 if (Kind == KindTy::VType)
679 bool isVTypeI11()
const {
680 if (Kind == KindTy::VType)
685 bool isXSfmmVType()
const {
689 bool isTileLambda()
const {
695 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
698 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
699 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
704 bool isSMTVType()
const {
705 return Kind == KindTy::SMTVType &&
709 bool isSMTI8()
const {
714 bool isLoadFPImm()
const {
717 if (Kind != KindTy::FPImmediate)
720 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
723 return Idx >= 0 &&
Idx != 1;
726 bool isImmXLenLI()
const {
735 return RISCVAsmParser::isSymbolDiff(
getExpr());
738 bool isImmXLenLI_Restricted()
const {
742 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
744 return IsConstantImm &&
748 template <
unsigned N>
bool isUImm()
const {
752 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
756 template <
unsigned N,
unsigned S>
bool isUImmShifted()
const {
760 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
764 template <
class Pred>
bool isUImmPred(Pred p)
const {
768 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
769 return IsConstantImm &&
p(
Imm);
772 bool isUImmLog2XLen()
const {
773 if (isExpr() && isRV64Expr())
778 bool isUImmLog2XLenNonZero()
const {
779 if (isExpr() && isRV64Expr())
784 bool isUImmLog2XLenHalf()
const {
785 if (isExpr() && isRV64Expr())
790 bool isUImm5NonZero()
const {
794 bool isUImm5GT3()
const {
798 bool isUImm4Plus1()
const {
803 bool isUImm5Plus1()
const {
808 bool isUImm6Plus1()
const {
813 bool isUImm5GE6Plus1()
const {
818 bool isUImm5Slist()
const {
819 return isUImmPred([](int64_t
Imm) {
820 return (
Imm == 0) || (
Imm == 1) || (
Imm == 2) || (
Imm == 4) ||
821 (
Imm == 8) || (
Imm == 16) || (
Imm == 15) || (
Imm == 31);
825 bool isUImm8GE32()
const {
829 bool isRnumArg()
const {
831 [](int64_t
Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(10); });
834 bool isRnumArg_0_7()
const {
836 [](int64_t
Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(7); });
839 bool isRnumArg_1_10()
const {
841 [](int64_t
Imm) {
return Imm >= INT64_C(1) &&
Imm <= INT64_C(10); });
844 bool isRnumArg_2_14()
const {
846 [](int64_t
Imm) {
return Imm >= INT64_C(2) &&
Imm <= INT64_C(14); });
849 template <
unsigned N>
bool isSImm()
const {
853 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
854 return IsConstantImm &&
isInt<N>(fixImmediateForRV32(
Imm, isRV64Expr()));
857 bool isYBNDSWImm()
const {
862 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
866 template <
class Pred>
bool isSImmPred(Pred p)
const {
870 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
871 return IsConstantImm &&
p(fixImmediateForRV32(
Imm, isRV64Expr()));
874 bool isSImm5NonZero()
const {
878 bool isSImm6NonZero()
const {
882 bool isCLUIImm()
const {
883 return isUImmPred([](int64_t
Imm) {
888 bool isUImm10Lsb00NonZero()
const {
895 static int64_t fixImmediateForRV32(int64_t
Imm,
bool IsRV64Imm) {
901 bool isSImm12LO()
const {
907 return isInt<12>(fixImmediateForRV32(
Imm, isRV64Expr()));
910 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
913 VK == ELF::R_RISCV_TLSDESC_ADD_LO12);
921 template <
bool (RISCVOperand::*Pred)() const>
922 DiagnosticPredicate isOptionalMemOffset()
const {
926 : DiagnosticPredicate::NearMatch;
929 bool isSImm12Lsb00000()
const {
933 bool isSImm10Lsb0000NonZero()
const {
938 bool isSImm16NonZero()
const {
942 bool isUImm16NonZero()
const {
946 bool isSImm20LI()
const {
952 return isInt<20>(fixImmediateForRV32(
Imm, isRV64Expr()));
955 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
959 bool isSImm8PLI_B()
const {
return isSImm<8>() || isUImm<8>(); }
960 bool isSImm10PLUI()
const {
return isSImm<10>() || isUImm<10>(); }
962 bool isSImm10PLI_H()
const {
963 return isSImm<10>() || isUImmPred([](int64_t
Imm) {
967 bool isSImm10PLI_W()
const {
968 return isSImm<10>() || isUImmPred([](int64_t
Imm) {
973 bool isUImm20LUI()
const {
982 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
983 (VK == ELF::R_RISCV_HI20 || VK == ELF::R_RISCV_TPREL_HI20);
986 bool isUImm20AUIPC()
const {
995 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
997 VK == ELF::R_RISCV_TLS_GOT_HI20 || VK == ELF::R_RISCV_TLS_GD_HI20 ||
998 VK == ELF::R_RISCV_TLSDESC_HI20);
1001 bool isImmZero()
const {
1002 return isUImmPred([](int64_t
Imm) {
return 0 ==
Imm; });
1005 bool isImmThree()
const {
1006 return isUImmPred([](int64_t
Imm) {
return 3 ==
Imm; });
1009 bool isImmFour()
const {
1010 return isUImmPred([](int64_t
Imm) {
return 4 ==
Imm; });
1013 bool isImm5Zibi()
const {
1018 bool isSImm5Plus1()
const {
1023 bool isSImm18Lsb0()
const {
1027 bool isSImm19Lsb00()
const {
1031 bool isSImm20Lsb000()
const {
1035 bool isSImm32Lsb0()
const {
1040 SMLoc getStartLoc()
const override {
return StartLoc; }
1042 SMLoc getEndLoc()
const override {
return EndLoc; }
1045 bool isRV64Expr()
const {
1046 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1050 MCRegister
getReg()
const override {
1051 assert(Kind == KindTy::Register &&
"Invalid type access!");
1055 StringRef getSysReg()
const {
1056 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
1057 return StringRef(SysReg.Data, SysReg.Length);
1060 const MCExpr *
getExpr()
const {
1061 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1066 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1071 assert(Kind == KindTy::Token &&
"Invalid type access!");
1075 unsigned getVType()
const {
1076 assert(Kind == KindTy::VType &&
"Invalid type access!");
1081 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1085 unsigned getFence()
const {
1086 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1091 assert(Kind == KindTy::SMTVType &&
"Invalid type access!");
1092 return SMTVType.SMTVType;
1095 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1104 case KindTy::Expression:
1107 OS <<
' ' << (Expr.IsRV64 ?
"rv64" :
"rv32") <<
'>';
1109 case KindTy::FPImmediate:
1110 OS <<
"<fpimm: " << FPImm.Val <<
">";
1112 case KindTy::Register:
1114 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1119 case KindTy::SystemRegister:
1120 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1129 OS << roundingModeToString(getFRM());
1132 case KindTy::SMTVType:
1133 OS <<
"<smtvtype: ";
1134 OS << SMTVTypeModeToString(getSMTVType());
1142 case KindTy::RegList:
1147 case KindTy::StackAdj:
1148 OS <<
"<stackadj: ";
1152 case KindTy::RegReg:
1153 OS <<
"<RegReg: BaseReg " <<
RegName(
RegReg.BaseReg) <<
" OffsetReg "
1159 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1160 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1167 static std::unique_ptr<RISCVOperand>
1168 createReg(MCRegister
Reg, SMLoc S, SMLoc
E,
bool IsGPRAsFPR =
false) {
1169 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1171 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1177 static std::unique_ptr<RISCVOperand> createExpr(
const MCExpr *Val, SMLoc S,
1178 SMLoc
E,
bool IsRV64) {
1179 auto Op = std::make_unique<RISCVOperand>(KindTy::Expression);
1180 Op->Expr.Expr = Val;
1181 Op->Expr.IsRV64 = IsRV64;
1187 static std::unique_ptr<RISCVOperand> createFPImm(
uint64_t Val, SMLoc S) {
1188 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1189 Op->FPImm.Val = Val;
1195 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1196 unsigned Encoding) {
1197 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1198 Op->SysReg.Data = Str.data();
1199 Op->SysReg.Length = Str.size();
1206 static std::unique_ptr<RISCVOperand>
1208 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1215 static std::unique_ptr<RISCVOperand>
1217 auto Op = std::make_unique<RISCVOperand>(KindTy::SMTVType);
1218 Op->SMTVType.SMTVType = VType;
1224 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val, SMLoc S) {
1225 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1226 Op->Fence.Val = Val;
1232 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI, SMLoc S) {
1233 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1234 Op->VType.Val = VTypeI;
1240 static std::unique_ptr<RISCVOperand> createRegList(
unsigned RlistEncode,
1242 auto Op = std::make_unique<RISCVOperand>(KindTy::RegList);
1248 static std::unique_ptr<RISCVOperand>
1249 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {
1250 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1252 Op->RegReg.OffsetReg = OffsetReg;
1258 static std::unique_ptr<RISCVOperand> createStackAdj(
unsigned StackAdj, SMLoc S) {
1259 auto Op = std::make_unique<RISCVOperand>(KindTy::StackAdj);
1260 Op->StackAdj.Val = StackAdj;
1265 static void addExpr(MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1266 assert(Expr &&
"Expr shouldn't be null!");
1278 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1279 assert(
N == 1 &&
"Invalid number of operands!");
1283 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1284 assert(
N == 1 &&
"Invalid number of operands!");
1285 addExpr(Inst,
getExpr(), isRV64Expr());
1288 template <
unsigned Bits>
1289 void addSExtImmOperands(MCInst &Inst,
unsigned N)
const {
1290 assert(
N == 1 &&
"Invalid number of operands!");
1297 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
1298 assert(
N == 1 &&
"Invalid number of operands!");
1300 addExpr(Inst,
getExpr(), isRV64Expr());
1305 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1309 void addFenceArgOperands(MCInst &Inst,
unsigned N)
const {
1310 assert(
N == 1 &&
"Invalid number of operands!");
1314 void addCSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
1315 assert(
N == 1 &&
"Invalid number of operands!");
1322 void addVTypeIOperands(MCInst &Inst,
unsigned N)
const {
1323 assert(
N == 1 &&
"Invalid number of operands!");
1325 if (Kind == KindTy::Expression) {
1326 [[maybe_unused]]
bool IsConstantImm =
1328 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1335 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1336 assert(
N == 1 &&
"Invalid number of operands!");
1340 void addRegRegOperands(MCInst &Inst,
unsigned N)
const {
1341 assert(
N == 2 &&
"Invalid number of operands!");
1346 void addStackAdjOperands(MCInst &Inst,
unsigned N)
const {
1347 assert(
N == 1 &&
"Invalid number of operands!");
1351 void addFRMArgOperands(MCInst &Inst,
unsigned N)
const {
1352 assert(
N == 1 &&
"Invalid number of operands!");
1356 void addSMTVTypeOperand(MCInst &Inst,
unsigned N)
const {
1357 assert(
N == 1 &&
"Invalid number of operands!");
1363#define GET_REGISTER_MATCHER
1364#define GET_SUBTARGET_FEATURE_NAME
1365#define GET_MATCHER_IMPLEMENTATION
1366#define GET_MNEMONIC_SPELL_CHECKER
1367#include "RISCVGenAsmMatcher.inc"
1370 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1371 return Reg - RISCV::F0_D + RISCV::F0_H;
1375 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1376 return Reg - RISCV::F0_D + RISCV::F0_F;
1380 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1381 return Reg - RISCV::F0_D + RISCV::F0_Q;
1385 assert(
Reg >= RISCV::X0 &&
Reg <= RISCV::X31 &&
"Invalid register");
1386 return Reg - RISCV::X0 + RISCV::X0_Y;
1391 unsigned RegClassID;
1392 if (Kind == MCK_VRM2)
1393 RegClassID = RISCV::VRM2RegClassID;
1394 else if (Kind == MCK_VRM4)
1395 RegClassID = RISCV::VRM4RegClassID;
1396 else if (Kind == MCK_VRM8)
1397 RegClassID = RISCV::VRM8RegClassID;
1401 &getRISCVMCRegisterClass(RegClassID));
1405 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1406 return Reg - RISCV::F0_D + RISCV::F0_Q2;
1411 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1413 return Match_InvalidOperand;
1415 MCRegister
Reg =
Op.getReg();
1417 getRISCVMCRegisterClass(RISCV::FPR64RegClassID).contains(
Reg);
1419 getRISCVMCRegisterClass(RISCV::FPR64CRegClassID).contains(
Reg);
1420 bool IsRegVR = getRISCVMCRegisterClass(RISCV::VRRegClassID).contains(
Reg);
1422 if (
Op.isGPR() && Kind == MCK_YGPR) {
1425 return Match_Success;
1427 if (IsRegFPR64 && Kind == MCK_FPR256) {
1429 return Match_Success;
1431 if (IsRegFPR64 && Kind == MCK_FPR128) {
1433 return Match_Success;
1437 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1438 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1440 return Match_Success;
1444 if (IsRegFPR64 && Kind == MCK_FPR16) {
1446 return Match_Success;
1448 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1449 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_H;
1450 return Match_Success;
1452 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1453 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_W;
1454 return Match_Success;
1461 if (getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg) &&
1462 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1464 return Match_Success;
1468 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1471 return Match_InvalidOperand;
1472 return Match_Success;
1474 return Match_InvalidOperand;
1477bool RISCVAsmParser::generateImmOutOfRangeError(
1478 SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
1479 const Twine &
Msg =
"immediate must be an integer in the range") {
1486std::string RISCVAsmParser::getCustomOperandDiag(
unsigned MatchError) {
1488 StringRef
Msg =
"immediate must be an integer in the range") {
1489 return (
Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]").str();
1492 switch (MatchError) {
1496 if (
const char *Diag = getMatchKindDiag((RISCVMatchResultTy)MatchError))
1498 return std::string();
1499 case Match_InvalidImmXLenLI:
1501 return "operand must be a constant 64-bit integer";
1502 return Range(std::numeric_limits<int32_t>::min(),
1503 std::numeric_limits<uint32_t>::max());
1504 case Match_InvalidImmXLenLI_Restricted:
1506 return "operand either must be a constant 64-bit integer "
1507 "or a bare symbol name";
1508 return Range(std::numeric_limits<int32_t>::min(),
1509 std::numeric_limits<uint32_t>::max(),
1510 "operand either must be a bare symbol name or an immediate "
1511 "integer in the range");
1512 case Match_InvalidUImmLog2XLen:
1514 return Range(0, (1 << 6) - 1);
1515 return Range(0, (1 << 5) - 1);
1516 case Match_InvalidUImmLog2XLenNonZero:
1518 return Range(1, (1 << 6) - 1);
1519 return Range(1, (1 << 5) - 1);
1520 case Match_InvalidUImm1:
1521 return Range(0, (1 << 1) - 1);
1522 case Match_InvalidUImm2:
1523 return Range(0, (1 << 2) - 1);
1524 case Match_InvalidUImm2Lsb0:
1525 return Range(0, 2,
"immediate must be one of");
1526 case Match_InvalidUImm3:
1527 return Range(0, (1 << 3) - 1);
1528 case Match_InvalidUImm4:
1529 return Range(0, (1 << 4) - 1);
1530 case Match_InvalidUImm4Plus1:
1531 return Range(1, (1 << 4));
1532 case Match_InvalidUImm5:
1533 return Range(0, (1 << 5) - 1);
1534 case Match_InvalidUImm5NonZero:
1535 return Range(1, (1 << 5) - 1);
1536 case Match_InvalidUImm5GT3:
1537 return Range(4, (1 << 5) - 1);
1538 case Match_InvalidUImm5Plus1:
1539 return Range(1, (1 << 5));
1540 case Match_InvalidUImm5GE6Plus1:
1541 return Range(6, (1 << 5));
1542 case Match_InvalidUImm5Slist:
1543 return "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31";
1544 case Match_InvalidUImm6:
1545 return Range(0, (1 << 6) - 1);
1546 case Match_InvalidUImm6Plus1:
1547 return Range(1, (1 << 6));
1548 case Match_InvalidUImm7:
1549 return Range(0, (1 << 7) - 1);
1550 case Match_InvalidUImm8:
1551 return Range(0, (1 << 8) - 1);
1552 case Match_InvalidUImm8GE32:
1553 return Range(32, (1 << 8) - 1);
1554 case Match_InvalidSImm5:
1555 return Range(-(1 << 4), (1 << 4) - 1);
1556 case Match_InvalidSImm5NonZero:
1557 return Range(-(1 << 4), (1 << 4) - 1,
1558 "immediate must be non-zero in the range");
1559 case Match_InvalidSImm6:
1560 return Range(-(1 << 5), (1 << 5) - 1);
1561 case Match_InvalidSImm6NonZero:
1562 return Range(-(1 << 5), (1 << 5) - 1,
1563 "immediate must be non-zero in the range");
1564 case Match_InvalidCLUIImm:
1565 return Range(1, (1 << 5) - 1,
"immediate must be in [0xfffe0, 0xfffff] or");
1566 case Match_InvalidUImm5Lsb0:
1567 return Range(0, (1 << 5) - 2,
1568 "immediate must be a multiple of 2 bytes in the range");
1569 case Match_InvalidUImm6Lsb0:
1570 return Range(0, (1 << 6) - 2,
1571 "immediate must be a multiple of 2 bytes in the range");
1572 case Match_InvalidUImm6Lsb000:
1573 return Range(0, (1 << 6) - 8,
1574 "immediate must be a multiple of 8 in the range");
1575 case Match_InvalidUImm7Lsb00:
1576 return Range(0, (1 << 7) - 4,
1577 "immediate must be a multiple of 4 bytes in the range");
1578 case Match_InvalidUImm8Lsb00:
1579 return Range(0, (1 << 8) - 4,
1580 "immediate must be a multiple of 4 bytes in the range");
1581 case Match_InvalidUImm8Lsb000:
1582 return Range(0, (1 << 8) - 8,
1583 "immediate must be a multiple of 8 bytes in the range");
1584 case Match_InvalidUImm9:
1585 return Range(0, (1 << 9) - 1,
"immediate offset must be in the range");
1586 case Match_InvalidBareSImm9Lsb0:
1587 return Range(-(1 << 8), (1 << 8) - 2,
1588 "immediate must be a multiple of 2 bytes in the range");
1589 case Match_InvalidUImm9Lsb000:
1590 return Range(0, (1 << 9) - 8,
1591 "immediate must be a multiple of 8 bytes in the range");
1592 case Match_InvalidSImm8PLI_B:
1593 return Range(-(1 << 7), (1 << 8) - 1);
1594 case Match_InvalidSImm10:
1595 case Match_InvalidSImm10PLI_H:
1596 case Match_InvalidSImm10PLI_W:
1597 return Range(-(1 << 9), (1 << 9) - 1);
1598 case Match_InvalidSImm10PLUI:
1599 return Range(-(1 << 9), (1 << 10) - 1);
1600 case Match_InvalidUImm10Lsb00NonZero:
1601 return Range(4, (1 << 10) - 4,
1602 "immediate must be a multiple of 4 bytes in the range");
1603 case Match_InvalidSImm10Lsb0000NonZero:
1605 -(1 << 9), (1 << 9) - 16,
1606 "immediate must be a multiple of 16 bytes and non-zero in the range");
1607 case Match_InvalidSImm11:
1608 return Range(-(1 << 10), (1 << 10) - 1);
1609 case Match_InvalidBareSImm11Lsb0:
1610 return Range(-(1 << 10), (1 << 10) - 2,
1611 "immediate must be a multiple of 2 bytes in the range");
1612 case Match_InvalidUImm10:
1613 return Range(0, (1 << 10) - 1);
1614 case Match_InvalidUImm11:
1615 return Range(0, (1 << 11) - 1);
1616 case Match_InvalidUImm14Lsb00:
1617 return Range(0, (1 << 14) - 4,
1618 "immediate must be a multiple of 4 bytes in the range");
1619 case Match_InvalidUImm16NonZero:
1620 return Range(1, (1 << 16) - 1);
1621 case Match_InvalidSImm12:
1622 return Range(-(1 << 11), (1 << 11) - 1);
1623 case Match_InvalidSImm12LO:
1624 return Range(-(1 << 11), (1 << 11) - 1,
1625 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo "
1626 "specifier or an integer in the range");
1627 case Match_InvalidBareSImm12Lsb0:
1628 return Range(-(1 << 11), (1 << 11) - 2,
1629 "immediate must be a multiple of 2 bytes in the range");
1630 case Match_InvalidSImm12Lsb00000:
1631 return Range(-(1 << 11), (1 << 11) - 32,
1632 "immediate must be a multiple of 32 bytes in the range");
1633 case Match_InvalidBareSImm13Lsb0:
1634 return Range(-(1 << 12), (1 << 12) - 2,
1635 "immediate must be a multiple of 2 bytes in the range");
1636 case Match_InvalidSImm16:
1637 return Range(-(1 << 15), (1 << 15) - 1);
1638 case Match_InvalidSImm16NonZero:
1639 return Range(-(1 << 15), (1 << 15) - 1,
1640 "immediate must be non-zero in the range");
1641 case Match_InvalidSImm20LI:
1642 return Range(-(1 << 19), (1 << 19) - 1,
1643 "operand must be a symbol with a %qc.abs20 specifier or an "
1644 "integer in the range");
1645 case Match_InvalidUImm20LUI:
1646 return Range(0, (1 << 20) - 1,
1647 "operand must be a symbol with %hi/%tprel_hi specifier or an "
1648 "integer in the range");
1649 case Match_InvalidUImm20:
1650 return Range(0, (1 << 20) - 1);
1651 case Match_InvalidUImm20AUIPC:
1654 "operand must be a symbol with a "
1655 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
1656 "or an integer in the range");
1657 case Match_InvalidBareSImm21Lsb0:
1658 return Range(-(1 << 20), (1 << 20) - 2,
1659 "immediate must be a multiple of 2 bytes in the range");
1660 case Match_InvalidCSRSystemRegister:
1661 return Range(0, (1 << 12) - 1,
1662 "operand must be a valid system register name or an integer "
1664 case Match_InvalidImm5Zibi:
1665 return Range(-1, (1 << 5) - 1,
"immediate must be non-zero in the range");
1666 case Match_InvalidVTypeI:
1667 return "operand must be "
1668 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]";
1669 case Match_InvalidSImm5Plus1:
1670 return Range(-(1 << 4) + 1, (1 << 4),
"immediate must be in the range");
1671 case Match_InvalidSImm18:
1672 return Range(-(1 << 17), (1 << 17) - 1);
1673 case Match_InvalidSImm18Lsb0:
1674 return Range(-(1 << 17), (1 << 17) - 2,
1675 "immediate must be a multiple of 2 bytes in the range");
1676 case Match_InvalidSImm19Lsb00:
1677 return Range(-(1 << 18), (1 << 18) - 4,
1678 "immediate must be a multiple of 4 bytes in the range");
1679 case Match_InvalidSImm20Lsb000:
1680 return Range(-(1 << 19), (1 << 19) - 8,
1681 "immediate must be a multiple of 8 bytes in the range");
1682 case Match_InvalidSImm26:
1683 return Range(-(1 << 25), (1 << 25) - 1);
1685 case Match_InvalidBareSymbolQC_E_LI:
1688 case Match_InvalidBareSImm32:
1689 return Range(std::numeric_limits<int32_t>::min(),
1690 std::numeric_limits<uint32_t>::max());
1691 case Match_InvalidBareSImm32Lsb0:
1692 return Range(std::numeric_limits<int32_t>::min(),
1693 std::numeric_limits<int32_t>::max() - 1,
1694 "operand must be a multiple of 2 bytes in the range");
1695 case Match_InvalidRnumArg:
1696 return Range(0, 10);
1697 case Match_InvalidStackAdj:
1698 return "stack adjustment is invalid for this instruction and register "
1700 case Match_InvalidYBNDSWImm:
1701 return "immediate must be an integer in the range "
1702 "[1, 255], a multiple of 8 in the range [256, 504], "
1703 "or a multiple of 16 in the range [512, 4096]";
1710void RISCVAsmParser::FilterNearMisses(
1711 SmallVectorImpl<NearMissInfo> &NearMissesIn,
1712 SmallVectorImpl<NearMissMessage> &NearMissesOut, SMLoc IDLoc,
1716 std::multimap<unsigned, unsigned> OperandMissesSeen;
1717 SmallSet<FeatureBitset, 4> FeatureMissesSeen;
1718 bool ReportedTooFewOperands =
false;
1719 bool ReportedTooManyOperands =
false;
1721 for (NearMissInfo &
I : NearMissesIn) {
1722 switch (
I.getKind()) {
1725 ((RISCVOperand &)*
Operands[
I.getOperandIndex()]).getStartLoc();
1730 if (
I.getOperandClass() == InvalidMatchClass) {
1731 if (!ReportedTooManyOperands) {
1733 OperandLoc,
"unexpected extra operand for instruction"});
1734 ReportedTooManyOperands =
true;
1739 std::string OperandDiag = getCustomOperandDiag(
I.getOperandError());
1743 unsigned DupCheckMatchClass =
1744 OperandDiag.empty() ? ~0
U :
I.getOperandClass();
1745 auto PrevReports = OperandMissesSeen.equal_range(
I.getOperandIndex());
1747 PrevReports.first, PrevReports.second,
1748 [DupCheckMatchClass](
const std::pair<unsigned, unsigned> Pair) {
1749 if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
1750 return Pair.second == DupCheckMatchClass;
1751 return isSubclass((MatchClassKind)DupCheckMatchClass,
1752 (MatchClassKind)Pair.second);
1755 OperandMissesSeen.insert(
1756 std::make_pair(
I.getOperandIndex(), DupCheckMatchClass));
1758 NearMissMessage Message;
1759 Message.Loc = OperandLoc;
1760 if (!OperandDiag.empty()) {
1761 Message.Message = OperandDiag;
1763 Message.Message =
"invalid operand for instruction";
1765 dbgs() <<
"Missing diagnostic string for operand class "
1766 << getMatchClassName((MatchClassKind)
I.getOperandClass())
1767 <<
I.getOperandClass() <<
", error " <<
I.getOperandError()
1768 <<
", opcode " << MII.
getName(
I.getOpcode()) <<
"\n");
1774 const FeatureBitset &MissingFeatures =
I.getFeatures();
1776 if (!FeatureMissesSeen.
insert(MissingFeatures).second)
1779 NearMissMessage Message;
1780 Message.Loc = IDLoc;
1781 bool FirstFeature =
true;
1782 Message.Message =
"instruction requires the following:";
1783 for (
unsigned Feature : MissingFeatures) {
1784 Message.Message += FirstFeature ?
" " :
", ";
1786 FirstFeature =
false;
1796 if (!ReportedTooFewOperands) {
1797 SMLoc EndLoc = ((RISCVOperand &)*
Operands.back()).getEndLoc();
1799 NearMissMessage{EndLoc,
"too few operands for instruction"});
1800 ReportedTooFewOperands =
true;
1812void RISCVAsmParser::ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses,
1815 FilterNearMisses(NearMisses, Messages, IDLoc,
Operands);
1820 Error(IDLoc,
"invalid instruction");
1823 Error(Messages[0].Loc, Messages[0].Message);
1828 "invalid instruction, any one of the following would fix this:");
1829 for (
auto &M : Messages)
1834bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1838 bool MatchingInlineAsm) {
1843 MatchInstructionImpl(
Operands, Inst, &NearMisses, MatchingInlineAsm);
1848 if (validateInstruction(Inst,
Operands))
1850 return processInstruction(Inst, IDLoc,
Operands, Out);
1851 case Match_MnemonicFail: {
1852 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1853 std::string Suggestion = RISCVMnemonicSpellCheck(
1855 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1857 case Match_NearMisses:
1858 ReportNearMisses(NearMisses, IDLoc,
Operands);
1869MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name)
const {
1878 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1879 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1880 static_assert(RISCV::F0_D < RISCV::F0_Q,
"FPR matching must be updated");
1883 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1888bool RISCVAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1890 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1891 return Error(StartLoc,
"invalid register name");
1895ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1897 const AsmToken &Tok = getParser().getTok();
1900 StringRef
Name = getLexer().getTok().getIdentifier();
1912 SMLoc FirstS = getLoc();
1913 bool HadParens =
false;
1920 size_t ReadCount = getLexer().peekTokens(Buf);
1923 LParen = getParser().getTok();
1928 switch (getLexer().getKind()) {
1931 getLexer().UnLex(LParen);
1934 StringRef
Name = getLexer().getTok().getIdentifier();
1939 getLexer().UnLex(LParen);
1943 Operands.push_back(RISCVOperand::createToken(
"(", FirstS));
1945 SMLoc
E = getTok().getEndLoc();
1947 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
1952 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
1963 switch (getLexer().getKind()) {
1973 if (getParser().parseExpression(Res,
E))
1978 int64_t
Imm =
CE->getValue();
1980 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1989 if (getParser().parseIdentifier(Identifier))
1992 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1995 "Unexpected opcode");
1998 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2008 return generateImmOutOfRangeError(
2010 "opcode must be a valid opcode name or an immediate in the range");
2018 switch (getLexer().getKind()) {
2028 if (getParser().parseExpression(Res,
E))
2033 int64_t
Imm =
CE->getValue();
2034 if (
Imm >= 0 &&
Imm <= 2) {
2035 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2044 if (getParser().parseIdentifier(Identifier))
2048 if (Identifier ==
"C0")
2050 else if (Identifier ==
"C1")
2052 else if (Identifier ==
"C2")
2059 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2068 return generateImmOutOfRangeError(
2070 "opcode must be a valid opcode name or an immediate in the range");
2077 auto SysRegFromConstantInt = [
this](
const MCExpr *
E, SMLoc S) {
2079 int64_t
Imm =
CE->getValue();
2081 auto Range = RISCVSysReg::lookupSysRegByEncoding(
Imm);
2085 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2088 return RISCVOperand::createSysReg(
2089 RISCVSysReg::getSysRegStr(
Reg.Name), S,
Imm);
2093 return RISCVOperand::createSysReg(
"", S,
Imm);
2096 return std::unique_ptr<RISCVOperand>();
2099 switch (getLexer().getKind()) {
2109 if (getParser().parseExpression(Res))
2112 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
2113 Operands.push_back(std::move(SysOpnd));
2117 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2121 if (getParser().parseIdentifier(Identifier))
2124 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
2127 if (SysReg->IsDeprecatedName) {
2129 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
2131 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2133 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
2134 RISCVSysReg::getSysRegStr(
Reg.Name) +
"'");
2139 const auto &FeatureBits = getSTI().getFeatureBits();
2140 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
2141 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
2142 const auto *Feature =
2144 return SysReg->FeaturesRequired[Feature.Value];
2146 std::string ErrorMsg =
2147 std::string(
"system register '") +
2148 std::string(RISCVSysReg::getSysRegStr(SysReg->Name)) +
"' ";
2149 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
2150 ErrorMsg +=
"is RV32 only";
2152 ErrorMsg +=
" and ";
2156 "requires '" + std::string(Feature->key()) +
"' to be enabled";
2159 return Error(S, ErrorMsg);
2162 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
2172 Operands.push_back(std::move(SysOpnd));
2177 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2178 "operand must be a valid system register "
2179 "name or an integer in the range");
2183 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2195 StringRef
Identifier = getTok().getIdentifier();
2196 if (
Identifier.compare_insensitive(
"inf") == 0) {
2199 getTok().getEndLoc(), isRV64()));
2200 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2203 getTok().getEndLoc(), isRV64()));
2204 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2207 getTok().getEndLoc(), isRV64()));
2209 return TokError(
"invalid floating point literal");
2220 const AsmToken &Tok = getTok();
2222 return TokError(
"invalid floating point immediate");
2225 APFloat RealVal(APFloat::IEEEdouble());
2227 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2229 return TokError(
"invalid floating point representation");
2232 RealVal.changeSign();
2234 Operands.push_back(RISCVOperand::createFPImm(
2235 RealVal.bitcastToAPInt().getZExtValue(), S));
2247 switch (getLexer().getKind()) {
2259 if (getParser().parseExpression(Res,
E))
2263 return parseOperandWithSpecifier(
Operands);
2266 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2276 const MCExpr *Expr =
nullptr;
2277 bool Failed = parseExprWithSpecifier(Expr,
E);
2279 Operands.push_back(RISCVOperand::createExpr(Expr, S,
E, isRV64()));
2283bool RISCVAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
2284 SMLoc Loc = getLoc();
2286 return TokError(
"expected '%' relocation specifier");
2287 StringRef
Identifier = getParser().getTok().getIdentifier();
2290 return TokError(
"invalid relocation specifier");
2296 const MCExpr *SubExpr;
2297 if (getParser().parseParenExpression(SubExpr,
E))
2304bool RISCVAsmParser::parseDataExpr(
const MCExpr *&Res) {
2307 return parseExprWithSpecifier(Res,
E);
2308 return getParser().parseExpression(Res);
2318 StringRef
Identifier = getTok().getIdentifier();
2328 if (getParser().parseExpression(Res,
E))
2331 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2341 std::string
Identifier(getTok().getIdentifier());
2347 SMLoc Loc = getLoc();
2348 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2349 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2363 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2375 std::string
Identifier(getTok().getIdentifier());
2381 SMLoc Loc = getLoc();
2382 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2383 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2397 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2406 if (getParser().parseExpression(Res,
E))
2409 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef)
2410 return Error(S,
"operand must be a valid jump target");
2413 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2434bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2435 unsigned &Sew,
unsigned &Lmul,
2436 bool &Fractional,
bool &TailAgnostic,
2437 bool &MaskAgnostic,
bool &AltFmt) {
2442 if (State < VTypeState::SeenSew &&
Identifier.consume_front(
"e")) {
2444 if (Identifier ==
"16alt") {
2447 }
else if (Identifier ==
"8alt") {
2457 State = VTypeState::SeenSew;
2461 if (State < VTypeState::SeenLmul &&
Identifier.consume_front(
"m")) {
2464 if (Identifier ==
"a" || Identifier ==
"u") {
2466 State = VTypeState::SeenMaskPolicy;
2477 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2478 unsigned MinLMUL = ELEN / 8;
2481 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2482 Twine(MinLMUL) +
" is reserved");
2485 State = VTypeState::SeenLmul;
2489 if (State < VTypeState::SeenTailPolicy &&
Identifier.starts_with(
"t")) {
2490 if (Identifier ==
"ta")
2491 TailAgnostic =
true;
2492 else if (Identifier ==
"tu")
2493 TailAgnostic =
false;
2497 State = VTypeState::SeenTailPolicy;
2501 if (State < VTypeState::SeenMaskPolicy &&
Identifier.starts_with(
"m")) {
2502 if (Identifier ==
"ma")
2503 MaskAgnostic =
true;
2504 else if (Identifier ==
"mu")
2505 MaskAgnostic =
false;
2509 State = VTypeState::SeenMaskPolicy;
2522 bool Fractional =
false;
2523 bool TailAgnostic =
false;
2524 bool MaskAgnostic =
false;
2527 VTypeState State = VTypeState::SeenNothingYet;
2529 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2530 MaskAgnostic, AltFmt)) {
2532 if (State == VTypeState::SeenNothingYet)
2541 State == VTypeState::SeenNothingYet)
2542 return generateVTypeError(S);
2546 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2547 unsigned MaxSEW = ELEN / Lmul;
2549 if (MaxSEW >= 8 && Sew > MaxSEW)
2550 Warning(S,
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2551 " and LMUL == mf" + Twine(Lmul) +
2552 " may not be compatible with all RVV implementations");
2557 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2561bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2562 return Error(ErrorLoc,
2564 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2584 if (Identifier !=
"16alt")
2613 Operands.push_back(RISCVOperand::createVType(
2619 return generateXSfmmVTypeError(S);
2622bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
2623 return Error(ErrorLoc,
"operand must be e[8|16|16alt|32|64],w[1|2|4]");
2630 StringRef
Name = getLexer().getTok().getIdentifier();
2631 if (!
Name.consume_back(
".t")) {
2635 return Error(getLoc(),
"expected '.t' suffix");
2642 if (
Reg != RISCV::V0)
2645 SMLoc
E = getTok().getEndLoc();
2647 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2655 StringRef
Name = getLexer().getTok().getIdentifier();
2656 if (!
Name.consume_back(
".scale"))
2657 return Error(getLoc(),
"expected '.scale' suffix");
2662 if (
Reg != RISCV::V0)
2665 SMLoc
E = getTok().getEndLoc();
2667 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2676 StringRef
Name = getLexer().getTok().getIdentifier();
2677 if (!
Name.consume_front(
"L") && !
Name.consume_front(
"l"))
2682 return Error(S,
"operand must be L1, L2, L4, L8, L16, L32, or L64");
2684 unsigned EncodedLambda =
Log2_32(Lambda) + 1;
2686 SMLoc
E = getTok().getEndLoc();
2688 Operands.push_back(RISCVOperand::createExpr(
2694 if (!isRV64() || getSTI().
hasFeature(RISCV::FeatureStdExtF))
2704 StringRef
Name = getLexer().getTok().getIdentifier();
2710 SMLoc
E = getTok().getEndLoc();
2712 Operands.push_back(RISCVOperand::createReg(
2718 if (isRV64() || getSTI().
hasFeature(RISCV::FeatureStdExtF))
2724 StringRef
Name = getLexer().getTok().getIdentifier();
2730 if (!getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg))
2733 if ((
Reg - RISCV::X0) & 1) {
2736 if (getSTI().
hasFeature(RISCV::FeatureStdExtZfinx))
2737 return TokError(
"double precision floating point operands must use even "
2738 "numbered X register");
2743 SMLoc
E = getTok().getEndLoc();
2746 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2748 Reg, RISCV::sub_gpr_even,
2749 &getRISCVMCRegisterClass(RISCV::GPRPairRegClassID));
2750 Operands.push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2754template <
bool IsRV64>
2756 return parseGPRPair(
Operands, IsRV64);
2766 if (!IsRV64Inst && isRV64())
2772 StringRef
Name = getLexer().getTok().getIdentifier();
2778 if (!getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg))
2781 if ((
Reg - RISCV::X0) & 1)
2782 return TokError(
"register must be even");
2785 SMLoc
E = getTok().getEndLoc();
2788 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2790 Reg, RISCV::sub_gpr_even,
2791 &getRISCVMCRegisterClass(RISCV::GPRPairRegClassID));
2792 Operands.push_back(RISCVOperand::createReg(Pair, S,
E));
2799 "operand must be a valid SpacemiT's Integer Matrix VType mnemonic");
2801 StringRef Str = getLexer().getTok().getIdentifier();
2804 if (!isValidSMTVTypeMode(VType))
2805 return TokError(
"SpacemiT's Integer Matrix only supports [i4|i8] mode");
2807 Operands.push_back(RISCVOperand::createSMTVType(VType, getLoc()));
2815 "operand must be a valid floating point rounding mode mnemonic");
2817 StringRef Str = getLexer().getTok().getIdentifier();
2822 "operand must be a valid floating point rounding mode mnemonic");
2824 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2829std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultSMTVType() {
2830 return RISCVOperand::createSMTVType(XSMTVTypeMode::SMTVTypeMode::SMT_I8,
2835 const AsmToken &Tok = getLexer().getTok();
2841 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2855 for (
char c : Str) {
2884 Operands.push_back(RISCVOperand::createFenceArg(
Imm, getLoc()));
2890 return TokError(
"operand must be formed of letters selected in-order from "
2897 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
2899 if (!parseRegister(
Operands).isSuccess())
2900 return Error(getLoc(),
"expected register");
2904 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2928 std::unique_ptr<RISCVOperand> OptionalImmOp;
2935 SMLoc ImmStart = getLoc();
2936 if (getParser().parseIntToken(ImmVal,
2937 "expected '(' or optional integer offset"))
2942 SMLoc ImmEnd = getLoc();
2945 ImmStart, ImmEnd, isRV64());
2949 OptionalImmOp ?
"expected '(' after optional integer offset"
2950 :
"expected '(' or optional integer offset"))
2953 if (!parseRegister(
Operands).isSuccess())
2954 return Error(getLoc(),
"expected register");
2960 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2962 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2963 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2974 StringRef OffsetRegName = getLexer().getTok().getIdentifier();
2977 !getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(OffsetReg))
2978 return Error(getLoc(),
"expected GPR register");
2985 return Error(getLoc(),
"expected GPR register");
2987 StringRef BaseRegName = getLexer().getTok().getIdentifier();
2990 !getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(BaseReg))
2991 return Error(getLoc(),
"expected GPR register");
2997 Operands.push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));
3010 bool MustIncludeS0) {
3022 return Error(getLoc(),
"invalid register");
3024 StringRef
RegName = getTok().getIdentifier();
3027 return Error(getLoc(),
"invalid register");
3030 UsesXRegs =
RegName[0] ==
'x';
3031 if (
Reg != RISCV::X1)
3032 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
3033 }
else if (RegEnd == RISCV::X1) {
3034 if (
Reg != RISCV::X8 || (UsesXRegs != (
RegName[0] ==
'x')))
3035 return Error(getLoc(), Twine(
"register must be '") +
3036 (UsesXRegs ?
"x8" :
"s0") +
"'");
3037 }
else if (RegEnd == RISCV::X9 && UsesXRegs) {
3038 if (
Reg != RISCV::X18 || (
RegName[0] !=
'x'))
3039 return Error(getLoc(),
"register must be 'x18'");
3041 return Error(getLoc(),
"too many register ranges");
3048 SMLoc MinusLoc = getLoc();
3050 if (RegEnd == RISCV::X1)
3051 return Error(MinusLoc, Twine(
"register '") + (UsesXRegs ?
"x1" :
"ra") +
3052 "' cannot start a multiple register range");
3055 return Error(getLoc(),
"invalid register");
3057 StringRef
RegName = getTok().getIdentifier();
3060 return Error(getLoc(),
"invalid register");
3062 if (RegEnd == RISCV::X8) {
3063 if ((
Reg != RISCV::X9 &&
3065 (UsesXRegs != (
RegName[0] ==
'x'))) {
3067 return Error(getLoc(),
"register must be 'x9'");
3068 return Error(getLoc(),
"register must be in the range 's1' to 's11'");
3070 }
else if (RegEnd == RISCV::X18) {
3072 return Error(getLoc(),
3073 "register must be in the range 'x19' to 'x27'");
3086 if (RegEnd == RISCV::X26)
3087 return Error(S,
"invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "
3088 "x18-x26}' is not supported");
3094 return Error(S,
"register list must include 's0' or 'x8'");
3096 Operands.push_back(RISCVOperand::createRegList(Encode, S));
3102 bool ExpectNegative) {
3111 auto *RegListOp =
static_cast<RISCVOperand *
>(
Operands.back().
get());
3112 if (!RegListOp->isRegList())
3115 unsigned RlistEncode = RegListOp->RegList.Encoding;
3119 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||
3120 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {
3121 int64_t
Lower = StackAdjBase;
3122 int64_t
Upper = StackAdjBase + 48;
3123 if (ExpectNegative) {
3128 return generateImmOutOfRangeError(S,
Lower,
Upper,
3129 "stack adjustment for register list must "
3130 "be a multiple of 16 bytes in the range");
3134 Operands.push_back(RISCVOperand::createStackAdj(StackAdj, S));
3146 MatchOperandParserImpl(
Operands, Mnemonic,
true);
3153 if (parseRegister(
Operands,
true).isSuccess())
3157 if (parseExpression(
Operands).isSuccess()) {
3160 return !parseMemOpBaseReg(
Operands).isSuccess();
3165 Error(getLoc(),
"unknown operand");
3169bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &Info,
3170 StringRef Name, SMLoc NameLoc,
3176 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
3180 Operands.push_back(RISCVOperand::createToken(Name, NameLoc));
3199 if (getParser().parseEOL(
"unexpected token")) {
3200 getParser().eatToEndOfStatement();
3206bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
3210 Kind = RE->getSpecifier();
3211 Expr = RE->getSubExpr();
3220bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
3229ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
3230 StringRef IDVal = DirectiveID.
getString();
3232 if (IDVal ==
".option")
3233 return parseDirectiveOption();
3234 if (IDVal ==
".attribute")
3235 return parseDirectiveAttribute();
3236 if (IDVal ==
".insn")
3237 return parseDirectiveInsn(DirectiveID.
getLoc());
3238 if (IDVal ==
".variant_cc")
3239 return parseDirectiveVariantCC();
3244bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
3245 bool FromOptionDirective) {
3246 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
3249 clearFeatureBits(Feature.Value, Feature.key());
3256 raw_string_ostream OutputErrMsg(Buffer);
3257 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3258 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
3259 << ErrMsg.getMessage();
3262 return Error(Loc, OutputErrMsg.str());
3264 auto &ISAInfo = *ParseResult;
3267 if (ISAInfo->hasExtension(Feature.key()))
3268 setFeatureBits(Feature.Value, Feature.key());
3270 if (FromOptionDirective) {
3271 if (ISAInfo->getXLen() == 32 && isRV64())
3272 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3273 else if (ISAInfo->getXLen() == 64 && !isRV64())
3274 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3277 if (ISAInfo->getXLen() == 32)
3278 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
3279 else if (ISAInfo->getXLen() == 64)
3280 setFeatureBits(RISCV::Feature64Bit,
"64bit");
3282 return Error(Loc,
"bad arch string " + Arch);
3284 Result = ISAInfo->toString();
3288bool RISCVAsmParser::parseDirectiveOption() {
3289 MCAsmParser &Parser = getParser();
3291 AsmToken Tok = Parser.
getTok();
3299 if (Option ==
"push") {
3303 getTargetStreamer().emitDirectiveOptionPush();
3308 if (Option ==
"pop") {
3313 getTargetStreamer().emitDirectiveOptionPop();
3314 if (popFeatureBits())
3315 return Error(StartLoc,
".option pop with no .option push");
3320 if (Option ==
"arch") {
3328 Type = RISCVOptionArchArgType::Plus;
3330 Type = RISCVOptionArchArgType::Minus;
3331 else if (!
Args.empty())
3333 "unexpected token, expected + or -");
3335 Type = RISCVOptionArchArgType::Full;
3339 "unexpected token, expected identifier");
3345 if (
Type == RISCVOptionArchArgType::Full) {
3347 if (resetToArch(Arch, Loc, Result,
true))
3356 Loc,
"extension version number parsing not currently implemented");
3359 if (!enableExperimentalExtension() &&
3361 return Error(Loc,
"unexpected experimental extensions");
3362 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
3364 if (Ext == std::end(
AllFeatures) || StringRef(Ext->key()) != Feature)
3365 return Error(Loc,
"unknown extension feature");
3369 if (
Type == RISCVOptionArchArgType::Plus) {
3372 setFeatureBits(Ext->Value, Ext->key());
3375 copySTI().setFeatureBits(OldFeatureBits);
3376 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3379 raw_string_ostream OutputErrMsg(Buffer);
3380 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3381 OutputErrMsg << ErrMsg.getMessage();
3384 return Error(Loc, OutputErrMsg.str());
3387 assert(
Type == RISCVOptionArchArgType::Minus);
3393 Feature.Implies.test(Ext->Value))
3394 return Error(Loc, Twine(
"can't disable ") + Ext->key() +
3395 " extension; " + Feature.key() +
3396 " extension requires " + Ext->key() +
3400 clearFeatureBits(Ext->Value, Ext->key());
3407 getTargetStreamer().emitDirectiveOptionArch(Args);
3410 getTargetStreamer().setArchString((*ParseResult)->toString());
3414 if (Option ==
"exact") {
3418 getTargetStreamer().emitDirectiveOptionExact();
3419 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3420 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3424 if (Option ==
"noexact") {
3428 getTargetStreamer().emitDirectiveOptionNoExact();
3429 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3430 setFeatureBits(RISCV::FeatureRelax,
"relax");
3434 if (Option ==
"rvc") {
3438 getTargetStreamer().emitDirectiveOptionRVC();
3439 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3441 getTargetStreamer().setArchString((*ParseResult)->toString());
3445 if (Option ==
"norvc") {
3449 getTargetStreamer().emitDirectiveOptionNoRVC();
3450 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3451 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3453 getTargetStreamer().setArchString((*ParseResult)->toString());
3457 if (Option ==
"pic") {
3461 getTargetStreamer().emitDirectiveOptionPIC();
3462 ParserOptions.IsPicEnabled =
true;
3466 if (Option ==
"nopic") {
3470 getTargetStreamer().emitDirectiveOptionNoPIC();
3471 ParserOptions.IsPicEnabled =
false;
3475 if (Option ==
"relax") {
3479 getTargetStreamer().emitDirectiveOptionRelax();
3480 setFeatureBits(RISCV::FeatureRelax,
"relax");
3484 if (Option ==
"norelax") {
3488 getTargetStreamer().emitDirectiveOptionNoRelax();
3489 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3495 "unknown option, expected 'push', 'pop', "
3496 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3497 "'exact', or 'noexact'");
3505bool RISCVAsmParser::parseDirectiveAttribute() {
3506 MCAsmParser &Parser = getParser();
3512 std::optional<unsigned> Ret =
3515 return Error(TagLoc,
"attribute name not recognised: " + Name);
3519 const MCExpr *AttrExpr;
3526 if (check(!CE, TagLoc,
"expected numeric constant"))
3529 Tag =
CE->getValue();
3535 StringRef StringValue;
3536 int64_t IntegerValue = 0;
3537 bool IsIntegerValue =
true;
3542 IsIntegerValue =
false;
3545 if (IsIntegerValue) {
3546 const MCExpr *ValueExpr;
3552 return Error(ValueExprLoc,
"expected numeric constant");
3553 IntegerValue =
CE->getValue();
3566 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3568 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3571 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3575 getTargetStreamer().emitTextAttribute(
Tag, Result);
3579 getTargetStreamer().setArchString(Result);
3587 .
Cases({
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s"},
true)
3588 .Cases({
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj"},
3590 .
Cases({
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es"},
3599bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3600 MCAsmParser &Parser = getParser();
3607 std::optional<int64_t>
Length;
3617 return Error(ErrorLoc,
3618 "instruction lengths must be a non-zero multiple of two");
3622 return Error(ErrorLoc,
3623 "instruction lengths over 64 bits are not supported");
3629 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3634 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3635 return Error(ErrorLoc,
3636 "instruction length does not match the encoding");
3639 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3642 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3645 if (!getSTI().
hasFeature(RISCV::FeatureStdExtZca) &&
3646 (EncodingDerivedLength == 2))
3647 return Error(ErrorLoc,
"compressed instructions are not allowed");
3649 if (getParser().parseEOL(
"invalid operand for instruction")) {
3650 getParser().eatToEndOfStatement();
3658 Opcode = RISCV::Insn16;
3661 Opcode = RISCV::Insn32;
3664 Opcode = RISCV::Insn48;
3667 Opcode = RISCV::Insn64;
3673 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3675 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3680 return Error(ErrorLoc,
"invalid instruction format");
3682 std::string FormatName = (
".insn_" +
Format).str();
3684 ParseInstructionInfo
Info;
3687 if (parseInstruction(Info, FormatName, L,
Operands))
3699bool RISCVAsmParser::parseDirectiveVariantCC() {
3701 if (getParser().parseIdentifier(Name))
3702 return TokError(
"expected symbol name");
3705 getTargetStreamer().emitDirectiveVariantCC(
3710void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3713 const MCSubtargetInfo &STI = getSTI();
3714 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3717 ++RISCVNumInstrsCompressed;
3721void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3726 for (MCInst &Inst : Seq) {
3727 emitToStreamer(Out, Inst);
3731void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3732 const MCExpr *Symbol,
3734 unsigned SecondOpcode, SMLoc IDLoc,
3742 Out.emitLabel(TmpLabel);
3746 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3751 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3754 .addExpr(RefToLinkTmpLabel));
3757void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3768 STI->
hasFeature(RISCV::FeatureVendorXqcili) &&
3769 !ParserOptions.IsPicEnabled)
3771 Out, MCInstBuilder(RISCV::QC_E_LI).addReg(DestReg).addExpr(Symbol));
3777void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3787 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3788 emitAuipcInstPair(DestReg, DestReg, Symbol,
RISCV::S_GOT_HI, SecondOpcode,
3792void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3801 if (ParserOptions.IsPicEnabled)
3802 emitLoadGlobalAddress(Inst, IDLoc, Out);
3804 emitLoadLocalAddress(Inst, IDLoc, Out);
3807void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3817 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3818 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3819 SecondOpcode, IDLoc, Out);
3822void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3832 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3833 RISCV::ADDI, IDLoc, Out);
3836void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3837 SMLoc IDLoc, MCStreamer &Out,
3846 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3848 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3852 if (getRISCVMCRegisterClass(RISCV::GPRPairRegClassID).
contains(TmpReg)) {
3853 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3854 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3862void RISCVAsmParser::emitQCELILoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3863 SMLoc IDLoc, MCStreamer &Out,
3873 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3877 MCInstBuilder(RISCV::QC_E_LI).addReg(AddrReg).addExpr(Symbol));
3880 const MCExpr *AccessExpr =
3886 struct CompressedForm {
3890 std::optional<CompressedForm> Compressed;
3894 case RISCV::PseudoQCAccessLBU:
3895 Compressed = {RISCV::PseudoQCAccessC_LBU, RISCV::FeatureStdExtZcb};
3897 case RISCV::PseudoQCAccessLH:
3898 Compressed = {RISCV::PseudoQCAccessC_LH, RISCV::FeatureStdExtZcb};
3900 case RISCV::PseudoQCAccessLHU:
3901 Compressed = {RISCV::PseudoQCAccessC_LHU, RISCV::FeatureStdExtZcb};
3903 case RISCV::PseudoQCAccessLW:
3904 Compressed = {RISCV::PseudoQCAccessC_LW, RISCV::FeatureStdExtZca};
3906 case RISCV::PseudoQCAccessSB:
3907 Compressed = {RISCV::PseudoQCAccessC_SB, RISCV::FeatureStdExtZcb};
3909 case RISCV::PseudoQCAccessSH:
3910 Compressed = {RISCV::PseudoQCAccessC_SH, RISCV::FeatureStdExtZcb};
3912 case RISCV::PseudoQCAccessSW:
3913 Compressed = {RISCV::PseudoQCAccessC_SW, RISCV::FeatureStdExtZca};
3920 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(AddrReg);
3921 if (HasTmpReg && CanUseGPRC) {
3924 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(DataReg);
3927 bool UseCompressed =
3928 Compressed && getSTI().hasFeature(Compressed->Feature) && CanUseGPRC;
3930 unsigned ActualOpcode = UseCompressed ? Compressed->Opcode : Opcode;
3933 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3937 .addExpr(AccessExpr));
3939 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3943 .addExpr(AccessExpr));
3947void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3948 int64_t Width, SMLoc IDLoc,
3957 const MCOperand &DestReg = Inst.
getOperand(0);
3958 const MCOperand &SourceReg = Inst.
getOperand(1);
3960 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3961 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3963 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3965 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3970 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3976void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
3983 emitToStreamer(Out, MCInstBuilder(Opcode)
3987 .addReg(MCRegister())
3989 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
4000 "The destination register should not be V0.");
4002 emitToStreamer(Out, MCInstBuilder(Opcode)
4008 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
4020 "The temporary vector register should not be V0.");
4021 emitToStreamer(Out, MCInstBuilder(Opcode)
4025 .addReg(MCRegister())
4027 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4039 "The temporary vector register should not be V0.");
4040 emitToStreamer(Out, MCInstBuilder(Opcode)
4044 .addReg(MCRegister())
4046 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4051 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4056 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
4064bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
4066 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
4069 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
4070 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
4071 "%tprel_add specifier");
4077bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
4079 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
4082 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
4083 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
4084 "%tlsdesc_call specifier");
4090std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
4091 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
4094std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
4095 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
4099std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
4100 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
4104std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultZeroOffset() {
4106 llvm::SMLoc(), llvm::SMLoc(), isRV64());
4113 case RISCV::VLOXSEG2EI8_V:
4114 case RISCV::VLOXSEG2EI16_V:
4115 case RISCV::VLOXSEG2EI32_V:
4116 case RISCV::VLOXSEG2EI64_V:
4117 case RISCV::VLUXSEG2EI8_V:
4118 case RISCV::VLUXSEG2EI16_V:
4119 case RISCV::VLUXSEG2EI32_V:
4120 case RISCV::VLUXSEG2EI64_V:
4122 case RISCV::VLOXSEG3EI8_V:
4123 case RISCV::VLOXSEG3EI16_V:
4124 case RISCV::VLOXSEG3EI32_V:
4125 case RISCV::VLOXSEG3EI64_V:
4126 case RISCV::VLUXSEG3EI8_V:
4127 case RISCV::VLUXSEG3EI16_V:
4128 case RISCV::VLUXSEG3EI32_V:
4129 case RISCV::VLUXSEG3EI64_V:
4131 case RISCV::VLOXSEG4EI8_V:
4132 case RISCV::VLOXSEG4EI16_V:
4133 case RISCV::VLOXSEG4EI32_V:
4134 case RISCV::VLOXSEG4EI64_V:
4135 case RISCV::VLUXSEG4EI8_V:
4136 case RISCV::VLUXSEG4EI16_V:
4137 case RISCV::VLUXSEG4EI32_V:
4138 case RISCV::VLUXSEG4EI64_V:
4140 case RISCV::VLOXSEG5EI8_V:
4141 case RISCV::VLOXSEG5EI16_V:
4142 case RISCV::VLOXSEG5EI32_V:
4143 case RISCV::VLOXSEG5EI64_V:
4144 case RISCV::VLUXSEG5EI8_V:
4145 case RISCV::VLUXSEG5EI16_V:
4146 case RISCV::VLUXSEG5EI32_V:
4147 case RISCV::VLUXSEG5EI64_V:
4149 case RISCV::VLOXSEG6EI8_V:
4150 case RISCV::VLOXSEG6EI16_V:
4151 case RISCV::VLOXSEG6EI32_V:
4152 case RISCV::VLOXSEG6EI64_V:
4153 case RISCV::VLUXSEG6EI8_V:
4154 case RISCV::VLUXSEG6EI16_V:
4155 case RISCV::VLUXSEG6EI32_V:
4156 case RISCV::VLUXSEG6EI64_V:
4158 case RISCV::VLOXSEG7EI8_V:
4159 case RISCV::VLOXSEG7EI16_V:
4160 case RISCV::VLOXSEG7EI32_V:
4161 case RISCV::VLOXSEG7EI64_V:
4162 case RISCV::VLUXSEG7EI8_V:
4163 case RISCV::VLUXSEG7EI16_V:
4164 case RISCV::VLUXSEG7EI32_V:
4165 case RISCV::VLUXSEG7EI64_V:
4167 case RISCV::VLOXSEG8EI8_V:
4168 case RISCV::VLOXSEG8EI16_V:
4169 case RISCV::VLOXSEG8EI32_V:
4170 case RISCV::VLOXSEG8EI64_V:
4171 case RISCV::VLUXSEG8EI8_V:
4172 case RISCV::VLUXSEG8EI16_V:
4173 case RISCV::VLUXSEG8EI32_V:
4174 case RISCV::VLUXSEG8EI64_V:
4180 if (getRISCVMCRegisterClass(RISCV::VRM2RegClassID).
contains(
Reg))
4182 if (getRISCVMCRegisterClass(RISCV::VRM4RegClassID).
contains(
Reg))
4184 if (getRISCVMCRegisterClass(RISCV::VRM8RegClassID).
contains(
Reg))
4191 case RISCV::VFWMMACC_VV_SCALE:
4192 case RISCV::VFQMMACC_VV_SCALE:
4193 case RISCV::VF8WMMACC_VV_SCALE:
4194 case RISCV::VFWIMMACC_VV:
4195 case RISCV::VFQIMMACC_VV:
4196 case RISCV::VF8WIMMACC_VV:
4203bool RISCVAsmParser::validateInstruction(MCInst &Inst,
4207 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
4208 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
4211 if (DestReg == TempReg) {
4212 SMLoc Loc =
Operands.back()->getStartLoc();
4213 return Error(Loc,
"the temporary vector register cannot be the same as "
4214 "the destination register");
4218 if (Opcode == RISCV::PseudoVMSGEU_VX_M || Opcode == RISCV::PseudoVMSGE_VX_M) {
4221 if (MaskReg == RISCV::V0 && DestReg == RISCV::V0) {
4222 SMLoc Loc =
Operands.back()->getStartLoc();
4223 return Error(Loc,
"the destination vector register cannot overlap the "
4224 "mask register unless a temporary register is "
4229 if (Opcode == RISCV::CV_INSERT &&
4232 "the sum of the immediate operands must be less than 32");
4237 case RISCV::TH_LBIA:
4238 case RISCV::TH_LBIB:
4239 case RISCV::TH_LBUIA:
4240 case RISCV::TH_LBUIB:
4241 case RISCV::TH_LHIA:
4242 case RISCV::TH_LHIB:
4243 case RISCV::TH_LHUIA:
4244 case RISCV::TH_LHUIB:
4245 case RISCV::TH_LWIA:
4246 case RISCV::TH_LWIB:
4247 case RISCV::TH_LWUIA:
4248 case RISCV::TH_LWUIB:
4249 case RISCV::TH_LDIA:
4250 case RISCV::TH_LDIB:
4252 return Error(
Operands[1]->getStartLoc(),
"rd and rs1 must be different");
4255 case RISCV::TH_LWUD:
4256 case RISCV::TH_LWD: {
4262 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
4263 SMLoc Loc =
Operands[1]->getStartLoc();
4264 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
4270 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
4274 SMLoc Loc =
Operands[1]->getStartLoc();
4275 return Error(Loc,
"rs1 and rs2 must be different");
4280 auto CheckOperandDoesNotOverlapV0 = [&](
int OperandIdx,
4281 unsigned ParsedIdx) {
4284 "vd, vs1, and vs2 cannot overlap v0.scale");
4289 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4291 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4293 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4294 assert(DestIdx >= 0 && VS1Idx >= 0 && VS2Idx >= 0 &&
4295 "Unexpected Zvvfmm scaled operand list");
4297 if (CheckOperandDoesNotOverlapV0(DestIdx, 1) ||
4298 CheckOperandDoesNotOverlapV0(VS1Idx, 2) ||
4299 CheckOperandDoesNotOverlapV0(VS2Idx, 3))
4303 const MCInstrDesc &MCID = MII.
get(Opcode);
4307 int DestIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4311 const MCParsedAsmOperand *ParsedOp =
Operands[1].get();
4312 if (!ParsedOp->
isReg()) {
4317 assert(ParsedOp->
getReg() == DestReg &&
"Can't find parsed dest operand");
4321 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4325 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4326 assert(VS2Idx >= 0 &&
"No vs2 operand?");
4327 unsigned CheckEncoding =
4330 for (
unsigned i = 0; i < std::max(NF, Lmul); i++) {
4331 if ((DestEncoding + i) == CheckEncoding)
4332 return Error(Loc,
"the destination vector register group cannot overlap"
4333 " the source vector register group");
4338 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4342 unsigned CheckEncoding =
4344 for (
unsigned i = 0; i < Lmul; i++) {
4345 if ((DestEncoding + i) == CheckEncoding)
4347 "the destination vector register group cannot overlap"
4348 " the source vector register group");
4354 int VMIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vm);
4355 assert(VMIdx >= 0 &&
"No vm operand?");
4357 if (DestReg == RISCV::V0) {
4360 return Error(Loc,
"the destination vector register group cannot be V0");
4368 "Unexpected mask operand register");
4370 return Error(Loc,
"the destination vector register group cannot overlap"
4371 " the mask register");
4379 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vmask);
4381 if (MaskReg != RISCV::V0 && MaskReg != RISCV::V1)
4383 "vmask operand only supports v0 or v1");
4386 RISCV::OpName RegOps[] = {RISCV::OpName::vd, RISCV::OpName::vs1,
4387 RISCV::OpName::vs2};
4388 for (RISCV::OpName OpN : RegOps) {
4389 int Idx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), OpN);
4395 for (
unsigned i = 0; i < RegLmul; i++) {
4396 if ((RegEnc + i) == MaskEnc) {
4398 return Error(Loc, Twine(
"register conflicts with vmask register ") +
4408bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
4416 case RISCV::MOP_RR_7: {
4428 case RISCV::MOP_R_28: {
4446 case RISCV::PseudoC_ADDI_NOP: {
4448 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
4458 if (getSTI().
hasFeature(RISCV::Feature64Bit))
4460 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV32)
4465 case RISCV::PACKW: {
4469 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV64)
4474 case RISCV::PseudoLLAImm:
4475 case RISCV::PseudoLAImm:
4476 case RISCV::PseudoLI: {
4482 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
4494 emitLoadImm(
Reg,
Imm, Out);
4497 case RISCV::PseudoLLA:
4498 emitLoadLocalAddress(Inst, IDLoc, Out);
4500 case RISCV::PseudoLGA:
4501 emitLoadGlobalAddress(Inst, IDLoc, Out);
4503 case RISCV::PseudoLA:
4504 emitLoadAddress(Inst, IDLoc, Out);
4506 case RISCV::PseudoLA_TLS_IE:
4507 emitLoadTLSIEAddress(Inst, IDLoc, Out);
4509 case RISCV::PseudoLA_TLS_GD:
4510 emitLoadTLSGDAddress(Inst, IDLoc, Out);
4512 case RISCV::PseudoLB:
4513 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
4515 case RISCV::PseudoLBU:
4516 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
4518 case RISCV::PseudoLH:
4519 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
4521 case RISCV::PseudoLHU:
4522 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
4524 case RISCV::PseudoLW:
4525 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
4527 case RISCV::PseudoLWU:
4528 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
4530 case RISCV::PseudoLD:
4531 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
4533 case RISCV::PseudoLD_RV32:
4534 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
4536 case RISCV::PseudoFLH:
4537 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
4539 case RISCV::PseudoFLW:
4540 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
4542 case RISCV::PseudoFLD:
4543 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
4545 case RISCV::PseudoFLQ:
4546 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
4548 case RISCV::PseudoSB:
4549 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
4551 case RISCV::PseudoSH:
4552 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
4554 case RISCV::PseudoSW:
4555 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
4557 case RISCV::PseudoSD:
4558 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
4560 case RISCV::PseudoSD_RV32:
4561 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
4563 case RISCV::PseudoQC_E_LB:
4564 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLB, IDLoc, Out,
4567 case RISCV::PseudoQC_E_LBU:
4568 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLBU, IDLoc, Out,
4571 case RISCV::PseudoQC_E_LH:
4572 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLH, IDLoc, Out,
4575 case RISCV::PseudoQC_E_LHU:
4576 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLHU, IDLoc, Out,
4579 case RISCV::PseudoQC_E_LW:
4580 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLW, IDLoc, Out,
4583 case RISCV::PseudoQC_E_SB:
4584 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSB, IDLoc, Out,
4587 case RISCV::PseudoQC_E_SH:
4588 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSH, IDLoc, Out,
4591 case RISCV::PseudoQC_E_SW:
4592 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSW, IDLoc, Out,
4595 case RISCV::PseudoFSH:
4596 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
4598 case RISCV::PseudoFSW:
4599 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
4601 case RISCV::PseudoFSD:
4602 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4604 case RISCV::PseudoFSQ:
4605 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4607 case RISCV::PseudoAddTPRel:
4608 if (checkPseudoAddTPRel(Inst,
Operands))
4611 case RISCV::PseudoTLSDESCCall:
4612 if (checkPseudoTLSDESCCall(Inst,
Operands))
4615 case RISCV::PseudoSEXT_B:
4616 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4618 case RISCV::PseudoSEXT_H:
4619 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4621 case RISCV::PseudoZEXT_H:
4622 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4624 case RISCV::PseudoZEXT_W:
4625 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4627 case RISCV::PseudoVMSGEU_VX_M:
4628 case RISCV::PseudoVMSGEU_VX_M_T:
4629 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4631 case RISCV::PseudoVMSGE_VX_M:
4632 case RISCV::PseudoVMSGE_VX_M_T:
4633 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4635 case RISCV::PseudoVMSGE_VI:
4636 case RISCV::PseudoVMSLT_VI: {
4640 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4642 emitToStreamer(Out, MCInstBuilder(
Opc)
4650 case RISCV::PseudoVMSGEU_VI:
4651 case RISCV::PseudoVMSLTU_VI: {
4658 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4661 emitToStreamer(Out, MCInstBuilder(
Opc)
4669 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4672 emitToStreamer(Out, MCInstBuilder(
Opc)
4682 case RISCV::PseudoCV_ELW:
4683 emitLoadStoreSymbol(Inst, RISCV::CV_ELW, IDLoc, Out,
false);
4687 emitToStreamer(Out, Inst);
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
static MCRegister MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, MCRegister &Reg, StringRef Name)
#define LLVM_EXTERNAL_VISIBILITY
const FeatureInfo AllFeatures[]
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static MCRegister convertGPRToYGPR(MCRegister Reg)
bool isValidInsnFormat(StringRef Format, const MCSubtargetInfo &STI)
static bool isZvvfmmScaleOpcode(unsigned Opcode)
static MCRegister convertFPR64ToFPR128(MCRegister Reg)
static MCRegister convertFPR64ToFPR32(MCRegister Reg)
static MCRegister convertFPR64ToFPR16(MCRegister Reg)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser()
static MCRegister convertFPR64ToFPR256(MCRegister Reg)
static MCRegister convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg, unsigned Kind)
static unsigned getNFforLXSEG(unsigned Opcode)
unsigned getLMULFromVectorRegister(MCRegister Reg)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
StringRef getStringContents() const
Get the contents of a string token (without quotes).
bool is(TokenKind K) const
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Encoding
Size and signedness of expression operations' operands.
Error takeError()
Take ownership of the stored error.
void printExpr(raw_ostream &, const MCExpr &) const
const AsmToken & getTok()
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
MCStreamer & getStreamer()
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
const MCObjectFileInfo * getObjectFileInfo() const
LLVM_ABI MCSymbol * createNamedTempSymbol()
Create a temporary symbol with a unique name whose name cannot be omitted in the symbol table.
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
ArrayRef< MCOperandInfo > operands() const
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
StringRef getName(unsigned Opcode) const
Returns the name for the instructions with the given opcode.
bool isPositionIndependent() const
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual MCRegister getReg() const =0
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const FeatureBitset & getFeatureBits() const
const FeatureBitset & ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
const MCSymbol * getAddSym() const
uint32_t getSpecifier() const
const MCSymbol * getSubSym() const
Ternary parse status returned by various parse* methods.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
static LLVM_ABI bool isSupportedExtensionFeature(StringRef Ext)
static LLVM_ABI std::string getTargetFeatureForExtension(StringRef Ext)
static LLVM_ABI llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseArchString(StringRef Arch, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck=true)
Parse RISC-V ISA info from arch string.
static const char * getRegisterName(MCRegister Reg)
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
reference emplace_back(ArgTypes &&... Args)
Represent a constant reference to a string, i.e.
std::string str() const
Get the contents as an std::string.
char back() const
Get the last character in the string.
A switch()-like statement whose cases are string literals.
StringSwitch & Cases(std::initializer_list< StringLiteral > CaseStrings, T Value)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
uint16_t StackAdjustment(const RuntimeFunction &RF)
StackAdjustment - calculated stack adjustment in words.
LLVM_ABI std::optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)
MCExpr const & getExpr(MCExpr const &Expr)
Expected< ABI > computeTargetABI(const MCSubtargetInfo &STI, StringRef ABIName)
LLVM_ABI const TagNameMap & getRISCVAttributeTags()
static RoundingMode stringToRoundingMode(StringRef Str)
llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseFeatureBits(const MCSubtargetInfo &STI)
int getLoadFPImm(APFloat FPImm)
getLoadFPImm - Return a 5-bit binary encoding of the floating-point immediate value.
void generateMCInstSeq(int64_t Val, const MCSubtargetInfo &STI, MCRegister DestReg, SmallVectorImpl< MCInst > &Insts)
bool compress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI)
static VLMUL encodeLMUL(unsigned LMUL, bool Fractional)
LLVM_ABI unsigned encodeXSfmmVType(unsigned SEW, unsigned Widen, bool AltFmt)
static bool isValidLMUL(unsigned LMUL, bool Fractional)
static bool isValidSEW(unsigned SEW)
LLVM_ABI void printVType(unsigned VType, raw_ostream &OS)
static bool isValidXSfmmVType(unsigned VTypeI)
LLVM_ABI unsigned encodeVTYPE(VLMUL VLMUL, unsigned SEW, bool TailAgnostic, bool MaskAgnostic, bool AltFmt=false)
unsigned encodeRegList(MCRegister EndReg, bool IsRVE=false)
static unsigned getStackAdjBase(unsigned RlistVal, bool IsRV64)
void printRegList(unsigned RlistEncode, raw_ostream &OS)
Specifier parseSpecifierName(StringRef name)
void updateCZceFeatureImplications(MCSubtargetInfo &STI)
bool isValidYBNDSWImm(int64_t Imm)
@ CE
Windows NT (Windows on ARM)
static SMTVTypeMode stringToSMTVTypeMode(StringRef Str)
static bool isValidSMTVTypeMode(unsigned Mode)
@ Valid
The data is already valid.
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,...