52#define DEBUG_TYPE "riscv-asm-parser"
55 "Number of RISC-V Compressed instructions emitted");
63struct ParserOptionsSet {
70 enum class VTypeState {
81 ParserOptionsSet ParserOptions;
83 SMLoc getLoc()
const {
return getParser().
getTok().
getLoc(); }
84 bool isRV64()
const {
return getSTI().hasFeature(RISCV::Feature64Bit); }
85 bool isRVE()
const {
return getSTI().hasFeature(RISCV::FeatureStdExtE); }
86 bool enableExperimentalExtension()
const {
87 return getSTI().hasFeature(RISCV::Experimental);
90 RISCVTargetStreamer &getTargetStreamer() {
91 assert(getParser().getStreamer().getTargetStreamer() &&
92 "do not have a target streamer");
93 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
94 return static_cast<RISCVTargetStreamer &
>(TS);
97 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
98 unsigned Kind)
override;
100 bool generateImmOutOfRangeError(SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
103 struct NearMissMessage {
108 std::string getCustomOperandDiag(
unsigned MatchError);
110 void FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
111 SmallVectorImpl<NearMissMessage> &NearMissesOut,
113 void ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses, SMLoc IDLoc,
116 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
119 bool MatchingInlineAsm)
override;
122 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
123 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
124 SMLoc &EndLoc)
override;
126 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
129 ParseStatus parseDirective(AsmToken DirectiveID)
override;
131 bool parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
unsigned &Sew,
132 unsigned &Lmul,
bool &Fractional,
bool &TailAgnostic,
133 bool &MaskAgnostic,
bool &AltFmt);
134 bool generateVTypeError(SMLoc ErrorLoc);
136 bool generateXSfmmVTypeError(SMLoc ErrorLoc);
139 void emitToStreamer(MCStreamer &S,
const MCInst &Inst);
143 void emitLoadImm(MCRegister DestReg, int64_t
Value, MCStreamer &Out);
147 void emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
149 unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out);
152 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
155 void emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
158 void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
162 void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
166 void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
169 void emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
170 MCStreamer &Out,
bool HasTmpReg);
175 void emitQCELILoadStoreSymbol(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
176 MCStreamer &Out,
bool HasTmpReg);
179 void emitPseudoExtend(MCInst &Inst,
bool SignExtend, int64_t Width,
180 SMLoc IDLoc, MCStreamer &Out);
183 void emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc, MCStreamer &Out);
208#define GET_ASSEMBLER_HEADER
209#include "RISCVGenAsmMatcher.inc"
239 return parseRegList(
Operands,
true);
245 bool ExpectNegative =
false);
247 return parseZcmpStackAdj(
Operands,
true);
251 bool parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
252 bool parseDataExpr(
const MCExpr *&Res)
override;
254 bool parseDirectiveOption();
255 bool parseDirectiveAttribute();
256 bool parseDirectiveInsn(SMLoc L);
257 bool parseDirectiveVariantCC();
262 bool resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
263 bool FromOptionDirective);
265 void setFeatureBits(
uint64_t Feature, StringRef FeatureString) {
267 MCSubtargetInfo &STI = copySTI();
273 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
277 void clearFeatureBits(
uint64_t Feature, StringRef FeatureString) {
279 MCSubtargetInfo &STI = copySTI();
280 setAvailableFeatures(
285 void pushFeatureBits() {
286 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
287 "These two stacks must be kept synchronized");
288 FeatureBitStack.push_back(getSTI().getFeatureBits());
289 ParserOptionsStack.push_back(ParserOptions);
292 bool popFeatureBits() {
293 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
294 "These two stacks must be kept synchronized");
295 if (FeatureBitStack.empty())
298 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
299 copySTI().setFeatureBits(FeatureBits);
300 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
302 ParserOptions = ParserOptionsStack.pop_back_val();
307 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
308 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
309 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
310 std::unique_ptr<RISCVOperand> defaultSMTVType();
311 std::unique_ptr<RISCVOperand> defaultZeroOffset();
314 enum RISCVMatchResultTy :
unsigned {
315 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
316#define GET_OPERAND_DIAGNOSTIC_TYPES
317#include "RISCVGenAsmMatcher.inc"
318#undef GET_OPERAND_DIAGNOSTIC_TYPES
322 static bool isSymbolDiff(
const MCExpr *Expr);
324 RISCVAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
325 const MCInstrInfo &MII)
326 : MCTargetAsmParser(STI, MII) {
333 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
339 getTargetStreamer().emitTargetAttributes(STI,
false);
345 void onBeginOfFile()
override {
348 if (getTargetStreamer().hasTargetABI())
351 Expected<RISCVABI::ABI> ABIOrErr =
355 getTargetStreamer().setTargetABI(
359 getTargetStreamer().setTargetABI(*ABIOrErr);
430 MCRegister OffsetReg;
433 SMLoc StartLoc, EndLoc;
449 RISCVOperand(KindTy K) : Kind(
K) {}
452 RISCVOperand(
const RISCVOperand &o) : MCParsedAsmOperand() {
454 StartLoc =
o.StartLoc;
457 case KindTy::Register:
460 case KindTy::Expression:
463 case KindTy::FPImmediate:
469 case KindTy::SystemRegister:
475 case KindTy::SMTVType:
476 SMTVType =
o.SMTVType;
484 case KindTy::RegList:
487 case KindTy::StackAdj:
488 StackAdj =
o.StackAdj;
496 bool isToken()
const override {
return Kind == KindTy::Token; }
497 bool isReg()
const override {
return Kind == KindTy::Register; }
498 bool isExpr()
const {
return Kind == KindTy::Expression; }
499 bool isV0Reg()
const {
500 return Kind == KindTy::Register &&
Reg.Reg == RISCV::V0;
502 bool isAnyReg()
const {
503 return Kind == KindTy::Register &&
504 (getRISCVMCRegisterClass(RISCV::GPRRegClassID).contains(
Reg.Reg) ||
505 getRISCVMCRegisterClass(RISCV::FPR64RegClassID).contains(
Reg.Reg) ||
506 getRISCVMCRegisterClass(RISCV::VRRegClassID).contains(
Reg.Reg));
508 bool isAnyRegC()
const {
509 return Kind == KindTy::Register &&
510 (getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(
Reg.Reg) ||
511 getRISCVMCRegisterClass(RISCV::FPR64CRegClassID).contains(
Reg.Reg));
513 bool isImm()
const override {
return isExpr(); }
514 bool isMem()
const override {
return false; }
515 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
516 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
517 bool isRegList()
const {
return Kind == KindTy::RegList; }
518 bool isRegListS0()
const {
519 return Kind == KindTy::RegList && RegList.Encoding !=
RISCVZC::RA;
521 bool isStackAdj()
const {
return Kind == KindTy::StackAdj; }
524 return Kind == KindTy::Register &&
525 getRISCVMCRegisterClass(RISCV::GPRRegClassID).contains(
Reg.Reg);
528 bool isYGPR()
const {
529 return Kind == KindTy::Register &&
530 getRISCVMCRegisterClass(RISCV::YGPRRegClassID).contains(
Reg.Reg);
533 bool isGPRPair()
const {
534 return Kind == KindTy::Register &&
535 getRISCVMCRegisterClass(RISCV::GPRPairRegClassID).contains(
Reg.Reg);
538 bool isGPRPairC()
const {
539 return Kind == KindTy::Register &&
540 getRISCVMCRegisterClass(RISCV::GPRPairCRegClassID).contains(
Reg.Reg);
543 bool isGPRPairNoX0()
const {
544 return Kind == KindTy::Register &&
545 getRISCVMCRegisterClass(RISCV::GPRPairNoX0RegClassID)
549 bool isGPRF16()
const {
550 return Kind == KindTy::Register &&
551 getRISCVMCRegisterClass(RISCV::GPRF16RegClassID).contains(
Reg.Reg);
554 bool isGPRF32()
const {
555 return Kind == KindTy::Register &&
556 getRISCVMCRegisterClass(RISCV::GPRF32RegClassID).contains(
Reg.Reg);
559 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
560 bool isGPRAsFPR16()
const {
return isGPRF16() &&
Reg.IsGPRAsFPR; }
561 bool isGPRAsFPR32()
const {
return isGPRF32() &&
Reg.IsGPRAsFPR; }
562 bool isGPRPairAsFPR64()
const {
return isGPRPair() &&
Reg.IsGPRAsFPR; }
564 static bool evaluateConstantExpr(
const MCExpr *Expr, int64_t &
Imm) {
566 Imm =
CE->getValue();
575 template <
int N>
bool isBareSimmNLsb0()
const {
584 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
590 template <
int N>
bool isBareSimmN()
const {
596 return isInt<N>(fixImmediateForRV32(
Imm, isRV64Expr()));
599 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
605 bool isBareSymbol()
const {
608 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
612 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
616 bool isCallSymbol()
const {
619 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
623 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
627 bool isTailCallSymbol()
const {
return isCallSymbol(); }
629 bool isPseudoJumpSymbol()
const {
632 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
636 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
640 bool isTPRelAddSymbol()
const {
643 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
647 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
648 VK == ELF::R_RISCV_TPREL_ADD;
651 bool isTLSDESCCallSymbol()
const {
654 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
658 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
659 VK == ELF::R_RISCV_TLSDESC_CALL;
662 bool isQCAccessSymbol()
const {
665 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
669 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
673 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
677 bool isVTypeI10()
const {
678 if (Kind == KindTy::VType)
682 bool isVTypeI11()
const {
683 if (Kind == KindTy::VType)
688 bool isXSfmmVType()
const {
692 bool isTileLambda()
const {
698 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
701 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
702 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
707 bool isSMTVType()
const {
708 return Kind == KindTy::SMTVType &&
712 bool isSMTI8()
const {
717 bool isLoadFPImm()
const {
720 if (Kind != KindTy::FPImmediate)
723 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
726 return Idx >= 0 && Idx != 1;
729 bool isImmXLenLI()
const {
738 return RISCVAsmParser::isSymbolDiff(
getExpr());
741 bool isImmXLenLI_Restricted()
const {
745 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
747 return IsConstantImm &&
751 template <
unsigned N>
bool isUImm()
const {
755 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
759 template <
unsigned N,
unsigned S>
bool isUImmShifted()
const {
763 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
767 template <
class Pred>
bool isUImmPred(Pred p)
const {
771 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
772 return IsConstantImm &&
p(
Imm);
775 bool isUImmLog2XLen()
const {
776 if (isExpr() && isRV64Expr())
781 bool isUImmLog2XLenNonZero()
const {
782 if (isExpr() && isRV64Expr())
787 bool isUImmLog2XLenHalf()
const {
788 if (isExpr() && isRV64Expr())
793 bool isUImm5NonZero()
const {
797 bool isUImm5GT3()
const {
801 bool isUImm4Plus1()
const {
806 bool isUImm5Plus1()
const {
811 bool isUImm6Plus1()
const {
816 bool isUImm5GE6Plus1()
const {
821 bool isUImm5Slist()
const {
822 return isUImmPred([](int64_t
Imm) {
823 return (
Imm == 0) || (
Imm == 1) || (
Imm == 2) || (
Imm == 4) ||
824 (
Imm == 8) || (
Imm == 16) || (
Imm == 15) || (
Imm == 31);
828 bool 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 {
1107 case KindTy::Expression:
1110 OS <<
' ' << (Expr.IsRV64 ?
"rv64" :
"rv32") <<
'>';
1112 case KindTy::FPImmediate:
1113 OS <<
"<fpimm: " << FPImm.Val <<
">";
1115 case KindTy::Register:
1117 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1122 case KindTy::SystemRegister:
1123 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1132 OS << roundingModeToString(getFRM());
1135 case KindTy::SMTVType:
1136 OS <<
"<smtvtype: ";
1137 OS << SMTVTypeModeToString(getSMTVType());
1145 case KindTy::RegList:
1150 case KindTy::StackAdj:
1151 OS <<
"<stackadj: ";
1155 case KindTy::RegReg:
1156 OS <<
"<RegReg: BaseReg " <<
RegName(
RegReg.BaseReg) <<
" OffsetReg "
1162 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1163 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1170 static std::unique_ptr<RISCVOperand>
1171 createReg(MCRegister
Reg, SMLoc S, SMLoc
E,
bool IsGPRAsFPR =
false) {
1172 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1174 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1180 static std::unique_ptr<RISCVOperand> createExpr(
const MCExpr *Val, SMLoc S,
1181 SMLoc
E,
bool IsRV64) {
1182 auto Op = std::make_unique<RISCVOperand>(KindTy::Expression);
1183 Op->Expr.Expr = Val;
1184 Op->Expr.IsRV64 = IsRV64;
1190 static std::unique_ptr<RISCVOperand> createFPImm(
uint64_t Val, SMLoc S) {
1191 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1192 Op->FPImm.Val = Val;
1198 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1199 unsigned Encoding) {
1200 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1201 Op->SysReg.Data = Str.data();
1202 Op->SysReg.Length = Str.size();
1209 static std::unique_ptr<RISCVOperand>
1211 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1218 static std::unique_ptr<RISCVOperand>
1220 auto Op = std::make_unique<RISCVOperand>(KindTy::SMTVType);
1221 Op->SMTVType.SMTVType = VType;
1227 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val, SMLoc S) {
1228 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1229 Op->Fence.Val = Val;
1235 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI, SMLoc S) {
1236 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1237 Op->VType.Val = VTypeI;
1243 static std::unique_ptr<RISCVOperand> createRegList(
unsigned RlistEncode,
1245 auto Op = std::make_unique<RISCVOperand>(KindTy::RegList);
1251 static std::unique_ptr<RISCVOperand>
1252 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {
1253 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1255 Op->RegReg.OffsetReg = OffsetReg;
1261 static std::unique_ptr<RISCVOperand> createStackAdj(
unsigned StackAdj, SMLoc S) {
1262 auto Op = std::make_unique<RISCVOperand>(KindTy::StackAdj);
1263 Op->StackAdj.Val = StackAdj;
1268 static void addExpr(MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1269 assert(Expr &&
"Expr shouldn't be null!");
1281 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1282 assert(
N == 1 &&
"Invalid number of operands!");
1286 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1287 assert(
N == 1 &&
"Invalid number of operands!");
1288 addExpr(Inst,
getExpr(), isRV64Expr());
1291 template <
unsigned Bits>
1292 void addSExtImmOperands(MCInst &Inst,
unsigned N)
const {
1293 assert(
N == 1 &&
"Invalid number of operands!");
1300 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
1301 assert(
N == 1 &&
"Invalid number of operands!");
1303 addExpr(Inst,
getExpr(), isRV64Expr());
1308 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1312 void addFenceArgOperands(MCInst &Inst,
unsigned N)
const {
1313 assert(
N == 1 &&
"Invalid number of operands!");
1317 void addCSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
1318 assert(
N == 1 &&
"Invalid number of operands!");
1325 void addVTypeIOperands(MCInst &Inst,
unsigned N)
const {
1326 assert(
N == 1 &&
"Invalid number of operands!");
1328 if (Kind == KindTy::Expression) {
1329 [[maybe_unused]]
bool IsConstantImm =
1331 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1338 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1339 assert(
N == 1 &&
"Invalid number of operands!");
1343 void addRegRegOperands(MCInst &Inst,
unsigned N)
const {
1344 assert(
N == 2 &&
"Invalid number of operands!");
1349 void addStackAdjOperands(MCInst &Inst,
unsigned N)
const {
1350 assert(
N == 1 &&
"Invalid number of operands!");
1354 void addFRMArgOperands(MCInst &Inst,
unsigned N)
const {
1355 assert(
N == 1 &&
"Invalid number of operands!");
1359 void addSMTVTypeOperand(MCInst &Inst,
unsigned N)
const {
1360 assert(
N == 1 &&
"Invalid number of operands!");
1366#define GET_REGISTER_MATCHER
1367#define GET_SUBTARGET_FEATURE_NAME
1368#define GET_MATCHER_IMPLEMENTATION
1369#define GET_MNEMONIC_SPELL_CHECKER
1370#include "RISCVGenAsmMatcher.inc"
1373 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1374 return Reg - RISCV::F0_D + RISCV::F0_H;
1378 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1379 return Reg - RISCV::F0_D + RISCV::F0_F;
1383 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1384 return Reg - RISCV::F0_D + RISCV::F0_Q;
1388 assert(
Reg >= RISCV::X0 &&
Reg <= RISCV::X31 &&
"Invalid register");
1389 return Reg - RISCV::X0 + RISCV::X0_Y;
1394 unsigned RegClassID;
1395 if (Kind == MCK_VRM2)
1396 RegClassID = RISCV::VRM2RegClassID;
1397 else if (Kind == MCK_VRM4)
1398 RegClassID = RISCV::VRM4RegClassID;
1399 else if (Kind == MCK_VRM8)
1400 RegClassID = RISCV::VRM8RegClassID;
1404 &getRISCVMCRegisterClass(RegClassID));
1408 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1409 return Reg - RISCV::F0_D + RISCV::F0_Q2;
1414 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1416 return Match_InvalidOperand;
1418 MCRegister
Reg =
Op.getReg();
1420 getRISCVMCRegisterClass(RISCV::FPR64RegClassID).contains(
Reg);
1422 getRISCVMCRegisterClass(RISCV::FPR64CRegClassID).contains(
Reg);
1423 bool IsRegVR = getRISCVMCRegisterClass(RISCV::VRRegClassID).contains(
Reg);
1425 if (
Op.isGPR() && Kind == MCK_YGPR) {
1428 return Match_Success;
1430 if (IsRegFPR64 && Kind == MCK_FPR256) {
1432 return Match_Success;
1434 if (IsRegFPR64 && Kind == MCK_FPR128) {
1436 return Match_Success;
1440 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1441 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1443 return Match_Success;
1447 if (IsRegFPR64 && Kind == MCK_FPR16) {
1449 return Match_Success;
1451 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1452 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_H;
1453 return Match_Success;
1455 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1456 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_W;
1457 return Match_Success;
1464 if (getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg) &&
1465 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1467 return Match_Success;
1471 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1474 return Match_InvalidOperand;
1475 return Match_Success;
1477 return Match_InvalidOperand;
1480bool RISCVAsmParser::generateImmOutOfRangeError(
1481 SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
1482 const Twine &
Msg =
"immediate must be an integer in the range") {
1489std::string RISCVAsmParser::getCustomOperandDiag(
unsigned MatchError) {
1491 StringRef
Msg =
"immediate must be an integer in the range") {
1492 return (
Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]").str();
1495 switch (MatchError) {
1499 if (
const char *Diag = getMatchKindDiag((RISCVMatchResultTy)MatchError))
1501 return std::string();
1502 case Match_InvalidImmXLenLI:
1504 return "operand must be a constant 64-bit integer";
1505 return Range(std::numeric_limits<int32_t>::min(),
1506 std::numeric_limits<uint32_t>::max());
1507 case Match_InvalidImmXLenLI_Restricted:
1509 return "operand either must be a constant 64-bit integer "
1510 "or a bare symbol name";
1511 return Range(std::numeric_limits<int32_t>::min(),
1512 std::numeric_limits<uint32_t>::max(),
1513 "operand either must be a bare symbol name or an immediate "
1514 "integer in the range");
1515 case Match_InvalidUImmLog2XLen:
1517 return Range(0, (1 << 6) - 1);
1518 return Range(0, (1 << 5) - 1);
1519 case Match_InvalidUImmLog2XLenNonZero:
1521 return Range(1, (1 << 6) - 1);
1522 return Range(1, (1 << 5) - 1);
1523 case Match_InvalidUImm1:
1524 return Range(0, (1 << 1) - 1);
1525 case Match_InvalidUImm2:
1526 return Range(0, (1 << 2) - 1);
1527 case Match_InvalidUImm2Lsb0:
1528 return Range(0, 2,
"immediate must be one of");
1529 case Match_InvalidUImm3:
1530 return Range(0, (1 << 3) - 1);
1531 case Match_InvalidUImm4:
1532 return Range(0, (1 << 4) - 1);
1533 case Match_InvalidUImm4Plus1:
1534 return Range(1, (1 << 4));
1535 case Match_InvalidUImm5:
1536 return Range(0, (1 << 5) - 1);
1537 case Match_InvalidUImm5NonZero:
1538 return Range(1, (1 << 5) - 1);
1539 case Match_InvalidUImm5GT3:
1540 return Range(4, (1 << 5) - 1);
1541 case Match_InvalidUImm5Plus1:
1542 return Range(1, (1 << 5));
1543 case Match_InvalidUImm5GE6Plus1:
1544 return Range(6, (1 << 5));
1545 case Match_InvalidUImm5Slist:
1546 return "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31";
1547 case Match_InvalidUImm6:
1548 return Range(0, (1 << 6) - 1);
1549 case Match_InvalidUImm6Plus1:
1550 return Range(1, (1 << 6));
1551 case Match_InvalidUImm7:
1552 return Range(0, (1 << 7) - 1);
1553 case Match_InvalidUImm8:
1554 return Range(0, (1 << 8) - 1);
1555 case Match_InvalidUImm8GE32:
1556 return Range(32, (1 << 8) - 1);
1557 case Match_InvalidSImm5:
1558 return Range(-(1 << 4), (1 << 4) - 1);
1559 case Match_InvalidSImm5NonZero:
1560 return Range(-(1 << 4), (1 << 4) - 1,
1561 "immediate must be non-zero in the range");
1562 case Match_InvalidSImm6:
1563 return Range(-(1 << 5), (1 << 5) - 1);
1564 case Match_InvalidSImm6NonZero:
1565 return Range(-(1 << 5), (1 << 5) - 1,
1566 "immediate must be non-zero in the range");
1567 case Match_InvalidCLUIImm:
1568 return Range(1, (1 << 5) - 1,
"immediate must be in [0xfffe0, 0xfffff] or");
1569 case Match_InvalidUImm5Lsb0:
1570 return Range(0, (1 << 5) - 2,
1571 "immediate must be a multiple of 2 bytes in the range");
1572 case Match_InvalidUImm6Lsb0:
1573 return Range(0, (1 << 6) - 2,
1574 "immediate must be a multiple of 2 bytes in the range");
1575 case Match_InvalidUImm6Lsb000:
1576 return Range(0, (1 << 6) - 8,
1577 "immediate must be a multiple of 8 in the range");
1578 case Match_InvalidUImm7Lsb00:
1579 return Range(0, (1 << 7) - 4,
1580 "immediate must be a multiple of 4 bytes in the range");
1581 case Match_InvalidUImm8Lsb00:
1582 return Range(0, (1 << 8) - 4,
1583 "immediate must be a multiple of 4 bytes in the range");
1584 case Match_InvalidUImm8Lsb000:
1585 return Range(0, (1 << 8) - 8,
1586 "immediate must be a multiple of 8 bytes in the range");
1587 case Match_InvalidUImm9:
1588 return Range(0, (1 << 9) - 1,
"immediate offset must be in the range");
1589 case Match_InvalidBareSImm9Lsb0:
1590 return Range(-(1 << 8), (1 << 8) - 2,
1591 "immediate must be a multiple of 2 bytes in the range");
1592 case Match_InvalidUImm9Lsb000:
1593 return Range(0, (1 << 9) - 8,
1594 "immediate must be a multiple of 8 bytes in the range");
1595 case Match_InvalidSImm8PLI_B:
1596 return Range(-(1 << 7), (1 << 8) - 1);
1597 case Match_InvalidSImm10:
1598 case Match_InvalidSImm10PLI_H:
1599 case Match_InvalidSImm10PLI_W:
1600 return Range(-(1 << 9), (1 << 9) - 1);
1601 case Match_InvalidSImm10PLUI:
1602 return Range(-(1 << 9), (1 << 10) - 1);
1603 case Match_InvalidUImm10Lsb00NonZero:
1604 return Range(4, (1 << 10) - 4,
1605 "immediate must be a multiple of 4 bytes in the range");
1606 case Match_InvalidSImm10Lsb0000NonZero:
1608 -(1 << 9), (1 << 9) - 16,
1609 "immediate must be a multiple of 16 bytes and non-zero in the range");
1610 case Match_InvalidSImm11:
1611 return Range(-(1 << 10), (1 << 10) - 1);
1612 case Match_InvalidBareSImm11Lsb0:
1613 return Range(-(1 << 10), (1 << 10) - 2,
1614 "immediate must be a multiple of 2 bytes in the range");
1615 case Match_InvalidUImm10:
1616 return Range(0, (1 << 10) - 1);
1617 case Match_InvalidUImm11:
1618 return Range(0, (1 << 11) - 1);
1619 case Match_InvalidUImm14Lsb00:
1620 return Range(0, (1 << 14) - 4,
1621 "immediate must be a multiple of 4 bytes in the range");
1622 case Match_InvalidUImm16NonZero:
1623 return Range(1, (1 << 16) - 1);
1624 case Match_InvalidSImm12:
1625 return Range(-(1 << 11), (1 << 11) - 1);
1626 case Match_InvalidSImm12LO:
1627 return Range(-(1 << 11), (1 << 11) - 1,
1628 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo "
1629 "specifier or an integer in the range");
1630 case Match_InvalidBareSImm12Lsb0:
1631 return Range(-(1 << 11), (1 << 11) - 2,
1632 "immediate must be a multiple of 2 bytes in the range");
1633 case Match_InvalidSImm12Lsb00000:
1634 return Range(-(1 << 11), (1 << 11) - 32,
1635 "immediate must be a multiple of 32 bytes in the range");
1636 case Match_InvalidBareSImm13Lsb0:
1637 return Range(-(1 << 12), (1 << 12) - 2,
1638 "immediate must be a multiple of 2 bytes in the range");
1639 case Match_InvalidSImm16:
1640 return Range(-(1 << 15), (1 << 15) - 1);
1641 case Match_InvalidSImm16NonZero:
1642 return Range(-(1 << 15), (1 << 15) - 1,
1643 "immediate must be non-zero in the range");
1644 case Match_InvalidSImm20LI:
1645 return Range(-(1 << 19), (1 << 19) - 1,
1646 "operand must be a symbol with a %qc.abs20 specifier or an "
1647 "integer in the range");
1648 case Match_InvalidUImm20LUI:
1649 return Range(0, (1 << 20) - 1,
1650 "operand must be a symbol with %hi/%tprel_hi specifier or an "
1651 "integer in the range");
1652 case Match_InvalidUImm20:
1653 return Range(0, (1 << 20) - 1);
1654 case Match_InvalidUImm20AUIPC:
1657 "operand must be a symbol with a "
1658 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
1659 "or an integer in the range");
1660 case Match_InvalidBareSImm21Lsb0:
1661 return Range(-(1 << 20), (1 << 20) - 2,
1662 "immediate must be a multiple of 2 bytes in the range");
1663 case Match_InvalidCSRSystemRegister:
1664 return Range(0, (1 << 12) - 1,
1665 "operand must be a valid system register name or an integer "
1667 case Match_InvalidImm5Zibi:
1668 return Range(-1, (1 << 5) - 1,
"immediate must be non-zero in the range");
1669 case Match_InvalidVTypeI:
1670 return "operand must be "
1671 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]";
1672 case Match_InvalidSImm5Plus1:
1673 return Range(-(1 << 4) + 1, (1 << 4),
"immediate must be in the range");
1674 case Match_InvalidSImm18:
1675 return Range(-(1 << 17), (1 << 17) - 1);
1676 case Match_InvalidSImm18Lsb0:
1677 return Range(-(1 << 17), (1 << 17) - 2,
1678 "immediate must be a multiple of 2 bytes in the range");
1679 case Match_InvalidSImm19Lsb00:
1680 return Range(-(1 << 18), (1 << 18) - 4,
1681 "immediate must be a multiple of 4 bytes in the range");
1682 case Match_InvalidSImm20Lsb000:
1683 return Range(-(1 << 19), (1 << 19) - 8,
1684 "immediate must be a multiple of 8 bytes in the range");
1685 case Match_InvalidSImm26:
1686 return Range(-(1 << 25), (1 << 25) - 1);
1688 case Match_InvalidBareSymbolQC_E_LI:
1691 case Match_InvalidBareSImm32:
1692 return Range(std::numeric_limits<int32_t>::min(),
1693 std::numeric_limits<uint32_t>::max());
1694 case Match_InvalidBareSImm32Lsb0:
1695 return Range(std::numeric_limits<int32_t>::min(),
1696 std::numeric_limits<int32_t>::max() - 1,
1697 "operand must be a multiple of 2 bytes in the range");
1698 case Match_InvalidRnumArg:
1699 return Range(0, 10);
1700 case Match_InvalidStackAdj:
1701 return "stack adjustment is invalid for this instruction and register "
1703 case Match_InvalidYBNDSWImm:
1704 return "immediate must be an integer in the range "
1705 "[1, 255], a multiple of 8 in the range [256, 504], "
1706 "or a multiple of 16 in the range [512, 4096]";
1713void RISCVAsmParser::FilterNearMisses(
1714 SmallVectorImpl<NearMissInfo> &NearMissesIn,
1715 SmallVectorImpl<NearMissMessage> &NearMissesOut, SMLoc IDLoc,
1719 std::multimap<unsigned, unsigned> OperandMissesSeen;
1720 SmallSet<FeatureBitset, 4> FeatureMissesSeen;
1721 bool ReportedTooFewOperands =
false;
1722 bool ReportedTooManyOperands =
false;
1724 for (NearMissInfo &
I : NearMissesIn) {
1725 switch (
I.getKind()) {
1728 ((RISCVOperand &)*
Operands[
I.getOperandIndex()]).getStartLoc();
1733 if (
I.getOperandClass() == InvalidMatchClass) {
1734 if (!ReportedTooManyOperands) {
1736 OperandLoc,
"unexpected extra operand for instruction"});
1737 ReportedTooManyOperands =
true;
1742 std::string OperandDiag = getCustomOperandDiag(
I.getOperandError());
1746 unsigned DupCheckMatchClass =
1747 OperandDiag.empty() ? ~0
U :
I.getOperandClass();
1748 auto PrevReports = OperandMissesSeen.equal_range(
I.getOperandIndex());
1750 PrevReports.first, PrevReports.second,
1751 [DupCheckMatchClass](
const std::pair<unsigned, unsigned> Pair) {
1752 if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
1753 return Pair.second == DupCheckMatchClass;
1754 return isSubclass((MatchClassKind)DupCheckMatchClass,
1755 (MatchClassKind)Pair.second);
1758 OperandMissesSeen.insert(
1759 std::make_pair(
I.getOperandIndex(), DupCheckMatchClass));
1761 NearMissMessage Message;
1762 Message.Loc = OperandLoc;
1763 if (!OperandDiag.empty()) {
1764 Message.Message = OperandDiag;
1766 Message.Message =
"invalid operand for instruction";
1768 dbgs() <<
"Missing diagnostic string for operand class "
1769 << getMatchClassName((MatchClassKind)
I.getOperandClass())
1770 <<
I.getOperandClass() <<
", error " <<
I.getOperandError()
1771 <<
", opcode " << MII.
getName(
I.getOpcode()) <<
"\n");
1777 const FeatureBitset &MissingFeatures =
I.getFeatures();
1779 if (!FeatureMissesSeen.
insert(MissingFeatures).second)
1782 NearMissMessage Message;
1783 Message.Loc = IDLoc;
1784 bool FirstFeature =
true;
1785 Message.Message =
"instruction requires the following:";
1786 for (
unsigned Feature : MissingFeatures) {
1787 Message.Message += FirstFeature ?
" " :
", ";
1789 FirstFeature =
false;
1799 if (!ReportedTooFewOperands) {
1800 SMLoc EndLoc = ((RISCVOperand &)*
Operands.back()).getEndLoc();
1802 NearMissMessage{EndLoc,
"too few operands for instruction"});
1803 ReportedTooFewOperands =
true;
1815void RISCVAsmParser::ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses,
1818 FilterNearMisses(NearMisses, Messages, IDLoc,
Operands);
1823 Error(IDLoc,
"invalid instruction");
1826 Error(Messages[0].Loc, Messages[0].Message);
1831 "invalid instruction, any one of the following would fix this:");
1832 for (
auto &M : Messages)
1837bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1841 bool MatchingInlineAsm) {
1846 MatchInstructionImpl(
Operands, Inst, &NearMisses, MatchingInlineAsm);
1851 if (validateInstruction(Inst,
Operands))
1853 return processInstruction(Inst, IDLoc,
Operands, Out);
1854 case Match_MnemonicFail: {
1855 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1856 std::string Suggestion = RISCVMnemonicSpellCheck(
1858 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1860 case Match_NearMisses:
1861 ReportNearMisses(NearMisses, IDLoc,
Operands);
1872MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name)
const {
1881 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1882 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1883 static_assert(RISCV::F0_D < RISCV::F0_Q,
"FPR matching must be updated");
1886 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1891bool RISCVAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1893 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1894 return Error(StartLoc,
"invalid register name");
1898ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1900 const AsmToken &Tok = getParser().getTok();
1903 StringRef
Name = getLexer().getTok().getIdentifier();
1915 SMLoc FirstS = getLoc();
1916 bool HadParens =
false;
1923 size_t ReadCount = getLexer().peekTokens(Buf);
1926 LParen = getParser().getTok();
1931 switch (getLexer().getKind()) {
1934 getLexer().UnLex(LParen);
1937 StringRef
Name = getLexer().getTok().getIdentifier();
1942 getLexer().UnLex(LParen);
1946 Operands.push_back(RISCVOperand::createToken(
"(", FirstS));
1948 SMLoc
E = getTok().getEndLoc();
1950 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
1955 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
1966 switch (getLexer().getKind()) {
1976 if (getParser().parseExpression(Res,
E))
1981 int64_t
Imm =
CE->getValue();
1983 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1992 if (getParser().parseIdentifier(Identifier))
1995 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1998 "Unexpected opcode");
2001 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2011 return generateImmOutOfRangeError(
2013 "opcode must be a valid opcode name or an immediate in the range");
2021 switch (getLexer().getKind()) {
2031 if (getParser().parseExpression(Res,
E))
2036 int64_t
Imm =
CE->getValue();
2037 if (
Imm >= 0 &&
Imm <= 2) {
2038 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2047 if (getParser().parseIdentifier(Identifier))
2051 if (Identifier ==
"C0")
2053 else if (Identifier ==
"C1")
2055 else if (Identifier ==
"C2")
2062 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2071 return generateImmOutOfRangeError(
2073 "opcode must be a valid opcode name or an immediate in the range");
2080 auto SysRegFromConstantInt = [
this](
const MCExpr *
E, SMLoc S) {
2082 int64_t
Imm =
CE->getValue();
2084 auto Range = RISCVSysReg::lookupSysRegByEncoding(
Imm);
2088 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2091 return RISCVOperand::createSysReg(
2092 RISCVSysReg::getSysRegStr(
Reg.Name), S,
Imm);
2096 return RISCVOperand::createSysReg(
"", S,
Imm);
2099 return std::unique_ptr<RISCVOperand>();
2102 switch (getLexer().getKind()) {
2112 if (getParser().parseExpression(Res))
2115 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
2116 Operands.push_back(std::move(SysOpnd));
2120 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2124 if (getParser().parseIdentifier(Identifier))
2127 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
2130 if (SysReg->IsDeprecatedName) {
2132 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
2134 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2136 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
2137 RISCVSysReg::getSysRegStr(
Reg.Name) +
"'");
2142 const auto &FeatureBits = getSTI().getFeatureBits();
2143 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
2144 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
2145 const auto *Feature =
2147 return SysReg->FeaturesRequired[Feature.Value];
2149 std::string ErrorMsg =
2150 std::string(
"system register '") +
2151 std::string(RISCVSysReg::getSysRegStr(SysReg->Name)) +
"' ";
2152 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
2153 ErrorMsg +=
"is RV32 only";
2155 ErrorMsg +=
" and ";
2159 "requires '" + std::string(Feature->key()) +
"' to be enabled";
2162 return Error(S, ErrorMsg);
2165 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
2175 Operands.push_back(std::move(SysOpnd));
2180 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2181 "operand must be a valid system register "
2182 "name or an integer in the range");
2186 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2198 StringRef
Identifier = getTok().getIdentifier();
2199 if (
Identifier.compare_insensitive(
"inf") == 0) {
2202 getTok().getEndLoc(), isRV64()));
2203 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2206 getTok().getEndLoc(), isRV64()));
2207 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2210 getTok().getEndLoc(), isRV64()));
2212 return TokError(
"invalid floating point literal");
2223 const AsmToken &Tok = getTok();
2225 return TokError(
"invalid floating point immediate");
2228 APFloat RealVal(APFloat::IEEEdouble());
2230 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2232 return TokError(
"invalid floating point representation");
2235 RealVal.changeSign();
2237 Operands.push_back(RISCVOperand::createFPImm(
2238 RealVal.bitcastToAPInt().getZExtValue(), S));
2250 switch (getLexer().getKind()) {
2262 if (getParser().parseExpression(Res,
E))
2266 return parseOperandWithSpecifier(
Operands);
2269 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2279 const MCExpr *Expr =
nullptr;
2280 bool Failed = parseExprWithSpecifier(Expr,
E);
2282 Operands.push_back(RISCVOperand::createExpr(Expr, S,
E, isRV64()));
2286bool RISCVAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
2287 SMLoc Loc = getLoc();
2289 return TokError(
"expected '%' relocation specifier");
2290 StringRef
Identifier = getParser().getTok().getIdentifier();
2293 return TokError(
"invalid relocation specifier");
2299 const MCExpr *SubExpr;
2300 if (getParser().parseParenExpression(SubExpr,
E))
2307bool RISCVAsmParser::parseDataExpr(
const MCExpr *&Res) {
2310 return parseExprWithSpecifier(Res,
E);
2311 return getParser().parseExpression(Res);
2321 StringRef
Identifier = getTok().getIdentifier();
2331 if (getParser().parseExpression(Res,
E))
2334 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2344 std::string
Identifier(getTok().getIdentifier());
2350 SMLoc Loc = getLoc();
2351 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2352 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2366 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2378 std::string
Identifier(getTok().getIdentifier());
2384 SMLoc Loc = getLoc();
2385 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2386 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2400 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2409 if (getParser().parseExpression(Res,
E))
2412 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef)
2413 return Error(S,
"operand must be a valid jump target");
2416 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2437bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2438 unsigned &Sew,
unsigned &Lmul,
2439 bool &Fractional,
bool &TailAgnostic,
2440 bool &MaskAgnostic,
bool &AltFmt) {
2445 if (State < VTypeState::SeenSew &&
Identifier.consume_front(
"e")) {
2447 if (Identifier ==
"16alt") {
2450 }
else if (Identifier ==
"8alt") {
2460 State = VTypeState::SeenSew;
2464 if (State < VTypeState::SeenLmul &&
Identifier.consume_front(
"m")) {
2467 if (Identifier ==
"a" || Identifier ==
"u") {
2469 State = VTypeState::SeenMaskPolicy;
2480 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2481 unsigned MinLMUL = ELEN / 8;
2484 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2485 Twine(MinLMUL) +
" is reserved");
2488 State = VTypeState::SeenLmul;
2492 if (State < VTypeState::SeenTailPolicy &&
Identifier.starts_with(
"t")) {
2493 if (Identifier ==
"ta")
2494 TailAgnostic =
true;
2495 else if (Identifier ==
"tu")
2496 TailAgnostic =
false;
2500 State = VTypeState::SeenTailPolicy;
2504 if (State < VTypeState::SeenMaskPolicy &&
Identifier.starts_with(
"m")) {
2505 if (Identifier ==
"ma")
2506 MaskAgnostic =
true;
2507 else if (Identifier ==
"mu")
2508 MaskAgnostic =
false;
2512 State = VTypeState::SeenMaskPolicy;
2525 bool Fractional =
false;
2526 bool TailAgnostic =
false;
2527 bool MaskAgnostic =
false;
2530 VTypeState State = VTypeState::SeenNothingYet;
2532 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2533 MaskAgnostic, AltFmt)) {
2535 if (State == VTypeState::SeenNothingYet)
2544 State == VTypeState::SeenNothingYet)
2545 return generateVTypeError(S);
2549 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2550 unsigned MaxSEW = ELEN / Lmul;
2552 if (MaxSEW >= 8 && Sew > MaxSEW)
2553 Warning(S,
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2554 " and LMUL == mf" + Twine(Lmul) +
2555 " may not be compatible with all RVV implementations");
2560 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2564bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2565 return Error(ErrorLoc,
2567 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2587 if (Identifier !=
"16alt")
2616 Operands.push_back(RISCVOperand::createVType(
2622 return generateXSfmmVTypeError(S);
2625bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
2626 return Error(ErrorLoc,
"operand must be e[8|16|16alt|32|64],w[1|2|4]");
2633 StringRef
Name = getLexer().getTok().getIdentifier();
2634 if (!
Name.consume_back(
".t")) {
2638 return Error(getLoc(),
"expected '.t' suffix");
2645 if (
Reg != RISCV::V0)
2648 SMLoc
E = getTok().getEndLoc();
2650 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2658 StringRef
Name = getLexer().getTok().getIdentifier();
2659 if (!
Name.consume_back(
".scale"))
2660 return Error(getLoc(),
"expected '.scale' suffix");
2665 if (
Reg != RISCV::V0)
2668 SMLoc
E = getTok().getEndLoc();
2670 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2679 StringRef
Name = getLexer().getTok().getIdentifier();
2680 if (!
Name.consume_front(
"L") && !
Name.consume_front(
"l"))
2685 return Error(S,
"operand must be L1, L2, L4, L8, L16, L32, or L64");
2687 unsigned EncodedLambda =
Log2_32(Lambda) + 1;
2689 SMLoc
E = getTok().getEndLoc();
2691 Operands.push_back(RISCVOperand::createExpr(
2697 if (!isRV64() || getSTI().
hasFeature(RISCV::FeatureStdExtF))
2707 StringRef
Name = getLexer().getTok().getIdentifier();
2713 SMLoc
E = getTok().getEndLoc();
2715 Operands.push_back(RISCVOperand::createReg(
2721 if (isRV64() || getSTI().
hasFeature(RISCV::FeatureStdExtF))
2727 StringRef
Name = getLexer().getTok().getIdentifier();
2733 if (!getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg))
2736 if ((
Reg - RISCV::X0) & 1) {
2739 if (getSTI().
hasFeature(RISCV::FeatureStdExtZfinx))
2740 return TokError(
"double precision floating point operands must use even "
2741 "numbered X register");
2746 SMLoc
E = getTok().getEndLoc();
2749 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2751 Reg, RISCV::sub_gpr_even,
2752 &getRISCVMCRegisterClass(RISCV::GPRPairRegClassID));
2753 Operands.push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2757template <
bool IsRV64>
2759 return parseGPRPair(
Operands, IsRV64);
2769 if (!IsRV64Inst && isRV64())
2775 StringRef
Name = getLexer().getTok().getIdentifier();
2781 if (!getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg))
2784 if ((
Reg - RISCV::X0) & 1)
2785 return TokError(
"register must be even");
2788 SMLoc
E = getTok().getEndLoc();
2791 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2793 Reg, RISCV::sub_gpr_even,
2794 &getRISCVMCRegisterClass(RISCV::GPRPairRegClassID));
2795 Operands.push_back(RISCVOperand::createReg(Pair, S,
E));
2802 "operand must be a valid SpacemiT's Integer Matrix VType mnemonic");
2804 StringRef Str = getLexer().getTok().getIdentifier();
2807 if (!isValidSMTVTypeMode(VType))
2808 return TokError(
"SpacemiT's Integer Matrix only supports [i4|i8] mode");
2810 Operands.push_back(RISCVOperand::createSMTVType(VType, getLoc()));
2818 "operand must be a valid floating point rounding mode mnemonic");
2820 StringRef Str = getLexer().getTok().getIdentifier();
2825 "operand must be a valid floating point rounding mode mnemonic");
2827 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2832std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultSMTVType() {
2833 return RISCVOperand::createSMTVType(XSMTVTypeMode::SMTVTypeMode::SMT_I8,
2838 const AsmToken &Tok = getLexer().getTok();
2844 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2858 for (
char c : Str) {
2887 Operands.push_back(RISCVOperand::createFenceArg(
Imm, getLoc()));
2893 return TokError(
"operand must be formed of letters selected in-order from "
2900 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
2902 if (!parseRegister(
Operands).isSuccess())
2903 return Error(getLoc(),
"expected register");
2907 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2931 std::unique_ptr<RISCVOperand> OptionalImmOp;
2938 SMLoc ImmStart = getLoc();
2939 if (getParser().parseIntToken(ImmVal,
2940 "expected '(' or optional integer offset"))
2945 SMLoc ImmEnd = getLoc();
2948 ImmStart, ImmEnd, isRV64());
2952 OptionalImmOp ?
"expected '(' after optional integer offset"
2953 :
"expected '(' or optional integer offset"))
2956 if (!parseRegister(
Operands).isSuccess())
2957 return Error(getLoc(),
"expected register");
2963 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2965 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2966 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2977 StringRef OffsetRegName = getLexer().getTok().getIdentifier();
2980 !getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(OffsetReg))
2981 return Error(getLoc(),
"expected GPR register");
2988 return Error(getLoc(),
"expected GPR register");
2990 StringRef BaseRegName = getLexer().getTok().getIdentifier();
2993 !getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(BaseReg))
2994 return Error(getLoc(),
"expected GPR register");
3000 Operands.push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));
3013 bool MustIncludeS0) {
3025 return Error(getLoc(),
"invalid register");
3027 StringRef
RegName = getTok().getIdentifier();
3030 return Error(getLoc(),
"invalid register");
3033 UsesXRegs =
RegName[0] ==
'x';
3034 if (
Reg != RISCV::X1)
3035 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
3036 }
else if (RegEnd == RISCV::X1) {
3037 if (
Reg != RISCV::X8 || (UsesXRegs != (
RegName[0] ==
'x')))
3038 return Error(getLoc(), Twine(
"register must be '") +
3039 (UsesXRegs ?
"x8" :
"s0") +
"'");
3040 }
else if (RegEnd == RISCV::X9 && UsesXRegs) {
3041 if (
Reg != RISCV::X18 || (
RegName[0] !=
'x'))
3042 return Error(getLoc(),
"register must be 'x18'");
3044 return Error(getLoc(),
"too many register ranges");
3051 SMLoc MinusLoc = getLoc();
3053 if (RegEnd == RISCV::X1)
3054 return Error(MinusLoc, Twine(
"register '") + (UsesXRegs ?
"x1" :
"ra") +
3055 "' cannot start a multiple register range");
3058 return Error(getLoc(),
"invalid register");
3060 StringRef
RegName = getTok().getIdentifier();
3063 return Error(getLoc(),
"invalid register");
3065 if (RegEnd == RISCV::X8) {
3066 if ((
Reg != RISCV::X9 &&
3068 (UsesXRegs != (
RegName[0] ==
'x'))) {
3070 return Error(getLoc(),
"register must be 'x9'");
3071 return Error(getLoc(),
"register must be in the range 's1' to 's11'");
3073 }
else if (RegEnd == RISCV::X18) {
3075 return Error(getLoc(),
3076 "register must be in the range 'x19' to 'x27'");
3089 if (RegEnd == RISCV::X26)
3090 return Error(S,
"invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "
3091 "x18-x26}' is not supported");
3097 return Error(S,
"register list must include 's0' or 'x8'");
3099 Operands.push_back(RISCVOperand::createRegList(Encode, S));
3105 bool ExpectNegative) {
3114 auto *RegListOp =
static_cast<RISCVOperand *
>(
Operands.back().
get());
3115 if (!RegListOp->isRegList())
3118 unsigned RlistEncode = RegListOp->RegList.Encoding;
3122 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||
3123 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {
3124 int64_t
Lower = StackAdjBase;
3125 int64_t
Upper = StackAdjBase + 48;
3126 if (ExpectNegative) {
3131 return generateImmOutOfRangeError(S,
Lower,
Upper,
3132 "stack adjustment for register list must "
3133 "be a multiple of 16 bytes in the range");
3137 Operands.push_back(RISCVOperand::createStackAdj(StackAdj, S));
3149 MatchOperandParserImpl(
Operands, Mnemonic,
true);
3156 if (parseRegister(
Operands,
true).isSuccess())
3160 if (parseExpression(
Operands).isSuccess()) {
3163 return !parseMemOpBaseReg(
Operands).isSuccess();
3168 Error(getLoc(),
"unknown operand");
3172bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &Info,
3173 StringRef Name, SMLoc NameLoc,
3179 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
3183 Operands.push_back(RISCVOperand::createToken(Name, NameLoc));
3202 if (getParser().parseEOL(
"unexpected token")) {
3203 getParser().eatToEndOfStatement();
3209bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
3213 Kind = RE->getSpecifier();
3214 Expr = RE->getSubExpr();
3223bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
3232ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
3233 StringRef IDVal = DirectiveID.
getString();
3235 if (IDVal ==
".option")
3236 return parseDirectiveOption();
3237 if (IDVal ==
".attribute")
3238 return parseDirectiveAttribute();
3239 if (IDVal ==
".insn")
3240 return parseDirectiveInsn(DirectiveID.
getLoc());
3241 if (IDVal ==
".variant_cc")
3242 return parseDirectiveVariantCC();
3247bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
3248 bool FromOptionDirective) {
3249 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
3252 clearFeatureBits(Feature.Value, Feature.key());
3259 raw_string_ostream OutputErrMsg(Buffer);
3260 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3261 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
3262 << ErrMsg.getMessage();
3265 return Error(Loc, OutputErrMsg.str());
3267 auto &ISAInfo = *ParseResult;
3270 if (ISAInfo->hasExtension(Feature.key()))
3271 setFeatureBits(Feature.Value, Feature.key());
3273 if (FromOptionDirective) {
3274 if (ISAInfo->getXLen() == 32 && isRV64())
3275 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3276 else if (ISAInfo->getXLen() == 64 && !isRV64())
3277 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3280 if (ISAInfo->getXLen() == 32)
3281 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
3282 else if (ISAInfo->getXLen() == 64)
3283 setFeatureBits(RISCV::Feature64Bit,
"64bit");
3285 return Error(Loc,
"bad arch string " + Arch);
3287 Result = ISAInfo->toString();
3291bool RISCVAsmParser::parseDirectiveOption() {
3292 MCAsmParser &Parser = getParser();
3294 AsmToken Tok = Parser.
getTok();
3302 if (Option ==
"push") {
3306 getTargetStreamer().emitDirectiveOptionPush();
3311 if (Option ==
"pop") {
3316 getTargetStreamer().emitDirectiveOptionPop();
3317 if (popFeatureBits())
3318 return Error(StartLoc,
".option pop with no .option push");
3323 if (Option ==
"arch") {
3331 Type = RISCVOptionArchArgType::Plus;
3333 Type = RISCVOptionArchArgType::Minus;
3334 else if (!
Args.empty())
3336 "unexpected token, expected + or -");
3338 Type = RISCVOptionArchArgType::Full;
3342 "unexpected token, expected identifier");
3348 if (
Type == RISCVOptionArchArgType::Full) {
3350 if (resetToArch(Arch, Loc, Result,
true))
3359 Loc,
"extension version number parsing not currently implemented");
3362 if (!enableExperimentalExtension() &&
3364 return Error(Loc,
"unexpected experimental extensions");
3365 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
3367 if (Ext == std::end(
AllFeatures) || StringRef(Ext->key()) != Feature)
3368 return Error(Loc,
"unknown extension feature");
3372 if (
Type == RISCVOptionArchArgType::Plus) {
3375 setFeatureBits(Ext->Value, Ext->key());
3378 copySTI().setFeatureBits(OldFeatureBits);
3379 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3382 raw_string_ostream OutputErrMsg(Buffer);
3383 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3384 OutputErrMsg << ErrMsg.getMessage();
3387 return Error(Loc, OutputErrMsg.str());
3390 assert(
Type == RISCVOptionArchArgType::Minus);
3396 Feature.Implies.test(Ext->Value))
3397 return Error(Loc, Twine(
"can't disable ") + Ext->key() +
3398 " extension; " + Feature.key() +
3399 " extension requires " + Ext->key() +
3403 clearFeatureBits(Ext->Value, Ext->key());
3410 getTargetStreamer().emitDirectiveOptionArch(Args);
3413 getTargetStreamer().setArchString((*ParseResult)->toString());
3417 if (Option ==
"exact") {
3421 getTargetStreamer().emitDirectiveOptionExact();
3422 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3423 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3427 if (Option ==
"noexact") {
3431 getTargetStreamer().emitDirectiveOptionNoExact();
3432 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3433 setFeatureBits(RISCV::FeatureRelax,
"relax");
3437 if (Option ==
"rvc") {
3441 getTargetStreamer().emitDirectiveOptionRVC();
3442 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3444 getTargetStreamer().setArchString((*ParseResult)->toString());
3448 if (Option ==
"norvc") {
3452 getTargetStreamer().emitDirectiveOptionNoRVC();
3453 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3454 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3456 getTargetStreamer().setArchString((*ParseResult)->toString());
3460 if (Option ==
"pic") {
3464 getTargetStreamer().emitDirectiveOptionPIC();
3465 ParserOptions.IsPicEnabled =
true;
3469 if (Option ==
"nopic") {
3473 getTargetStreamer().emitDirectiveOptionNoPIC();
3474 ParserOptions.IsPicEnabled =
false;
3478 if (Option ==
"relax") {
3482 getTargetStreamer().emitDirectiveOptionRelax();
3483 setFeatureBits(RISCV::FeatureRelax,
"relax");
3487 if (Option ==
"norelax") {
3491 getTargetStreamer().emitDirectiveOptionNoRelax();
3492 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3498 "unknown option, expected 'push', 'pop', "
3499 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3500 "'exact', or 'noexact'");
3508bool RISCVAsmParser::parseDirectiveAttribute() {
3509 MCAsmParser &Parser = getParser();
3515 std::optional<unsigned> Ret =
3518 return Error(TagLoc,
"attribute name not recognised: " + Name);
3522 const MCExpr *AttrExpr;
3529 if (check(!CE, TagLoc,
"expected numeric constant"))
3532 Tag =
CE->getValue();
3538 StringRef StringValue;
3539 int64_t IntegerValue = 0;
3540 bool IsIntegerValue =
true;
3545 IsIntegerValue =
false;
3548 if (IsIntegerValue) {
3549 const MCExpr *ValueExpr;
3555 return Error(ValueExprLoc,
"expected numeric constant");
3556 IntegerValue =
CE->getValue();
3569 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3571 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3574 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3578 getTargetStreamer().emitTextAttribute(
Tag, Result);
3582 getTargetStreamer().setArchString(Result);
3590 .
Cases({
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s"},
true)
3591 .Cases({
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj"},
3593 .
Cases({
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es"},
3602bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3603 MCAsmParser &Parser = getParser();
3610 std::optional<int64_t>
Length;
3620 return Error(ErrorLoc,
3621 "instruction lengths must be a non-zero multiple of two");
3625 return Error(ErrorLoc,
3626 "instruction lengths over 64 bits are not supported");
3632 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3637 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3638 return Error(ErrorLoc,
3639 "instruction length does not match the encoding");
3642 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3645 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3648 if (!getSTI().
hasFeature(RISCV::FeatureStdExtZca) &&
3649 (EncodingDerivedLength == 2))
3650 return Error(ErrorLoc,
"compressed instructions are not allowed");
3652 if (getParser().parseEOL(
"invalid operand for instruction")) {
3653 getParser().eatToEndOfStatement();
3661 Opcode = RISCV::Insn16;
3664 Opcode = RISCV::Insn32;
3667 Opcode = RISCV::Insn48;
3670 Opcode = RISCV::Insn64;
3676 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3678 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3683 return Error(ErrorLoc,
"invalid instruction format");
3685 std::string FormatName = (
".insn_" +
Format).str();
3687 ParseInstructionInfo
Info;
3690 if (parseInstruction(Info, FormatName, L,
Operands))
3702bool RISCVAsmParser::parseDirectiveVariantCC() {
3704 if (getParser().parseIdentifier(Name))
3705 return TokError(
"expected symbol name");
3708 getTargetStreamer().emitDirectiveVariantCC(
3713void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3716 const MCSubtargetInfo &STI = getSTI();
3717 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3720 ++RISCVNumInstrsCompressed;
3724void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3729 for (MCInst &Inst : Seq) {
3730 emitToStreamer(Out, Inst);
3734void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3735 const MCExpr *Symbol,
3737 unsigned SecondOpcode, SMLoc IDLoc,
3745 Out.emitLabel(TmpLabel);
3749 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3754 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3757 .addExpr(RefToLinkTmpLabel));
3760void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3773 Out, MCInstBuilder(RISCV::QC_E_LI).addReg(DestReg).addExpr(Symbol));
3779void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3789 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3790 emitAuipcInstPair(DestReg, DestReg, Symbol,
RISCV::S_GOT_HI, SecondOpcode,
3794void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3803 if (ParserOptions.IsPicEnabled)
3804 emitLoadGlobalAddress(Inst, IDLoc, Out);
3806 emitLoadLocalAddress(Inst, IDLoc, Out);
3809void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3819 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3820 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3821 SecondOpcode, IDLoc, Out);
3824void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3834 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3835 RISCV::ADDI, IDLoc, Out);
3838void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3839 SMLoc IDLoc, MCStreamer &Out,
3848 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3850 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3854 if (getRISCVMCRegisterClass(RISCV::GPRPairRegClassID).
contains(TmpReg)) {
3855 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3856 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3864void RISCVAsmParser::emitQCELILoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3865 SMLoc IDLoc, MCStreamer &Out,
3875 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3879 MCInstBuilder(RISCV::QC_E_LI).addReg(AddrReg).addExpr(Symbol));
3882 const MCExpr *AccessExpr =
3888 struct CompressedForm {
3892 std::optional<CompressedForm> Compressed;
3896 case RISCV::PseudoQCAccessLBU:
3897 Compressed = {RISCV::PseudoQCAccessC_LBU, RISCV::FeatureStdExtZcb};
3899 case RISCV::PseudoQCAccessLH:
3900 Compressed = {RISCV::PseudoQCAccessC_LH, RISCV::FeatureStdExtZcb};
3902 case RISCV::PseudoQCAccessLHU:
3903 Compressed = {RISCV::PseudoQCAccessC_LHU, RISCV::FeatureStdExtZcb};
3905 case RISCV::PseudoQCAccessLW:
3906 Compressed = {RISCV::PseudoQCAccessC_LW, RISCV::FeatureStdExtZca};
3908 case RISCV::PseudoQCAccessSB:
3909 Compressed = {RISCV::PseudoQCAccessC_SB, RISCV::FeatureStdExtZcb};
3911 case RISCV::PseudoQCAccessSH:
3912 Compressed = {RISCV::PseudoQCAccessC_SH, RISCV::FeatureStdExtZcb};
3914 case RISCV::PseudoQCAccessSW:
3915 Compressed = {RISCV::PseudoQCAccessC_SW, RISCV::FeatureStdExtZca};
3922 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(AddrReg);
3923 if (HasTmpReg && CanUseGPRC) {
3926 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(DataReg);
3929 bool UseCompressed =
3930 Compressed && getSTI().hasFeature(Compressed->Feature) && CanUseGPRC;
3932 unsigned ActualOpcode = UseCompressed ? Compressed->Opcode : Opcode;
3935 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3939 .addExpr(AccessExpr));
3941 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3945 .addExpr(AccessExpr));
3949void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3950 int64_t Width, SMLoc IDLoc,
3959 const MCOperand &DestReg = Inst.
getOperand(0);
3960 const MCOperand &SourceReg = Inst.
getOperand(1);
3962 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3963 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3965 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3967 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3972 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3978void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
3985 emitToStreamer(Out, MCInstBuilder(Opcode)
3989 .addReg(MCRegister())
3991 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
4002 "The destination register should not be V0.");
4004 emitToStreamer(Out, MCInstBuilder(Opcode)
4010 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
4022 "The temporary vector register should not be V0.");
4023 emitToStreamer(Out, MCInstBuilder(Opcode)
4027 .addReg(MCRegister())
4029 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4041 "The temporary vector register should not be V0.");
4042 emitToStreamer(Out, MCInstBuilder(Opcode)
4046 .addReg(MCRegister())
4048 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4053 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4058 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
4066bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
4068 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
4071 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
4072 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
4073 "%tprel_add specifier");
4079bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
4081 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
4084 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
4085 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
4086 "%tlsdesc_call specifier");
4092std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
4093 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
4096std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
4097 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
4101std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
4102 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
4106std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultZeroOffset() {
4108 llvm::SMLoc(), llvm::SMLoc(), isRV64());
4115 case RISCV::VLOXSEG2EI8_V:
4116 case RISCV::VLOXSEG2EI16_V:
4117 case RISCV::VLOXSEG2EI32_V:
4118 case RISCV::VLOXSEG2EI64_V:
4119 case RISCV::VLUXSEG2EI8_V:
4120 case RISCV::VLUXSEG2EI16_V:
4121 case RISCV::VLUXSEG2EI32_V:
4122 case RISCV::VLUXSEG2EI64_V:
4124 case RISCV::VLOXSEG3EI8_V:
4125 case RISCV::VLOXSEG3EI16_V:
4126 case RISCV::VLOXSEG3EI32_V:
4127 case RISCV::VLOXSEG3EI64_V:
4128 case RISCV::VLUXSEG3EI8_V:
4129 case RISCV::VLUXSEG3EI16_V:
4130 case RISCV::VLUXSEG3EI32_V:
4131 case RISCV::VLUXSEG3EI64_V:
4133 case RISCV::VLOXSEG4EI8_V:
4134 case RISCV::VLOXSEG4EI16_V:
4135 case RISCV::VLOXSEG4EI32_V:
4136 case RISCV::VLOXSEG4EI64_V:
4137 case RISCV::VLUXSEG4EI8_V:
4138 case RISCV::VLUXSEG4EI16_V:
4139 case RISCV::VLUXSEG4EI32_V:
4140 case RISCV::VLUXSEG4EI64_V:
4142 case RISCV::VLOXSEG5EI8_V:
4143 case RISCV::VLOXSEG5EI16_V:
4144 case RISCV::VLOXSEG5EI32_V:
4145 case RISCV::VLOXSEG5EI64_V:
4146 case RISCV::VLUXSEG5EI8_V:
4147 case RISCV::VLUXSEG5EI16_V:
4148 case RISCV::VLUXSEG5EI32_V:
4149 case RISCV::VLUXSEG5EI64_V:
4151 case RISCV::VLOXSEG6EI8_V:
4152 case RISCV::VLOXSEG6EI16_V:
4153 case RISCV::VLOXSEG6EI32_V:
4154 case RISCV::VLOXSEG6EI64_V:
4155 case RISCV::VLUXSEG6EI8_V:
4156 case RISCV::VLUXSEG6EI16_V:
4157 case RISCV::VLUXSEG6EI32_V:
4158 case RISCV::VLUXSEG6EI64_V:
4160 case RISCV::VLOXSEG7EI8_V:
4161 case RISCV::VLOXSEG7EI16_V:
4162 case RISCV::VLOXSEG7EI32_V:
4163 case RISCV::VLOXSEG7EI64_V:
4164 case RISCV::VLUXSEG7EI8_V:
4165 case RISCV::VLUXSEG7EI16_V:
4166 case RISCV::VLUXSEG7EI32_V:
4167 case RISCV::VLUXSEG7EI64_V:
4169 case RISCV::VLOXSEG8EI8_V:
4170 case RISCV::VLOXSEG8EI16_V:
4171 case RISCV::VLOXSEG8EI32_V:
4172 case RISCV::VLOXSEG8EI64_V:
4173 case RISCV::VLUXSEG8EI8_V:
4174 case RISCV::VLUXSEG8EI16_V:
4175 case RISCV::VLUXSEG8EI32_V:
4176 case RISCV::VLUXSEG8EI64_V:
4182 if (getRISCVMCRegisterClass(RISCV::VRM2RegClassID).
contains(
Reg))
4184 if (getRISCVMCRegisterClass(RISCV::VRM4RegClassID).
contains(
Reg))
4186 if (getRISCVMCRegisterClass(RISCV::VRM8RegClassID).
contains(
Reg))
4193 case RISCV::VFWMMACC_VV_SCALE:
4194 case RISCV::VFQMMACC_VV_SCALE:
4195 case RISCV::VF8WMMACC_VV_SCALE:
4196 case RISCV::VFWIMMACC_VV:
4197 case RISCV::VFQIMMACC_VV:
4198 case RISCV::VF8WIMMACC_VV:
4205bool RISCVAsmParser::validateInstruction(MCInst &Inst,
4209 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
4210 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
4213 if (DestReg == TempReg) {
4214 SMLoc Loc =
Operands.back()->getStartLoc();
4215 return Error(Loc,
"the temporary vector register cannot be the same as "
4216 "the destination register");
4220 if (Opcode == RISCV::PseudoVMSGEU_VX_M || Opcode == RISCV::PseudoVMSGE_VX_M) {
4223 if (MaskReg == RISCV::V0 && DestReg == RISCV::V0) {
4224 SMLoc Loc =
Operands.back()->getStartLoc();
4225 return Error(Loc,
"the destination vector register cannot overlap the "
4226 "mask register unless a temporary register is "
4231 if (Opcode == RISCV::CV_INSERT &&
4234 "the sum of the immediate operands must be less than 32");
4239 case RISCV::TH_LBIA:
4240 case RISCV::TH_LBIB:
4241 case RISCV::TH_LBUIA:
4242 case RISCV::TH_LBUIB:
4243 case RISCV::TH_LHIA:
4244 case RISCV::TH_LHIB:
4245 case RISCV::TH_LHUIA:
4246 case RISCV::TH_LHUIB:
4247 case RISCV::TH_LWIA:
4248 case RISCV::TH_LWIB:
4249 case RISCV::TH_LWUIA:
4250 case RISCV::TH_LWUIB:
4251 case RISCV::TH_LDIA:
4252 case RISCV::TH_LDIB:
4254 return Error(
Operands[1]->getStartLoc(),
"rd and rs1 must be different");
4257 case RISCV::TH_LWUD:
4258 case RISCV::TH_LWD: {
4264 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
4265 SMLoc Loc =
Operands[1]->getStartLoc();
4266 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
4272 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
4276 SMLoc Loc =
Operands[1]->getStartLoc();
4277 return Error(Loc,
"rs1 and rs2 must be different");
4282 auto CheckOperandDoesNotOverlapV0 = [&](
int OperandIdx,
4283 unsigned ParsedIdx) {
4286 "vd, vs1, and vs2 cannot overlap v0.scale");
4291 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4293 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4295 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4296 assert(DestIdx >= 0 && VS1Idx >= 0 && VS2Idx >= 0 &&
4297 "Unexpected Zvvfmm scaled operand list");
4299 if (CheckOperandDoesNotOverlapV0(DestIdx, 1) ||
4300 CheckOperandDoesNotOverlapV0(VS1Idx, 2) ||
4301 CheckOperandDoesNotOverlapV0(VS2Idx, 3))
4305 const MCInstrDesc &MCID = MII.
get(Opcode);
4309 int DestIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4313 const MCParsedAsmOperand *ParsedOp =
Operands[1].get();
4314 if (!ParsedOp->
isReg()) {
4319 assert(ParsedOp->
getReg() == DestReg &&
"Can't find parsed dest operand");
4323 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4327 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4328 assert(VS2Idx >= 0 &&
"No vs2 operand?");
4329 unsigned CheckEncoding =
4332 for (
unsigned i = 0; i < std::max(NF, Lmul); i++) {
4333 if ((DestEncoding + i) == CheckEncoding)
4334 return Error(Loc,
"the destination vector register group cannot overlap"
4335 " the source vector register group");
4340 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4344 unsigned CheckEncoding =
4346 for (
unsigned i = 0; i < Lmul; i++) {
4347 if ((DestEncoding + i) == CheckEncoding)
4349 "the destination vector register group cannot overlap"
4350 " the source vector register group");
4356 int VMIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vm);
4357 assert(VMIdx >= 0 &&
"No vm operand?");
4359 if (DestReg == RISCV::V0) {
4362 return Error(Loc,
"the destination vector register group cannot be V0");
4370 "Unexpected mask operand register");
4372 return Error(Loc,
"the destination vector register group cannot overlap"
4373 " the mask register");
4381 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vmask);
4383 if (MaskReg != RISCV::V0 && MaskReg != RISCV::V1)
4385 "vmask operand only supports v0 or v1");
4388 RISCV::OpName RegOps[] = {RISCV::OpName::vd, RISCV::OpName::vs1,
4389 RISCV::OpName::vs2};
4390 for (RISCV::OpName OpN : RegOps) {
4391 int Idx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), OpN);
4397 for (
unsigned i = 0; i < RegLmul; i++) {
4398 if ((RegEnc + i) == MaskEnc) {
4399 SMLoc Loc =
Operands[Idx]->getStartLoc();
4400 return Error(Loc, Twine(
"register conflicts with vmask register ") +
4410bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
4418 case RISCV::MOP_RR_7: {
4430 case RISCV::MOP_R_28: {
4448 case RISCV::PseudoC_ADDI_NOP: {
4450 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
4460 if (getSTI().
hasFeature(RISCV::Feature64Bit))
4462 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV32)
4467 case RISCV::PACKW: {
4471 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV64)
4476 case RISCV::PseudoLLAImm:
4477 case RISCV::PseudoLAImm:
4478 case RISCV::PseudoLI: {
4484 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
4496 emitLoadImm(
Reg,
Imm, Out);
4499 case RISCV::PseudoLLA:
4500 emitLoadLocalAddress(Inst, IDLoc, Out);
4502 case RISCV::PseudoLGA:
4503 emitLoadGlobalAddress(Inst, IDLoc, Out);
4505 case RISCV::PseudoLA:
4506 emitLoadAddress(Inst, IDLoc, Out);
4508 case RISCV::PseudoLA_TLS_IE:
4509 emitLoadTLSIEAddress(Inst, IDLoc, Out);
4511 case RISCV::PseudoLA_TLS_GD:
4512 emitLoadTLSGDAddress(Inst, IDLoc, Out);
4514 case RISCV::PseudoLB:
4515 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
4517 case RISCV::PseudoLBU:
4518 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
4520 case RISCV::PseudoLH:
4521 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
4523 case RISCV::PseudoLHU:
4524 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
4526 case RISCV::PseudoLW:
4527 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
4529 case RISCV::PseudoLWU:
4530 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
4532 case RISCV::PseudoLD:
4533 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
4535 case RISCV::PseudoLD_RV32:
4536 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
4538 case RISCV::PseudoFLH:
4539 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
4541 case RISCV::PseudoFLW:
4542 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
4544 case RISCV::PseudoFLD:
4545 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
4547 case RISCV::PseudoFLQ:
4548 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
4550 case RISCV::PseudoSB:
4551 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
4553 case RISCV::PseudoSH:
4554 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
4556 case RISCV::PseudoSW:
4557 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
4559 case RISCV::PseudoSD:
4560 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
4562 case RISCV::PseudoSD_RV32:
4563 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
4565 case RISCV::PseudoQC_E_LB:
4566 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLB, IDLoc, Out,
4569 case RISCV::PseudoQC_E_LBU:
4570 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLBU, IDLoc, Out,
4573 case RISCV::PseudoQC_E_LH:
4574 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLH, IDLoc, Out,
4577 case RISCV::PseudoQC_E_LHU:
4578 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLHU, IDLoc, Out,
4581 case RISCV::PseudoQC_E_LW:
4582 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLW, IDLoc, Out,
4585 case RISCV::PseudoQC_E_SB:
4586 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSB, IDLoc, Out,
4589 case RISCV::PseudoQC_E_SH:
4590 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSH, IDLoc, Out,
4593 case RISCV::PseudoQC_E_SW:
4594 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSW, IDLoc, Out,
4597 case RISCV::PseudoFSH:
4598 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
4600 case RISCV::PseudoFSW:
4601 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
4603 case RISCV::PseudoFSD:
4604 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4606 case RISCV::PseudoFSQ:
4607 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4609 case RISCV::PseudoAddTPRel:
4610 if (checkPseudoAddTPRel(Inst,
Operands))
4613 case RISCV::PseudoTLSDESCCall:
4614 if (checkPseudoTLSDESCCall(Inst,
Operands))
4617 case RISCV::PseudoSEXT_B:
4618 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4620 case RISCV::PseudoSEXT_H:
4621 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4623 case RISCV::PseudoZEXT_H:
4624 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4626 case RISCV::PseudoZEXT_W:
4627 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4629 case RISCV::PseudoVMSGEU_VX_M:
4630 case RISCV::PseudoVMSGEU_VX_M_T:
4631 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4633 case RISCV::PseudoVMSGE_VX_M:
4634 case RISCV::PseudoVMSGE_VX_M_T:
4635 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4637 case RISCV::PseudoVMSGE_VI:
4638 case RISCV::PseudoVMSLT_VI: {
4642 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4644 emitToStreamer(Out, MCInstBuilder(
Opc)
4652 case RISCV::PseudoVMSGEU_VI:
4653 case RISCV::PseudoVMSLTU_VI: {
4660 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4663 emitToStreamer(Out, MCInstBuilder(
Opc)
4671 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4674 emitToStreamer(Out, MCInstBuilder(
Opc)
4684 case RISCV::PseudoCV_ELW:
4685 emitLoadStoreSymbol(Inst, RISCV::CV_ELW, IDLoc, Out,
false);
4689 emitToStreamer(Out, Inst);
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
static MCRegister MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, MCRegister &Reg, StringRef Name)
#define LLVM_EXTERNAL_VISIBILITY
const FeatureInfo AllFeatures[]
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static MCRegister convertGPRToYGPR(MCRegister Reg)
bool isValidInsnFormat(StringRef Format, const MCSubtargetInfo &STI)
static bool isZvvfmmScaleOpcode(unsigned Opcode)
static MCRegister convertFPR64ToFPR128(MCRegister Reg)
static MCRegister convertFPR64ToFPR32(MCRegister Reg)
static cl::opt< bool > AddBuildAttributes("riscv-add-build-attributes", cl::init(false))
static MCRegister convertFPR64ToFPR16(MCRegister Reg)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser()
static MCRegister convertFPR64ToFPR256(MCRegister Reg)
static MCRegister convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg, unsigned Kind)
static unsigned getNFforLXSEG(unsigned Opcode)
unsigned getLMULFromVectorRegister(MCRegister Reg)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
LLVM_ABI SMLoc getLoc() const
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
StringRef getStringContents() const
Get the contents of a string token (without quotes).
bool is(TokenKind K) const
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Encoding
Size and signedness of expression operations' operands.
Error takeError()
Take ownership of the stored error.
void printExpr(raw_ostream &, const MCExpr &) const
const AsmToken & getTok()
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
MCStreamer & getStreamer()
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
const MCObjectFileInfo * getObjectFileInfo() const
LLVM_ABI MCSymbol * createNamedTempSymbol()
Create a temporary symbol with a unique name whose name cannot be omitted in the symbol table.
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
ArrayRef< MCOperandInfo > operands() const
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
StringRef getName(unsigned Opcode) const
Returns the name for the instructions with the given opcode.
bool isPositionIndependent() const
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual MCRegister getReg() const =0
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const FeatureBitset & getFeatureBits() const
const FeatureBitset & ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
const MCSymbol * getAddSym() const
uint32_t getSpecifier() const
const MCSymbol * getSubSym() const
Ternary parse status returned by various parse* methods.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
static LLVM_ABI bool isSupportedExtensionFeature(StringRef Ext)
static LLVM_ABI std::string getTargetFeatureForExtension(StringRef Ext)
static LLVM_ABI llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseArchString(StringRef Arch, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck=true)
Parse RISC-V ISA info from arch string.
static const char * getRegisterName(MCRegister Reg)
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
reference emplace_back(ArgTypes &&... Args)
Represent a constant reference to a string, i.e.
std::string str() const
Get the contents as an std::string.
char back() const
Get the last character in the string.
A switch()-like statement whose cases are string literals.
StringSwitch & Cases(std::initializer_list< StringLiteral > CaseStrings, T Value)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
uint16_t StackAdjustment(const RuntimeFunction &RF)
StackAdjustment - calculated stack adjustment in words.
LLVM_ABI std::optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)
MCExpr const & getExpr(MCExpr const &Expr)
Expected< ABI > computeTargetABI(const MCSubtargetInfo &STI, StringRef ABIName)
LLVM_ABI const TagNameMap & getRISCVAttributeTags()
static RoundingMode stringToRoundingMode(StringRef Str)
llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseFeatureBits(const MCSubtargetInfo &STI)
int getLoadFPImm(APFloat FPImm)
getLoadFPImm - Return a 5-bit binary encoding of the floating-point immediate value.
void generateMCInstSeq(int64_t Val, const MCSubtargetInfo &STI, MCRegister DestReg, SmallVectorImpl< MCInst > &Insts)
bool compress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI)
static VLMUL encodeLMUL(unsigned LMUL, bool Fractional)
LLVM_ABI unsigned encodeXSfmmVType(unsigned SEW, unsigned Widen, bool AltFmt)
static bool isValidLMUL(unsigned LMUL, bool Fractional)
static bool isValidSEW(unsigned SEW)
LLVM_ABI void printVType(unsigned VType, raw_ostream &OS)
static bool isValidXSfmmVType(unsigned VTypeI)
LLVM_ABI unsigned encodeVTYPE(VLMUL VLMUL, unsigned SEW, bool TailAgnostic, bool MaskAgnostic, bool AltFmt=false)
unsigned encodeRegList(MCRegister EndReg, bool IsRVE=false)
static unsigned getStackAdjBase(unsigned RlistVal, bool IsRV64)
void printRegList(unsigned RlistEncode, raw_ostream &OS)
Specifier parseSpecifierName(StringRef name)
void updateCZceFeatureImplications(MCSubtargetInfo &STI)
bool isValidYBNDSWImm(int64_t Imm)
@ CE
Windows NT (Windows on ARM)
static SMTVTypeMode stringToSMTVTypeMode(StringRef Str)
static bool isValidSMTVTypeMode(unsigned Mode)
@ Valid
The data is already valid.
initializer< Ty > init(const Ty &Val)
std::function< llvm::json::Value()> Lambda
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
testing::Matcher< const detail::ErrorHolder & > Failed()
Target & getTheRISCV32Target()
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Target & getTheRISCV64beTarget()
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isDigit(char C)
Checks if character C is one of the 10 decimal digits.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
DWARFExpression::Operation Op
Target & getTheRISCV64Target()
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
Target & getTheRISCV32beTarget()
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...