52#define DEBUG_TYPE "riscv-asm-parser"
55 "Number of RISC-V Compressed instructions emitted");
60struct ParserOptionsSet {
65 const RISCVMCOptions &CLOpts;
69 enum class VTypeState {
80 ParserOptionsSet ParserOptions;
82 SMLoc getLoc()
const {
return getParser().
getTok().
getLoc(); }
83 bool isRV64()
const {
return getSTI().hasFeature(RISCV::Feature64Bit); }
84 bool isRVE()
const {
return getSTI().hasFeature(RISCV::FeatureStdExtE); }
85 bool enableExperimentalExtension()
const {
86 return getSTI().hasFeature(RISCV::Experimental);
89 RISCVTargetStreamer &getTargetStreamer() {
90 assert(getParser().getStreamer().getTargetStreamer() &&
91 "do not have a target streamer");
92 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
93 return static_cast<RISCVTargetStreamer &
>(TS);
96 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
97 unsigned Kind)
override;
99 bool generateImmOutOfRangeError(SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
102 struct NearMissMessage {
107 std::string getCustomOperandDiag(
unsigned MatchError);
109 void FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
110 SmallVectorImpl<NearMissMessage> &NearMissesOut,
112 void ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses, SMLoc IDLoc,
115 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
118 bool MatchingInlineAsm)
override;
121 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
122 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
123 SMLoc &EndLoc)
override;
125 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
128 ParseStatus parseDirective(AsmToken DirectiveID)
override;
130 bool parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
unsigned &Sew,
131 unsigned &Lmul,
bool &Fractional,
bool &TailAgnostic,
132 bool &MaskAgnostic,
bool &AltFmt);
133 bool generateVTypeError(SMLoc ErrorLoc);
135 bool generateXSfmmVTypeError(SMLoc ErrorLoc);
138 void emitToStreamer(MCStreamer &S,
const MCInst &Inst);
142 void emitLoadImm(MCRegister DestReg, int64_t
Value, MCStreamer &Out);
146 void emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
148 unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out);
151 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
154 void emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
157 void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
161 void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
165 void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
168 void emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
169 MCStreamer &Out,
bool HasTmpReg);
174 void emitQCELILoadStoreSymbol(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
175 MCStreamer &Out,
bool HasTmpReg);
178 void emitPseudoExtend(MCInst &Inst,
bool SignExtend, int64_t Width,
179 SMLoc IDLoc, MCStreamer &Out);
182 void emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc, MCStreamer &Out);
207#define GET_ASSEMBLER_HEADER
208#include "RISCVGenAsmMatcher.inc"
238 return parseRegList(
Operands,
true);
244 bool ExpectNegative =
false);
246 return parseZcmpStackAdj(
Operands,
true);
250 bool parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
251 bool parseDataExpr(
const MCExpr *&Res)
override;
253 bool parseDirectiveOption();
254 bool parseDirectiveAttribute();
255 bool parseDirectiveInsn(SMLoc L);
256 bool parseDirectiveVariantCC();
261 bool resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
262 bool FromOptionDirective);
264 void setFeatureBits(
uint64_t Feature, StringRef FeatureString) {
266 MCSubtargetInfo &STI = copySTI();
272 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
276 void clearFeatureBits(
uint64_t Feature, StringRef FeatureString) {
278 MCSubtargetInfo &STI = copySTI();
279 setAvailableFeatures(
284 void pushFeatureBits() {
285 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
286 "These two stacks must be kept synchronized");
287 FeatureBitStack.push_back(getSTI().getFeatureBits());
288 ParserOptionsStack.push_back(ParserOptions);
291 bool popFeatureBits() {
292 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
293 "These two stacks must be kept synchronized");
294 if (FeatureBitStack.empty())
297 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
298 copySTI().setFeatureBits(FeatureBits);
299 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
301 ParserOptions = ParserOptionsStack.pop_back_val();
306 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
307 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
308 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
309 std::unique_ptr<RISCVOperand> defaultSMTVType();
310 std::unique_ptr<RISCVOperand> defaultZeroOffset();
313 enum RISCVMatchResultTy :
unsigned {
314 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
315#define GET_OPERAND_DIAGNOSTIC_TYPES
316#include "RISCVGenAsmMatcher.inc"
317#undef GET_OPERAND_DIAGNOSTIC_TYPES
321 static bool isSymbolDiff(
const MCExpr *Expr);
323 RISCVAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
324 const MCInstrInfo &MII)
325 : MCTargetAsmParser(STI, MII),
333 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
338 if (CLOpts.add_build_attributes)
339 getTargetStreamer().emitTargetAttributes(STI,
false);
345 void onBeginOfFile()
override {
348 if (getTargetStreamer().hasTargetABI())
351 Expected<RISCVABI::ABI> ABIOrErr =
355 getTargetStreamer().setTargetABI(
359 getTargetStreamer().setTargetABI(*ABIOrErr);
430 MCRegister OffsetReg;
433 SMLoc StartLoc, EndLoc;
449 RISCVOperand(KindTy K) : Kind(
K) {}
452 RISCVOperand(
const RISCVOperand &o) : MCParsedAsmOperand() {
454 StartLoc =
o.StartLoc;
457 case KindTy::Register:
460 case KindTy::Expression:
463 case KindTy::FPImmediate:
469 case KindTy::SystemRegister:
475 case KindTy::SMTVType:
476 SMTVType =
o.SMTVType;
484 case KindTy::RegList:
487 case KindTy::StackAdj:
488 StackAdj =
o.StackAdj;
496 bool isToken()
const override {
return Kind == KindTy::Token; }
497 bool isReg()
const override {
return Kind == KindTy::Register; }
498 bool isExpr()
const {
return Kind == KindTy::Expression; }
499 bool isV0Reg()
const {
500 return Kind == KindTy::Register &&
Reg.Reg == RISCV::V0;
502 bool isAnyReg()
const {
503 return Kind == KindTy::Register &&
504 (getRISCVMCRegisterClass(RISCV::GPRRegClassID).contains(
Reg.Reg) ||
505 getRISCVMCRegisterClass(RISCV::FPR64RegClassID).contains(
Reg.Reg) ||
506 getRISCVMCRegisterClass(RISCV::VRRegClassID).contains(
Reg.Reg));
508 bool isAnyRegC()
const {
509 return Kind == KindTy::Register &&
510 (getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(
Reg.Reg) ||
511 getRISCVMCRegisterClass(RISCV::FPR64CRegClassID).contains(
Reg.Reg));
513 bool isImm()
const override {
return isExpr(); }
514 bool isMem()
const override {
return false; }
515 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
516 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
517 bool isRegList()
const {
return Kind == KindTy::RegList; }
518 bool isRegListS0()
const {
519 return Kind == KindTy::RegList && RegList.Encoding !=
RISCVZC::RA;
521 bool isStackAdj()
const {
return Kind == KindTy::StackAdj; }
524 return Kind == KindTy::Register &&
525 getRISCVMCRegisterClass(RISCV::GPRRegClassID).contains(
Reg.Reg);
528 bool isYGPR()
const {
529 return Kind == KindTy::Register &&
530 getRISCVMCRegisterClass(RISCV::YGPRRegClassID).contains(
Reg.Reg);
533 bool isGPRPair()
const {
534 return Kind == KindTy::Register &&
535 getRISCVMCRegisterClass(RISCV::GPRPairRegClassID).contains(
Reg.Reg);
538 bool isGPRPairC()
const {
539 return Kind == KindTy::Register &&
540 getRISCVMCRegisterClass(RISCV::GPRPairCRegClassID).contains(
Reg.Reg);
543 bool isGPRPairNoX0()
const {
544 return Kind == KindTy::Register &&
545 getRISCVMCRegisterClass(RISCV::GPRPairNoX0RegClassID)
549 bool isGPRF16()
const {
550 return Kind == KindTy::Register &&
551 getRISCVMCRegisterClass(RISCV::GPRF16RegClassID).contains(
Reg.Reg);
554 bool isGPRF32()
const {
555 return Kind == KindTy::Register &&
556 getRISCVMCRegisterClass(RISCV::GPRF32RegClassID).contains(
Reg.Reg);
559 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
560 bool isGPRAsFPR16()
const {
return isGPRF16() &&
Reg.IsGPRAsFPR; }
561 bool isGPRAsFPR32()
const {
return isGPRF32() &&
Reg.IsGPRAsFPR; }
562 bool isGPRPairAsFPR64()
const {
return isGPRPair() &&
Reg.IsGPRAsFPR; }
564 static bool evaluateConstantExpr(
const MCExpr *Expr, int64_t &
Imm) {
566 Imm =
CE->getValue();
575 template <
int N>
bool isBareSimmNLsb0()
const {
584 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
590 template <
int N>
bool isBareSimmN()
const {
596 return isInt<N>(fixImmediateForRV32(
Imm, isRV64Expr()));
599 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
605 bool isBareSymbol()
const {
608 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
612 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
616 bool isCallSymbol()
const {
619 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
623 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
627 bool isTailCallSymbol()
const {
return isCallSymbol(); }
629 bool isPseudoJumpSymbol()
const {
632 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
636 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
640 bool isTPRelAddSymbol()
const {
643 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
647 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
648 VK == ELF::R_RISCV_TPREL_ADD;
651 bool isTLSDESCCallSymbol()
const {
654 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
658 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
659 VK == ELF::R_RISCV_TLSDESC_CALL;
662 bool isQCAccessSymbol()
const {
665 if (!isExpr() || evaluateConstantExpr(
getExpr(),
Imm))
669 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
673 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
677 bool isVTypeI10()
const {
678 if (Kind == KindTy::VType)
682 bool isVTypeI11()
const {
683 if (Kind == KindTy::VType)
688 bool isXSfmmVType()
const {
692 bool isTileLambda()
const {
698 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
701 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
702 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
707 bool isSMTVType()
const {
708 return Kind == KindTy::SMTVType &&
712 bool isSMTI8()
const {
717 bool isLoadFPImm()
const {
720 if (Kind != KindTy::FPImmediate)
723 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
726 return Idx >= 0 &&
Idx != 1;
729 bool isImmXLenLI()
const {
738 return RISCVAsmParser::isSymbolDiff(
getExpr());
741 bool isImmXLenLI_Restricted()
const {
745 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
747 return IsConstantImm &&
751 template <
unsigned N>
bool isUImm()
const {
755 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
759 template <
unsigned N,
unsigned S>
bool isUImmShifted()
const {
763 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
767 template <
class Pred>
bool isUImmPred(Pred p)
const {
771 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
772 return IsConstantImm &&
p(
Imm);
775 bool isUImmLog2XLen()
const {
776 if (isExpr() && isRV64Expr())
781 bool isUImmLog2XLenNonZero()
const {
782 if (isExpr() && isRV64Expr())
787 bool isUImmLog2XLenHalf()
const {
788 if (isExpr() && isRV64Expr())
793 bool isUImm5NonZero()
const {
797 bool isUImm5GT3()
const {
801 bool isUImm4Plus1()
const {
806 bool isUImm5Plus1()
const {
811 bool isUImm6Plus1()
const {
816 bool isUImm5GE6Plus1()
const {
821 bool isUImm5Slist()
const {
822 return isUImmPred([](int64_t
Imm) {
823 return (
Imm == 0) || (
Imm == 1) || (
Imm == 2) || (
Imm == 4) ||
824 (
Imm == 8) || (
Imm == 16) || (
Imm == 15) || (
Imm == 31);
828 bool isUImm8GE32()
const {
832 bool isRnumArg()
const {
834 [](int64_t
Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(10); });
837 bool isRnumArg_0_7()
const {
839 [](int64_t
Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(7); });
842 bool isRnumArg_1_10()
const {
844 [](int64_t
Imm) {
return Imm >= INT64_C(1) &&
Imm <= INT64_C(10); });
847 bool isRnumArg_2_14()
const {
849 [](int64_t
Imm) {
return Imm >= INT64_C(2) &&
Imm <= INT64_C(14); });
852 template <
unsigned N>
bool isSImm()
const {
856 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
857 return IsConstantImm &&
isInt<N>(fixImmediateForRV32(
Imm, isRV64Expr()));
860 bool isYBNDSWImm()
const {
865 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
869 template <
class Pred>
bool isSImmPred(Pred p)
const {
873 bool IsConstantImm = evaluateConstantExpr(
getExpr(),
Imm);
874 return IsConstantImm &&
p(fixImmediateForRV32(
Imm, isRV64Expr()));
877 bool isSImm5NonZero()
const {
881 bool isSImm6NonZero()
const {
885 bool isCLUIImm()
const {
886 return isUImmPred([](int64_t
Imm) {
891 bool isUImm10Lsb00NonZero()
const {
898 static int64_t fixImmediateForRV32(int64_t
Imm,
bool IsRV64Imm) {
904 bool isSImm12LO()
const {
910 return isInt<12>(fixImmediateForRV32(
Imm, isRV64Expr()));
913 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
916 VK == ELF::R_RISCV_TLSDESC_ADD_LO12);
924 template <
bool (RISCVOperand::*Pred)() const>
925 DiagnosticPredicate isOptionalMemOffset()
const {
929 : DiagnosticPredicate::NearMatch;
932 bool isSImm12Lsb00000()
const {
936 bool isSImm10Lsb0000NonZero()
const {
941 bool isSImm16NonZero()
const {
945 bool isUImm16NonZero()
const {
949 bool isSImm20LI()
const {
955 return isInt<20>(fixImmediateForRV32(
Imm, isRV64Expr()));
958 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
962 bool isSImm8PLI_B()
const {
return isSImm<8>() || isUImm<8>(); }
963 bool isSImm10PLUI()
const {
return isSImm<10>() || isUImm<10>(); }
965 bool isSImm10PLI_H()
const {
966 return isSImm<10>() || isUImmPred([](int64_t
Imm) {
970 bool isSImm10PLI_W()
const {
971 return isSImm<10>() || isUImmPred([](int64_t
Imm) {
976 bool isUImm20LUI()
const {
985 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
986 (VK == ELF::R_RISCV_HI20 || VK == ELF::R_RISCV_TPREL_HI20);
989 bool isUImm20AUIPC()
const {
998 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
1000 VK == ELF::R_RISCV_TLS_GOT_HI20 || VK == ELF::R_RISCV_TLS_GD_HI20 ||
1001 VK == ELF::R_RISCV_TLSDESC_HI20);
1004 bool isImmZero()
const {
1005 return isUImmPred([](int64_t
Imm) {
return 0 ==
Imm; });
1008 bool isImmThree()
const {
1009 return isUImmPred([](int64_t
Imm) {
return 3 ==
Imm; });
1012 bool isImmFour()
const {
1013 return isUImmPred([](int64_t
Imm) {
return 4 ==
Imm; });
1016 bool isImm5Zibi()
const {
1021 bool isSImm5Plus1()
const {
1026 bool isSImm18Lsb0()
const {
1030 bool isSImm19Lsb00()
const {
1034 bool isSImm20Lsb000()
const {
1038 bool isSImm32Lsb0()
const {
1043 SMLoc getStartLoc()
const override {
return StartLoc; }
1045 SMLoc getEndLoc()
const override {
return EndLoc; }
1048 bool isRV64Expr()
const {
1049 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1053 MCRegister
getReg()
const override {
1054 assert(Kind == KindTy::Register &&
"Invalid type access!");
1058 StringRef getSysReg()
const {
1059 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
1060 return StringRef(SysReg.Data, SysReg.Length);
1063 const MCExpr *
getExpr()
const {
1064 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1069 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1074 assert(Kind == KindTy::Token &&
"Invalid type access!");
1078 unsigned getVType()
const {
1079 assert(Kind == KindTy::VType &&
"Invalid type access!");
1084 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1088 unsigned getFence()
const {
1089 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1094 assert(Kind == KindTy::SMTVType &&
"Invalid type access!");
1095 return SMTVType.SMTVType;
1098 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1108 case KindTy::Expression:
1111 OS <<
' ' << (Expr.IsRV64 ?
"rv64" :
"rv32") <<
'>';
1113 case KindTy::FPImmediate:
1114 OS <<
"<fpimm: " << FPImm.Val <<
">";
1116 case KindTy::Register:
1118 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1123 case KindTy::SystemRegister:
1124 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1133 OS << roundingModeToString(getFRM());
1136 case KindTy::SMTVType:
1137 OS <<
"<smtvtype: ";
1138 OS << SMTVTypeModeToString(getSMTVType());
1146 case KindTy::RegList:
1151 case KindTy::StackAdj:
1152 OS <<
"<stackadj: ";
1156 case KindTy::RegReg:
1157 OS <<
"<RegReg: BaseReg " <<
RegName(
RegReg.BaseReg) <<
" OffsetReg "
1163 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1164 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1171 static std::unique_ptr<RISCVOperand>
1172 createReg(MCRegister
Reg, SMLoc S, SMLoc
E,
bool IsGPRAsFPR =
false) {
1173 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1175 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1181 static std::unique_ptr<RISCVOperand> createExpr(
const MCExpr *Val, SMLoc S,
1182 SMLoc
E,
bool IsRV64) {
1183 auto Op = std::make_unique<RISCVOperand>(KindTy::Expression);
1184 Op->Expr.Expr = Val;
1185 Op->Expr.IsRV64 = IsRV64;
1191 static std::unique_ptr<RISCVOperand> createFPImm(
uint64_t Val, SMLoc S) {
1192 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1193 Op->FPImm.Val = Val;
1199 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1200 unsigned Encoding) {
1201 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1202 Op->SysReg.Data = Str.data();
1203 Op->SysReg.Length = Str.size();
1210 static std::unique_ptr<RISCVOperand>
1212 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1219 static std::unique_ptr<RISCVOperand>
1221 auto Op = std::make_unique<RISCVOperand>(KindTy::SMTVType);
1222 Op->SMTVType.SMTVType = VType;
1228 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val, SMLoc S) {
1229 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1230 Op->Fence.Val = Val;
1236 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI, SMLoc S) {
1237 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1238 Op->VType.Val = VTypeI;
1244 static std::unique_ptr<RISCVOperand> createRegList(
unsigned RlistEncode,
1246 auto Op = std::make_unique<RISCVOperand>(KindTy::RegList);
1252 static std::unique_ptr<RISCVOperand>
1253 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {
1254 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1256 Op->RegReg.OffsetReg = OffsetReg;
1262 static std::unique_ptr<RISCVOperand> createStackAdj(
unsigned StackAdj, SMLoc S) {
1263 auto Op = std::make_unique<RISCVOperand>(KindTy::StackAdj);
1264 Op->StackAdj.Val = StackAdj;
1269 static void addExpr(MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1270 assert(Expr &&
"Expr shouldn't be null!");
1282 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1283 assert(
N == 1 &&
"Invalid number of operands!");
1287 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1288 assert(
N == 1 &&
"Invalid number of operands!");
1289 addExpr(Inst,
getExpr(), isRV64Expr());
1292 template <
unsigned Bits>
1293 void addSExtImmOperands(MCInst &Inst,
unsigned N)
const {
1294 assert(
N == 1 &&
"Invalid number of operands!");
1301 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
1302 assert(
N == 1 &&
"Invalid number of operands!");
1304 addExpr(Inst,
getExpr(), isRV64Expr());
1309 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1313 void addFenceArgOperands(MCInst &Inst,
unsigned N)
const {
1314 assert(
N == 1 &&
"Invalid number of operands!");
1318 void addCSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
1319 assert(
N == 1 &&
"Invalid number of operands!");
1326 void addVTypeIOperands(MCInst &Inst,
unsigned N)
const {
1327 assert(
N == 1 &&
"Invalid number of operands!");
1329 if (Kind == KindTy::Expression) {
1330 [[maybe_unused]]
bool IsConstantImm =
1332 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1339 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1340 assert(
N == 1 &&
"Invalid number of operands!");
1344 void addRegRegOperands(MCInst &Inst,
unsigned N)
const {
1345 assert(
N == 2 &&
"Invalid number of operands!");
1350 void addStackAdjOperands(MCInst &Inst,
unsigned N)
const {
1351 assert(
N == 1 &&
"Invalid number of operands!");
1355 void addFRMArgOperands(MCInst &Inst,
unsigned N)
const {
1356 assert(
N == 1 &&
"Invalid number of operands!");
1360 void addSMTVTypeOperand(MCInst &Inst,
unsigned N)
const {
1361 assert(
N == 1 &&
"Invalid number of operands!");
1367#define GET_REGISTER_MATCHER
1368#define GET_SUBTARGET_FEATURE_NAME
1369#define GET_MATCHER_IMPLEMENTATION
1370#define GET_MNEMONIC_SPELL_CHECKER
1371#include "RISCVGenAsmMatcher.inc"
1374 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1375 return Reg - RISCV::F0_D + RISCV::F0_H;
1379 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1380 return Reg - RISCV::F0_D + RISCV::F0_F;
1384 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1385 return Reg - RISCV::F0_D + RISCV::F0_Q;
1389 assert(
Reg >= RISCV::X0 &&
Reg <= RISCV::X31 &&
"Invalid register");
1390 return Reg - RISCV::X0 + RISCV::X0_Y;
1395 unsigned RegClassID;
1396 if (Kind == MCK_VRM2)
1397 RegClassID = RISCV::VRM2RegClassID;
1398 else if (Kind == MCK_VRM4)
1399 RegClassID = RISCV::VRM4RegClassID;
1400 else if (Kind == MCK_VRM8)
1401 RegClassID = RISCV::VRM8RegClassID;
1405 &getRISCVMCRegisterClass(RegClassID));
1409 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1410 return Reg - RISCV::F0_D + RISCV::F0_Q2;
1415 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1417 return Match_InvalidOperand;
1419 MCRegister
Reg =
Op.getReg();
1421 getRISCVMCRegisterClass(RISCV::FPR64RegClassID).contains(
Reg);
1423 getRISCVMCRegisterClass(RISCV::FPR64CRegClassID).contains(
Reg);
1424 bool IsRegVR = getRISCVMCRegisterClass(RISCV::VRRegClassID).contains(
Reg);
1426 if (
Op.isGPR() && Kind == MCK_YGPR) {
1429 return Match_Success;
1431 if (IsRegFPR64 && Kind == MCK_FPR256) {
1433 return Match_Success;
1435 if (IsRegFPR64 && Kind == MCK_FPR128) {
1437 return Match_Success;
1441 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1442 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1444 return Match_Success;
1448 if (IsRegFPR64 && Kind == MCK_FPR16) {
1450 return Match_Success;
1452 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1453 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_H;
1454 return Match_Success;
1456 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1457 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_W;
1458 return Match_Success;
1465 if (getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg) &&
1466 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1468 return Match_Success;
1472 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1475 return Match_InvalidOperand;
1476 return Match_Success;
1478 return Match_InvalidOperand;
1481bool RISCVAsmParser::generateImmOutOfRangeError(
1482 SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
1483 const Twine &
Msg =
"immediate must be an integer in the range") {
1490std::string RISCVAsmParser::getCustomOperandDiag(
unsigned MatchError) {
1492 StringRef
Msg =
"immediate must be an integer in the range") {
1493 return (
Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]").str();
1496 switch (MatchError) {
1500 if (
const char *Diag = getMatchKindDiag((RISCVMatchResultTy)MatchError))
1502 return std::string();
1503 case Match_InvalidImmXLenLI:
1505 return "operand must be a constant 64-bit integer";
1506 return Range(std::numeric_limits<int32_t>::min(),
1507 std::numeric_limits<uint32_t>::max());
1508 case Match_InvalidImmXLenLI_Restricted:
1510 return "operand either must be a constant 64-bit integer "
1511 "or a bare symbol name";
1512 return Range(std::numeric_limits<int32_t>::min(),
1513 std::numeric_limits<uint32_t>::max(),
1514 "operand either must be a bare symbol name or an immediate "
1515 "integer in the range");
1516 case Match_InvalidUImmLog2XLen:
1518 return Range(0, (1 << 6) - 1);
1519 return Range(0, (1 << 5) - 1);
1520 case Match_InvalidUImmLog2XLenNonZero:
1522 return Range(1, (1 << 6) - 1);
1523 return Range(1, (1 << 5) - 1);
1524 case Match_InvalidUImm1:
1525 return Range(0, (1 << 1) - 1);
1526 case Match_InvalidUImm2:
1527 return Range(0, (1 << 2) - 1);
1528 case Match_InvalidUImm2Lsb0:
1529 return Range(0, 2,
"immediate must be one of");
1530 case Match_InvalidUImm3:
1531 return Range(0, (1 << 3) - 1);
1532 case Match_InvalidUImm4:
1533 return Range(0, (1 << 4) - 1);
1534 case Match_InvalidUImm4Plus1:
1535 return Range(1, (1 << 4));
1536 case Match_InvalidUImm5:
1537 return Range(0, (1 << 5) - 1);
1538 case Match_InvalidUImm5NonZero:
1539 return Range(1, (1 << 5) - 1);
1540 case Match_InvalidUImm5GT3:
1541 return Range(4, (1 << 5) - 1);
1542 case Match_InvalidUImm5Plus1:
1543 return Range(1, (1 << 5));
1544 case Match_InvalidUImm5GE6Plus1:
1545 return Range(6, (1 << 5));
1546 case Match_InvalidUImm5Slist:
1547 return "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31";
1548 case Match_InvalidUImm6:
1549 return Range(0, (1 << 6) - 1);
1550 case Match_InvalidUImm6Plus1:
1551 return Range(1, (1 << 6));
1552 case Match_InvalidUImm7:
1553 return Range(0, (1 << 7) - 1);
1554 case Match_InvalidUImm8:
1555 return Range(0, (1 << 8) - 1);
1556 case Match_InvalidUImm8GE32:
1557 return Range(32, (1 << 8) - 1);
1558 case Match_InvalidSImm5:
1559 return Range(-(1 << 4), (1 << 4) - 1);
1560 case Match_InvalidSImm5NonZero:
1561 return Range(-(1 << 4), (1 << 4) - 1,
1562 "immediate must be non-zero in the range");
1563 case Match_InvalidSImm6:
1564 return Range(-(1 << 5), (1 << 5) - 1);
1565 case Match_InvalidSImm6NonZero:
1566 return Range(-(1 << 5), (1 << 5) - 1,
1567 "immediate must be non-zero in the range");
1568 case Match_InvalidCLUIImm:
1569 return Range(1, (1 << 5) - 1,
"immediate must be in [0xfffe0, 0xfffff] or");
1570 case Match_InvalidUImm5Lsb0:
1571 return Range(0, (1 << 5) - 2,
1572 "immediate must be a multiple of 2 bytes in the range");
1573 case Match_InvalidUImm6Lsb0:
1574 return Range(0, (1 << 6) - 2,
1575 "immediate must be a multiple of 2 bytes in the range");
1576 case Match_InvalidUImm6Lsb000:
1577 return Range(0, (1 << 6) - 8,
1578 "immediate must be a multiple of 8 in the range");
1579 case Match_InvalidUImm7Lsb00:
1580 return Range(0, (1 << 7) - 4,
1581 "immediate must be a multiple of 4 bytes in the range");
1582 case Match_InvalidUImm8Lsb00:
1583 return Range(0, (1 << 8) - 4,
1584 "immediate must be a multiple of 4 bytes in the range");
1585 case Match_InvalidUImm8Lsb000:
1586 return Range(0, (1 << 8) - 8,
1587 "immediate must be a multiple of 8 bytes in the range");
1588 case Match_InvalidUImm9:
1589 return Range(0, (1 << 9) - 1,
"immediate offset must be in the range");
1590 case Match_InvalidBareSImm9Lsb0:
1591 return Range(-(1 << 8), (1 << 8) - 2,
1592 "immediate must be a multiple of 2 bytes in the range");
1593 case Match_InvalidUImm9Lsb000:
1594 return Range(0, (1 << 9) - 8,
1595 "immediate must be a multiple of 8 bytes in the range");
1596 case Match_InvalidSImm8PLI_B:
1597 return Range(-(1 << 7), (1 << 8) - 1);
1598 case Match_InvalidSImm10:
1599 case Match_InvalidSImm10PLI_H:
1600 case Match_InvalidSImm10PLI_W:
1601 return Range(-(1 << 9), (1 << 9) - 1);
1602 case Match_InvalidSImm10PLUI:
1603 return Range(-(1 << 9), (1 << 10) - 1);
1604 case Match_InvalidUImm10Lsb00NonZero:
1605 return Range(4, (1 << 10) - 4,
1606 "immediate must be a multiple of 4 bytes in the range");
1607 case Match_InvalidSImm10Lsb0000NonZero:
1609 -(1 << 9), (1 << 9) - 16,
1610 "immediate must be a multiple of 16 bytes and non-zero in the range");
1611 case Match_InvalidSImm11:
1612 return Range(-(1 << 10), (1 << 10) - 1);
1613 case Match_InvalidBareSImm11Lsb0:
1614 return Range(-(1 << 10), (1 << 10) - 2,
1615 "immediate must be a multiple of 2 bytes in the range");
1616 case Match_InvalidUImm10:
1617 return Range(0, (1 << 10) - 1);
1618 case Match_InvalidUImm11:
1619 return Range(0, (1 << 11) - 1);
1620 case Match_InvalidUImm14Lsb00:
1621 return Range(0, (1 << 14) - 4,
1622 "immediate must be a multiple of 4 bytes in the range");
1623 case Match_InvalidUImm16NonZero:
1624 return Range(1, (1 << 16) - 1);
1625 case Match_InvalidSImm12:
1626 return Range(-(1 << 11), (1 << 11) - 1);
1627 case Match_InvalidSImm12LO:
1628 return Range(-(1 << 11), (1 << 11) - 1,
1629 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo "
1630 "specifier or an integer in the range");
1631 case Match_InvalidBareSImm12Lsb0:
1632 return Range(-(1 << 11), (1 << 11) - 2,
1633 "immediate must be a multiple of 2 bytes in the range");
1634 case Match_InvalidSImm12Lsb00000:
1635 return Range(-(1 << 11), (1 << 11) - 32,
1636 "immediate must be a multiple of 32 bytes in the range");
1637 case Match_InvalidBareSImm13Lsb0:
1638 return Range(-(1 << 12), (1 << 12) - 2,
1639 "immediate must be a multiple of 2 bytes in the range");
1640 case Match_InvalidSImm16:
1641 return Range(-(1 << 15), (1 << 15) - 1);
1642 case Match_InvalidSImm16NonZero:
1643 return Range(-(1 << 15), (1 << 15) - 1,
1644 "immediate must be non-zero in the range");
1645 case Match_InvalidSImm20LI:
1646 return Range(-(1 << 19), (1 << 19) - 1,
1647 "operand must be a symbol with a %qc.abs20 specifier or an "
1648 "integer in the range");
1649 case Match_InvalidUImm20LUI:
1650 return Range(0, (1 << 20) - 1,
1651 "operand must be a symbol with %hi/%tprel_hi specifier or an "
1652 "integer in the range");
1653 case Match_InvalidUImm20:
1654 return Range(0, (1 << 20) - 1);
1655 case Match_InvalidUImm20AUIPC:
1658 "operand must be a symbol with a "
1659 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
1660 "or an integer in the range");
1661 case Match_InvalidBareSImm21Lsb0:
1662 return Range(-(1 << 20), (1 << 20) - 2,
1663 "immediate must be a multiple of 2 bytes in the range");
1664 case Match_InvalidCSRSystemRegister:
1665 return Range(0, (1 << 12) - 1,
1666 "operand must be a valid system register name or an integer "
1668 case Match_InvalidImm5Zibi:
1669 return Range(-1, (1 << 5) - 1,
"immediate must be non-zero in the range");
1670 case Match_InvalidVTypeI:
1671 return "operand must be "
1672 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]";
1673 case Match_InvalidSImm5Plus1:
1674 return Range(-(1 << 4) + 1, (1 << 4),
"immediate must be in the range");
1675 case Match_InvalidSImm18:
1676 return Range(-(1 << 17), (1 << 17) - 1);
1677 case Match_InvalidSImm18Lsb0:
1678 return Range(-(1 << 17), (1 << 17) - 2,
1679 "immediate must be a multiple of 2 bytes in the range");
1680 case Match_InvalidSImm19Lsb00:
1681 return Range(-(1 << 18), (1 << 18) - 4,
1682 "immediate must be a multiple of 4 bytes in the range");
1683 case Match_InvalidSImm20Lsb000:
1684 return Range(-(1 << 19), (1 << 19) - 8,
1685 "immediate must be a multiple of 8 bytes in the range");
1686 case Match_InvalidSImm26:
1687 return Range(-(1 << 25), (1 << 25) - 1);
1689 case Match_InvalidBareSymbolQC_E_LI:
1692 case Match_InvalidBareSImm32:
1693 return Range(std::numeric_limits<int32_t>::min(),
1694 std::numeric_limits<uint32_t>::max());
1695 case Match_InvalidBareSImm32Lsb0:
1696 return Range(std::numeric_limits<int32_t>::min(),
1697 std::numeric_limits<int32_t>::max() - 1,
1698 "operand must be a multiple of 2 bytes in the range");
1699 case Match_InvalidRnumArg:
1700 return Range(0, 10);
1701 case Match_InvalidStackAdj:
1702 return "stack adjustment is invalid for this instruction and register "
1704 case Match_InvalidYBNDSWImm:
1705 return "immediate must be an integer in the range "
1706 "[1, 255], a multiple of 8 in the range [256, 504], "
1707 "or a multiple of 16 in the range [512, 4096]";
1714void RISCVAsmParser::FilterNearMisses(
1715 SmallVectorImpl<NearMissInfo> &NearMissesIn,
1716 SmallVectorImpl<NearMissMessage> &NearMissesOut, SMLoc IDLoc,
1720 std::multimap<unsigned, unsigned> OperandMissesSeen;
1721 SmallSet<FeatureBitset, 4> FeatureMissesSeen;
1722 bool ReportedTooFewOperands =
false;
1723 bool ReportedTooManyOperands =
false;
1725 for (NearMissInfo &
I : NearMissesIn) {
1726 switch (
I.getKind()) {
1729 ((RISCVOperand &)*
Operands[
I.getOperandIndex()]).getStartLoc();
1734 if (
I.getOperandClass() == InvalidMatchClass) {
1735 if (!ReportedTooManyOperands) {
1737 OperandLoc,
"unexpected extra operand for instruction"});
1738 ReportedTooManyOperands =
true;
1743 std::string OperandDiag = getCustomOperandDiag(
I.getOperandError());
1747 unsigned DupCheckMatchClass =
1748 OperandDiag.empty() ? ~0
U :
I.getOperandClass();
1749 auto PrevReports = OperandMissesSeen.equal_range(
I.getOperandIndex());
1751 PrevReports.first, PrevReports.second,
1752 [DupCheckMatchClass](
const std::pair<unsigned, unsigned> Pair) {
1753 if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
1754 return Pair.second == DupCheckMatchClass;
1755 return isSubclass((MatchClassKind)DupCheckMatchClass,
1756 (MatchClassKind)Pair.second);
1759 OperandMissesSeen.insert(
1760 std::make_pair(
I.getOperandIndex(), DupCheckMatchClass));
1762 NearMissMessage Message;
1763 Message.Loc = OperandLoc;
1764 if (!OperandDiag.empty()) {
1765 Message.Message = OperandDiag;
1767 Message.Message =
"invalid operand for instruction";
1769 dbgs() <<
"Missing diagnostic string for operand class "
1770 << getMatchClassName((MatchClassKind)
I.getOperandClass())
1771 <<
I.getOperandClass() <<
", error " <<
I.getOperandError()
1772 <<
", opcode " << MII.
getName(
I.getOpcode()) <<
"\n");
1778 const FeatureBitset &MissingFeatures =
I.getFeatures();
1780 if (!FeatureMissesSeen.
insert(MissingFeatures).second)
1783 NearMissMessage Message;
1784 Message.Loc = IDLoc;
1785 bool FirstFeature =
true;
1786 Message.Message =
"instruction requires the following:";
1787 for (
unsigned Feature : MissingFeatures) {
1788 Message.Message += FirstFeature ?
" " :
", ";
1790 FirstFeature =
false;
1800 if (!ReportedTooFewOperands) {
1801 SMLoc EndLoc = ((RISCVOperand &)*
Operands.back()).getEndLoc();
1803 NearMissMessage{EndLoc,
"too few operands for instruction"});
1804 ReportedTooFewOperands =
true;
1816void RISCVAsmParser::ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses,
1819 FilterNearMisses(NearMisses, Messages, IDLoc,
Operands);
1824 Error(IDLoc,
"invalid instruction");
1827 Error(Messages[0].Loc, Messages[0].Message);
1832 "invalid instruction, any one of the following would fix this:");
1833 for (
auto &M : Messages)
1838bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1842 bool MatchingInlineAsm) {
1847 MatchInstructionImpl(
Operands, Inst, &NearMisses, MatchingInlineAsm);
1852 if (validateInstruction(Inst,
Operands))
1854 return processInstruction(Inst, IDLoc,
Operands, Out);
1855 case Match_MnemonicFail: {
1856 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1857 std::string Suggestion = RISCVMnemonicSpellCheck(
1859 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1861 case Match_NearMisses:
1862 ReportNearMisses(NearMisses, IDLoc,
Operands);
1873MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name)
const {
1882 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1883 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1884 static_assert(RISCV::F0_D < RISCV::F0_Q,
"FPR matching must be updated");
1887 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1892bool RISCVAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1894 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1895 return Error(StartLoc,
"invalid register name");
1899ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1901 const AsmToken &Tok = getParser().getTok();
1904 StringRef
Name = getLexer().getTok().getIdentifier();
1916 SMLoc FirstS = getLoc();
1917 bool HadParens =
false;
1924 size_t ReadCount = getLexer().peekTokens(Buf);
1927 LParen = getParser().getTok();
1932 switch (getLexer().getKind()) {
1935 getLexer().UnLex(LParen);
1938 StringRef
Name = getLexer().getTok().getIdentifier();
1943 getLexer().UnLex(LParen);
1947 Operands.push_back(RISCVOperand::createToken(
"(", FirstS));
1949 SMLoc
E = getTok().getEndLoc();
1951 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
1956 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
1967 switch (getLexer().getKind()) {
1977 if (getParser().parseExpression(Res,
E))
1982 int64_t
Imm =
CE->getValue();
1984 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1993 if (getParser().parseIdentifier(Identifier))
1996 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1999 "Unexpected opcode");
2002 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2012 return generateImmOutOfRangeError(
2014 "opcode must be a valid opcode name or an immediate in the range");
2022 switch (getLexer().getKind()) {
2032 if (getParser().parseExpression(Res,
E))
2037 int64_t
Imm =
CE->getValue();
2038 if (
Imm >= 0 &&
Imm <= 2) {
2039 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2048 if (getParser().parseIdentifier(Identifier))
2052 if (Identifier ==
"C0")
2054 else if (Identifier ==
"C1")
2056 else if (Identifier ==
"C2")
2063 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2072 return generateImmOutOfRangeError(
2074 "opcode must be a valid opcode name or an immediate in the range");
2081 auto SysRegFromConstantInt = [
this](
const MCExpr *
E, SMLoc S) {
2083 int64_t
Imm =
CE->getValue();
2085 auto Range = RISCVSysReg::lookupSysRegByEncoding(
Imm);
2089 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2092 return RISCVOperand::createSysReg(
2093 RISCVSysReg::getSysRegStr(
Reg.Name), S,
Imm);
2097 return RISCVOperand::createSysReg(
"", S,
Imm);
2100 return std::unique_ptr<RISCVOperand>();
2103 switch (getLexer().getKind()) {
2113 if (getParser().parseExpression(Res))
2116 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
2117 Operands.push_back(std::move(SysOpnd));
2121 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2125 if (getParser().parseIdentifier(Identifier))
2128 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
2131 if (SysReg->IsDeprecatedName) {
2133 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
2135 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2137 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
2138 RISCVSysReg::getSysRegStr(
Reg.Name) +
"'");
2143 const auto &FeatureBits = getSTI().getFeatureBits();
2144 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
2145 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
2146 const auto *Feature =
2148 return SysReg->FeaturesRequired[Feature.Value];
2150 std::string ErrorMsg =
2151 std::string(
"system register '") +
2152 std::string(RISCVSysReg::getSysRegStr(SysReg->Name)) +
"' ";
2153 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
2154 ErrorMsg +=
"is RV32 only";
2156 ErrorMsg +=
" and ";
2160 "requires '" + std::string(Feature->key()) +
"' to be enabled";
2163 return Error(S, ErrorMsg);
2166 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
2176 Operands.push_back(std::move(SysOpnd));
2181 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2182 "operand must be a valid system register "
2183 "name or an integer in the range");
2187 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2199 StringRef
Identifier = getTok().getIdentifier();
2200 if (
Identifier.compare_insensitive(
"inf") == 0) {
2203 getTok().getEndLoc(), isRV64()));
2204 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2207 getTok().getEndLoc(), isRV64()));
2208 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2211 getTok().getEndLoc(), isRV64()));
2213 return TokError(
"invalid floating point literal");
2224 const AsmToken &Tok = getTok();
2226 return TokError(
"invalid floating point immediate");
2229 APFloat RealVal(APFloat::IEEEdouble());
2231 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2233 return TokError(
"invalid floating point representation");
2236 RealVal.changeSign();
2238 Operands.push_back(RISCVOperand::createFPImm(
2239 RealVal.bitcastToAPInt().getZExtValue(), S));
2251 switch (getLexer().getKind()) {
2263 if (getParser().parseExpression(Res,
E))
2267 return parseOperandWithSpecifier(
Operands);
2270 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2280 const MCExpr *Expr =
nullptr;
2281 bool Failed = parseExprWithSpecifier(Expr,
E);
2283 Operands.push_back(RISCVOperand::createExpr(Expr, S,
E, isRV64()));
2287bool RISCVAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
2288 SMLoc Loc = getLoc();
2290 return TokError(
"expected '%' relocation specifier");
2291 StringRef
Identifier = getParser().getTok().getIdentifier();
2294 return TokError(
"invalid relocation specifier");
2300 const MCExpr *SubExpr;
2301 if (getParser().parseParenExpression(SubExpr,
E))
2308bool RISCVAsmParser::parseDataExpr(
const MCExpr *&Res) {
2311 return parseExprWithSpecifier(Res,
E);
2312 return getParser().parseExpression(Res);
2322 StringRef
Identifier = getTok().getIdentifier();
2332 if (getParser().parseExpression(Res,
E))
2335 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2345 std::string
Identifier(getTok().getIdentifier());
2351 SMLoc Loc = getLoc();
2352 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2353 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2367 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2379 std::string
Identifier(getTok().getIdentifier());
2385 SMLoc Loc = getLoc();
2386 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2387 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2401 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2410 if (getParser().parseExpression(Res,
E))
2413 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef)
2414 return Error(S,
"operand must be a valid jump target");
2417 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2438bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2439 unsigned &Sew,
unsigned &Lmul,
2440 bool &Fractional,
bool &TailAgnostic,
2441 bool &MaskAgnostic,
bool &AltFmt) {
2446 if (State < VTypeState::SeenSew &&
Identifier.consume_front(
"e")) {
2448 if (Identifier ==
"16alt") {
2451 }
else if (Identifier ==
"8alt") {
2461 State = VTypeState::SeenSew;
2465 if (State < VTypeState::SeenLmul &&
Identifier.consume_front(
"m")) {
2468 if (Identifier ==
"a" || Identifier ==
"u") {
2470 State = VTypeState::SeenMaskPolicy;
2481 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2482 unsigned MinLMUL = ELEN / 8;
2485 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2486 Twine(MinLMUL) +
" is reserved");
2489 State = VTypeState::SeenLmul;
2493 if (State < VTypeState::SeenTailPolicy &&
Identifier.starts_with(
"t")) {
2494 if (Identifier ==
"ta")
2495 TailAgnostic =
true;
2496 else if (Identifier ==
"tu")
2497 TailAgnostic =
false;
2501 State = VTypeState::SeenTailPolicy;
2505 if (State < VTypeState::SeenMaskPolicy &&
Identifier.starts_with(
"m")) {
2506 if (Identifier ==
"ma")
2507 MaskAgnostic =
true;
2508 else if (Identifier ==
"mu")
2509 MaskAgnostic =
false;
2513 State = VTypeState::SeenMaskPolicy;
2526 bool Fractional =
false;
2527 bool TailAgnostic =
false;
2528 bool MaskAgnostic =
false;
2531 VTypeState State = VTypeState::SeenNothingYet;
2533 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2534 MaskAgnostic, AltFmt)) {
2536 if (State == VTypeState::SeenNothingYet)
2545 State == VTypeState::SeenNothingYet)
2546 return generateVTypeError(S);
2550 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2551 unsigned MaxSEW = ELEN / Lmul;
2553 if (MaxSEW >= 8 && Sew > MaxSEW)
2554 Warning(S,
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2555 " and LMUL == mf" + Twine(Lmul) +
2556 " may not be compatible with all RVV implementations");
2561 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2565bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2566 return Error(ErrorLoc,
2568 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2588 if (Identifier !=
"16alt")
2617 Operands.push_back(RISCVOperand::createVType(
2623 return generateXSfmmVTypeError(S);
2626bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
2627 return Error(ErrorLoc,
"operand must be e[8|16|16alt|32|64],w[1|2|4]");
2634 StringRef
Name = getLexer().getTok().getIdentifier();
2635 if (!
Name.consume_back(
".t")) {
2639 return Error(getLoc(),
"expected '.t' suffix");
2646 if (
Reg != RISCV::V0)
2649 SMLoc
E = getTok().getEndLoc();
2651 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2659 StringRef
Name = getLexer().getTok().getIdentifier();
2660 if (!
Name.consume_back(
".scale"))
2661 return Error(getLoc(),
"expected '.scale' suffix");
2666 if (
Reg != RISCV::V0)
2669 SMLoc
E = getTok().getEndLoc();
2671 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2680 StringRef
Name = getLexer().getTok().getIdentifier();
2681 if (!
Name.consume_front(
"L") && !
Name.consume_front(
"l"))
2686 return Error(S,
"operand must be L1, L2, L4, L8, L16, L32, or L64");
2688 unsigned EncodedLambda =
Log2_32(Lambda) + 1;
2690 SMLoc
E = getTok().getEndLoc();
2692 Operands.push_back(RISCVOperand::createExpr(
2698 if (!isRV64() || getSTI().
hasFeature(RISCV::FeatureStdExtF))
2708 StringRef
Name = getLexer().getTok().getIdentifier();
2714 SMLoc
E = getTok().getEndLoc();
2716 Operands.push_back(RISCVOperand::createReg(
2722 if (isRV64() || getSTI().
hasFeature(RISCV::FeatureStdExtF))
2728 StringRef
Name = getLexer().getTok().getIdentifier();
2734 if (!getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg))
2737 if ((
Reg - RISCV::X0) & 1) {
2740 if (getSTI().
hasFeature(RISCV::FeatureStdExtZfinx))
2741 return TokError(
"double precision floating point operands must use even "
2742 "numbered X register");
2747 SMLoc
E = getTok().getEndLoc();
2750 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2752 Reg, RISCV::sub_gpr_even,
2753 &getRISCVMCRegisterClass(RISCV::GPRPairRegClassID));
2754 Operands.push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2758template <
bool IsRV64>
2760 return parseGPRPair(
Operands, IsRV64);
2770 if (!IsRV64Inst && isRV64())
2776 StringRef
Name = getLexer().getTok().getIdentifier();
2782 if (!getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg))
2785 if ((
Reg - RISCV::X0) & 1)
2786 return TokError(
"register must be even");
2789 SMLoc
E = getTok().getEndLoc();
2792 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2794 Reg, RISCV::sub_gpr_even,
2795 &getRISCVMCRegisterClass(RISCV::GPRPairRegClassID));
2796 Operands.push_back(RISCVOperand::createReg(Pair, S,
E));
2803 "operand must be a valid SpacemiT's Integer Matrix VType mnemonic");
2805 StringRef Str = getLexer().getTok().getIdentifier();
2808 if (!isValidSMTVTypeMode(VType))
2809 return TokError(
"SpacemiT's Integer Matrix only supports [i4|i8] mode");
2811 Operands.push_back(RISCVOperand::createSMTVType(VType, getLoc()));
2819 "operand must be a valid floating point rounding mode mnemonic");
2821 StringRef Str = getLexer().getTok().getIdentifier();
2826 "operand must be a valid floating point rounding mode mnemonic");
2828 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2833std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultSMTVType() {
2834 return RISCVOperand::createSMTVType(XSMTVTypeMode::SMTVTypeMode::SMT_I8,
2839 const AsmToken &Tok = getLexer().getTok();
2845 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2859 for (
char c : Str) {
2888 Operands.push_back(RISCVOperand::createFenceArg(
Imm, getLoc()));
2894 return TokError(
"operand must be formed of letters selected in-order from "
2901 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
2903 if (!parseRegister(
Operands).isSuccess())
2904 return Error(getLoc(),
"expected register");
2908 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2932 std::unique_ptr<RISCVOperand> OptionalImmOp;
2939 SMLoc ImmStart = getLoc();
2940 if (getParser().parseIntToken(ImmVal,
2941 "expected '(' or optional integer offset"))
2946 SMLoc ImmEnd = getLoc();
2949 ImmStart, ImmEnd, isRV64());
2953 OptionalImmOp ?
"expected '(' after optional integer offset"
2954 :
"expected '(' or optional integer offset"))
2957 if (!parseRegister(
Operands).isSuccess())
2958 return Error(getLoc(),
"expected register");
2964 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2966 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2967 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2978 StringRef OffsetRegName = getLexer().getTok().getIdentifier();
2981 !getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(OffsetReg))
2982 return Error(getLoc(),
"expected GPR register");
2989 return Error(getLoc(),
"expected GPR register");
2991 StringRef BaseRegName = getLexer().getTok().getIdentifier();
2994 !getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(BaseReg))
2995 return Error(getLoc(),
"expected GPR register");
3001 Operands.push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));
3014 bool MustIncludeS0) {
3026 return Error(getLoc(),
"invalid register");
3028 StringRef
RegName = getTok().getIdentifier();
3031 return Error(getLoc(),
"invalid register");
3034 UsesXRegs =
RegName[0] ==
'x';
3035 if (
Reg != RISCV::X1)
3036 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
3037 }
else if (RegEnd == RISCV::X1) {
3038 if (
Reg != RISCV::X8 || (UsesXRegs != (
RegName[0] ==
'x')))
3039 return Error(getLoc(), Twine(
"register must be '") +
3040 (UsesXRegs ?
"x8" :
"s0") +
"'");
3041 }
else if (RegEnd == RISCV::X9 && UsesXRegs) {
3042 if (
Reg != RISCV::X18 || (
RegName[0] !=
'x'))
3043 return Error(getLoc(),
"register must be 'x18'");
3045 return Error(getLoc(),
"too many register ranges");
3052 SMLoc MinusLoc = getLoc();
3054 if (RegEnd == RISCV::X1)
3055 return Error(MinusLoc, Twine(
"register '") + (UsesXRegs ?
"x1" :
"ra") +
3056 "' cannot start a multiple register range");
3059 return Error(getLoc(),
"invalid register");
3061 StringRef
RegName = getTok().getIdentifier();
3064 return Error(getLoc(),
"invalid register");
3066 if (RegEnd == RISCV::X8) {
3067 if ((
Reg != RISCV::X9 &&
3069 (UsesXRegs != (
RegName[0] ==
'x'))) {
3071 return Error(getLoc(),
"register must be 'x9'");
3072 return Error(getLoc(),
"register must be in the range 's1' to 's11'");
3074 }
else if (RegEnd == RISCV::X18) {
3076 return Error(getLoc(),
3077 "register must be in the range 'x19' to 'x27'");
3090 if (RegEnd == RISCV::X26)
3091 return Error(S,
"invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "
3092 "x18-x26}' is not supported");
3098 return Error(S,
"register list must include 's0' or 'x8'");
3100 Operands.push_back(RISCVOperand::createRegList(Encode, S));
3106 bool ExpectNegative) {
3115 auto *RegListOp =
static_cast<RISCVOperand *
>(
Operands.back().
get());
3116 if (!RegListOp->isRegList())
3119 unsigned RlistEncode = RegListOp->RegList.Encoding;
3123 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||
3124 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {
3125 int64_t
Lower = StackAdjBase;
3126 int64_t
Upper = StackAdjBase + 48;
3127 if (ExpectNegative) {
3132 return generateImmOutOfRangeError(S,
Lower,
Upper,
3133 "stack adjustment for register list must "
3134 "be a multiple of 16 bytes in the range");
3138 Operands.push_back(RISCVOperand::createStackAdj(StackAdj, S));
3150 MatchOperandParserImpl(
Operands, Mnemonic,
true);
3157 if (parseRegister(
Operands,
true).isSuccess())
3161 if (parseExpression(
Operands).isSuccess()) {
3164 return !parseMemOpBaseReg(
Operands).isSuccess();
3169 Error(getLoc(),
"unknown operand");
3173bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &Info,
3174 StringRef Name, SMLoc NameLoc,
3180 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
3184 Operands.push_back(RISCVOperand::createToken(Name, NameLoc));
3203 if (getParser().parseEOL(
"unexpected token")) {
3204 getParser().eatToEndOfStatement();
3210bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
3214 Kind = RE->getSpecifier();
3215 Expr = RE->getSubExpr();
3224bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
3233ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
3234 StringRef IDVal = DirectiveID.
getString();
3236 if (IDVal ==
".option")
3237 return parseDirectiveOption();
3238 if (IDVal ==
".attribute")
3239 return parseDirectiveAttribute();
3240 if (IDVal ==
".insn")
3241 return parseDirectiveInsn(DirectiveID.
getLoc());
3242 if (IDVal ==
".variant_cc")
3243 return parseDirectiveVariantCC();
3248bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
3249 bool FromOptionDirective) {
3255 raw_string_ostream OutputErrMsg(Buffer);
3256 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3257 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
3258 << ErrMsg.getMessage();
3261 return Error(Loc, OutputErrMsg.str());
3263 auto &ISAInfo = *ParseResult;
3265 if (FromOptionDirective) {
3266 if (ISAInfo->getXLen() == 32 && isRV64())
3267 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3268 else if (ISAInfo->getXLen() == 64 && !isRV64())
3269 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3271 if (ISAInfo->getXLen() != 32 && ISAInfo->getXLen() != 64)
3272 return Error(Loc,
"bad arch string " + Arch);
3278 MCSubtargetInfo &STI = copySTI();
3282 if (ISAInfo->hasExtension(Feature.key()) != STI.
hasFeature(Feature.Value))
3285 if ((ISAInfo->getXLen() == 64) != STI.
hasFeature(RISCV::Feature64Bit))
3287 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
3289 Result = ISAInfo->toString();
3293bool RISCVAsmParser::parseDirectiveOption() {
3294 MCAsmParser &Parser = getParser();
3296 AsmToken Tok = Parser.
getTok();
3304 if (Option ==
"push") {
3308 getTargetStreamer().emitDirectiveOptionPush();
3313 if (Option ==
"pop") {
3318 getTargetStreamer().emitDirectiveOptionPop();
3319 if (popFeatureBits())
3320 return Error(StartLoc,
".option pop with no .option push");
3325 if (Option ==
"arch") {
3333 Type = RISCVOptionArchArgType::Plus;
3335 Type = RISCVOptionArchArgType::Minus;
3336 else if (!
Args.empty())
3338 "unexpected token, expected + or -");
3340 Type = RISCVOptionArchArgType::Full;
3344 "unexpected token, expected identifier");
3350 if (
Type == RISCVOptionArchArgType::Full) {
3352 if (resetToArch(Arch, Loc, Result,
true))
3361 Loc,
"extension version number parsing not currently implemented");
3364 if (!enableExperimentalExtension() &&
3366 return Error(Loc,
"unexpected experimental extensions");
3367 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
3369 if (Ext == std::end(
AllFeatures) || StringRef(Ext->key()) != Feature)
3370 return Error(Loc,
"unknown extension feature");
3374 if (
Type == RISCVOptionArchArgType::Plus) {
3377 setFeatureBits(Ext->Value, Ext->key());
3380 copySTI().setFeatureBits(OldFeatureBits);
3381 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3384 raw_string_ostream OutputErrMsg(Buffer);
3385 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3386 OutputErrMsg << ErrMsg.getMessage();
3389 return Error(Loc, OutputErrMsg.str());
3392 assert(
Type == RISCVOptionArchArgType::Minus);
3398 Feature.Implies.test(Ext->Value))
3399 return Error(Loc, Twine(
"can't disable ") + Ext->key() +
3400 " extension; " + Feature.key() +
3401 " extension requires " + Ext->key() +
3405 clearFeatureBits(Ext->Value, Ext->key());
3412 getTargetStreamer().emitDirectiveOptionArch(Args);
3415 getTargetStreamer().setArchString((*ParseResult)->toString());
3419 if (Option ==
"exact") {
3423 getTargetStreamer().emitDirectiveOptionExact();
3424 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3425 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3429 if (Option ==
"noexact") {
3433 getTargetStreamer().emitDirectiveOptionNoExact();
3434 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3435 setFeatureBits(RISCV::FeatureRelax,
"relax");
3439 if (Option ==
"rvc") {
3443 getTargetStreamer().emitDirectiveOptionRVC();
3444 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3446 getTargetStreamer().setArchString((*ParseResult)->toString());
3450 if (Option ==
"norvc") {
3454 getTargetStreamer().emitDirectiveOptionNoRVC();
3455 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3456 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3458 getTargetStreamer().setArchString((*ParseResult)->toString());
3462 if (Option ==
"pic") {
3466 getTargetStreamer().emitDirectiveOptionPIC();
3467 ParserOptions.IsPicEnabled =
true;
3471 if (Option ==
"nopic") {
3475 getTargetStreamer().emitDirectiveOptionNoPIC();
3476 ParserOptions.IsPicEnabled =
false;
3480 if (Option ==
"relax") {
3484 getTargetStreamer().emitDirectiveOptionRelax();
3485 setFeatureBits(RISCV::FeatureRelax,
"relax");
3489 if (Option ==
"norelax") {
3493 getTargetStreamer().emitDirectiveOptionNoRelax();
3494 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3500 "unknown option, expected 'push', 'pop', "
3501 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3502 "'exact', or 'noexact'");
3510bool RISCVAsmParser::parseDirectiveAttribute() {
3511 MCAsmParser &Parser = getParser();
3517 std::optional<unsigned> Ret =
3520 return Error(TagLoc,
"attribute name not recognised: " + Name);
3524 const MCExpr *AttrExpr;
3531 if (check(!CE, TagLoc,
"expected numeric constant"))
3534 Tag =
CE->getValue();
3540 StringRef StringValue;
3541 int64_t IntegerValue = 0;
3542 bool IsIntegerValue =
true;
3547 IsIntegerValue =
false;
3550 if (IsIntegerValue) {
3551 const MCExpr *ValueExpr;
3557 return Error(ValueExprLoc,
"expected numeric constant");
3558 IntegerValue =
CE->getValue();
3571 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3573 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3576 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3580 getTargetStreamer().emitTextAttribute(
Tag, Result);
3584 getTargetStreamer().setArchString(Result);
3592 .
Cases({
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s"},
true)
3593 .Cases({
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj"},
3595 .
Cases({
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es"},
3604bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3605 MCAsmParser &Parser = getParser();
3612 std::optional<int64_t>
Length;
3622 return Error(ErrorLoc,
3623 "instruction lengths must be a non-zero multiple of two");
3627 return Error(ErrorLoc,
3628 "instruction lengths over 64 bits are not supported");
3634 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3639 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3640 return Error(ErrorLoc,
3641 "instruction length does not match the encoding");
3644 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3647 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3650 if (!getSTI().
hasFeature(RISCV::FeatureStdExtZca) &&
3651 (EncodingDerivedLength == 2))
3652 return Error(ErrorLoc,
"compressed instructions are not allowed");
3654 if (getParser().parseEOL(
"invalid operand for instruction")) {
3655 getParser().eatToEndOfStatement();
3663 Opcode = RISCV::Insn16;
3666 Opcode = RISCV::Insn32;
3669 Opcode = RISCV::Insn48;
3672 Opcode = RISCV::Insn64;
3678 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3680 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3685 return Error(ErrorLoc,
"invalid instruction format");
3687 std::string FormatName = (
".insn_" +
Format).str();
3689 ParseInstructionInfo
Info;
3692 if (parseInstruction(Info, FormatName, L,
Operands))
3704bool RISCVAsmParser::parseDirectiveVariantCC() {
3706 if (getParser().parseIdentifier(Name))
3707 return TokError(
"expected symbol name");
3710 getTargetStreamer().emitDirectiveVariantCC(
3715void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3718 const MCSubtargetInfo &STI = getSTI();
3719 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3722 ++RISCVNumInstrsCompressed;
3726void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3731 for (MCInst &Inst : Seq) {
3732 emitToStreamer(Out, Inst);
3736void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3737 const MCExpr *Symbol,
3739 unsigned SecondOpcode, SMLoc IDLoc,
3747 Out.emitLabel(TmpLabel);
3751 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3756 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3759 .addExpr(RefToLinkTmpLabel));
3762void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3773 STI->
hasFeature(RISCV::FeatureVendorXqcili) &&
3774 !ParserOptions.IsPicEnabled)
3776 Out, MCInstBuilder(RISCV::QC_E_LI).addReg(DestReg).addExpr(Symbol));
3782void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3792 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3793 emitAuipcInstPair(DestReg, DestReg, Symbol,
RISCV::S_GOT_HI, SecondOpcode,
3797void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3806 if (ParserOptions.IsPicEnabled)
3807 emitLoadGlobalAddress(Inst, IDLoc, Out);
3809 emitLoadLocalAddress(Inst, IDLoc, Out);
3812void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3822 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3823 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3824 SecondOpcode, IDLoc, Out);
3827void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3837 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3838 RISCV::ADDI, IDLoc, Out);
3841void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3842 SMLoc IDLoc, MCStreamer &Out,
3851 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3853 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3857 if (getRISCVMCRegisterClass(RISCV::GPRPairRegClassID).
contains(TmpReg)) {
3858 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3859 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3867void RISCVAsmParser::emitQCELILoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3868 SMLoc IDLoc, MCStreamer &Out,
3878 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3882 MCInstBuilder(RISCV::QC_E_LI).addReg(AddrReg).addExpr(Symbol));
3885 const MCExpr *AccessExpr =
3891 struct CompressedForm {
3895 std::optional<CompressedForm> Compressed;
3899 case RISCV::PseudoQCAccessLBU:
3900 Compressed = {RISCV::PseudoQCAccessC_LBU, RISCV::FeatureStdExtZcb};
3902 case RISCV::PseudoQCAccessLH:
3903 Compressed = {RISCV::PseudoQCAccessC_LH, RISCV::FeatureStdExtZcb};
3905 case RISCV::PseudoQCAccessLHU:
3906 Compressed = {RISCV::PseudoQCAccessC_LHU, RISCV::FeatureStdExtZcb};
3908 case RISCV::PseudoQCAccessLW:
3909 Compressed = {RISCV::PseudoQCAccessC_LW, RISCV::FeatureStdExtZca};
3911 case RISCV::PseudoQCAccessSB:
3912 Compressed = {RISCV::PseudoQCAccessC_SB, RISCV::FeatureStdExtZcb};
3914 case RISCV::PseudoQCAccessSH:
3915 Compressed = {RISCV::PseudoQCAccessC_SH, RISCV::FeatureStdExtZcb};
3917 case RISCV::PseudoQCAccessSW:
3918 Compressed = {RISCV::PseudoQCAccessC_SW, RISCV::FeatureStdExtZca};
3925 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(AddrReg);
3926 if (HasTmpReg && CanUseGPRC) {
3929 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(DataReg);
3932 bool UseCompressed =
3933 Compressed && getSTI().hasFeature(Compressed->Feature) && CanUseGPRC;
3935 unsigned ActualOpcode = UseCompressed ? Compressed->Opcode : Opcode;
3938 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3942 .addExpr(AccessExpr));
3944 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3948 .addExpr(AccessExpr));
3952void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3953 int64_t Width, SMLoc IDLoc,
3962 const MCOperand &DestReg = Inst.
getOperand(0);
3963 const MCOperand &SourceReg = Inst.
getOperand(1);
3965 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3966 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3968 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3970 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3975 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3981void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
3988 emitToStreamer(Out, MCInstBuilder(Opcode)
3992 .addReg(MCRegister())
3994 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
4005 "The destination register should not be V0.");
4007 emitToStreamer(Out, MCInstBuilder(Opcode)
4013 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
4025 "The temporary vector register should not be V0.");
4026 emitToStreamer(Out, MCInstBuilder(Opcode)
4030 .addReg(MCRegister())
4032 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4044 "The temporary vector register should not be V0.");
4045 emitToStreamer(Out, MCInstBuilder(Opcode)
4049 .addReg(MCRegister())
4051 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4056 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4061 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
4069bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
4071 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
4074 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
4075 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
4076 "%tprel_add specifier");
4082bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
4084 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
4087 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
4088 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
4089 "%tlsdesc_call specifier");
4095std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
4096 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
4099std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
4100 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
4104std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
4105 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
4109std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultZeroOffset() {
4111 llvm::SMLoc(), llvm::SMLoc(), isRV64());
4118 case RISCV::VLOXSEG2EI8_V:
4119 case RISCV::VLOXSEG2EI16_V:
4120 case RISCV::VLOXSEG2EI32_V:
4121 case RISCV::VLOXSEG2EI64_V:
4122 case RISCV::VLUXSEG2EI8_V:
4123 case RISCV::VLUXSEG2EI16_V:
4124 case RISCV::VLUXSEG2EI32_V:
4125 case RISCV::VLUXSEG2EI64_V:
4127 case RISCV::VLOXSEG3EI8_V:
4128 case RISCV::VLOXSEG3EI16_V:
4129 case RISCV::VLOXSEG3EI32_V:
4130 case RISCV::VLOXSEG3EI64_V:
4131 case RISCV::VLUXSEG3EI8_V:
4132 case RISCV::VLUXSEG3EI16_V:
4133 case RISCV::VLUXSEG3EI32_V:
4134 case RISCV::VLUXSEG3EI64_V:
4136 case RISCV::VLOXSEG4EI8_V:
4137 case RISCV::VLOXSEG4EI16_V:
4138 case RISCV::VLOXSEG4EI32_V:
4139 case RISCV::VLOXSEG4EI64_V:
4140 case RISCV::VLUXSEG4EI8_V:
4141 case RISCV::VLUXSEG4EI16_V:
4142 case RISCV::VLUXSEG4EI32_V:
4143 case RISCV::VLUXSEG4EI64_V:
4145 case RISCV::VLOXSEG5EI8_V:
4146 case RISCV::VLOXSEG5EI16_V:
4147 case RISCV::VLOXSEG5EI32_V:
4148 case RISCV::VLOXSEG5EI64_V:
4149 case RISCV::VLUXSEG5EI8_V:
4150 case RISCV::VLUXSEG5EI16_V:
4151 case RISCV::VLUXSEG5EI32_V:
4152 case RISCV::VLUXSEG5EI64_V:
4154 case RISCV::VLOXSEG6EI8_V:
4155 case RISCV::VLOXSEG6EI16_V:
4156 case RISCV::VLOXSEG6EI32_V:
4157 case RISCV::VLOXSEG6EI64_V:
4158 case RISCV::VLUXSEG6EI8_V:
4159 case RISCV::VLUXSEG6EI16_V:
4160 case RISCV::VLUXSEG6EI32_V:
4161 case RISCV::VLUXSEG6EI64_V:
4163 case RISCV::VLOXSEG7EI8_V:
4164 case RISCV::VLOXSEG7EI16_V:
4165 case RISCV::VLOXSEG7EI32_V:
4166 case RISCV::VLOXSEG7EI64_V:
4167 case RISCV::VLUXSEG7EI8_V:
4168 case RISCV::VLUXSEG7EI16_V:
4169 case RISCV::VLUXSEG7EI32_V:
4170 case RISCV::VLUXSEG7EI64_V:
4172 case RISCV::VLOXSEG8EI8_V:
4173 case RISCV::VLOXSEG8EI16_V:
4174 case RISCV::VLOXSEG8EI32_V:
4175 case RISCV::VLOXSEG8EI64_V:
4176 case RISCV::VLUXSEG8EI8_V:
4177 case RISCV::VLUXSEG8EI16_V:
4178 case RISCV::VLUXSEG8EI32_V:
4179 case RISCV::VLUXSEG8EI64_V:
4185 if (getRISCVMCRegisterClass(RISCV::VRM2RegClassID).
contains(
Reg))
4187 if (getRISCVMCRegisterClass(RISCV::VRM4RegClassID).
contains(
Reg))
4189 if (getRISCVMCRegisterClass(RISCV::VRM8RegClassID).
contains(
Reg))
4196 case RISCV::VFWMMACC_VV_SCALE:
4197 case RISCV::VFQMMACC_VV_SCALE:
4198 case RISCV::VF8WMMACC_VV_SCALE:
4199 case RISCV::VFWIMMACC_VV:
4200 case RISCV::VFQIMMACC_VV:
4201 case RISCV::VF8WIMMACC_VV:
4208bool RISCVAsmParser::validateInstruction(MCInst &Inst,
4212 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
4213 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
4216 if (DestReg == TempReg) {
4217 SMLoc Loc =
Operands.back()->getStartLoc();
4218 return Error(Loc,
"the temporary vector register cannot be the same as "
4219 "the destination register");
4223 if (Opcode == RISCV::PseudoVMSGEU_VX_M || Opcode == RISCV::PseudoVMSGE_VX_M) {
4226 if (MaskReg == RISCV::V0 && DestReg == RISCV::V0) {
4227 SMLoc Loc =
Operands.back()->getStartLoc();
4228 return Error(Loc,
"the destination vector register cannot overlap the "
4229 "mask register unless a temporary register is "
4234 if (Opcode == RISCV::CV_INSERT &&
4237 "the sum of the immediate operands must be less than 32");
4242 case RISCV::TH_LBIA:
4243 case RISCV::TH_LBIB:
4244 case RISCV::TH_LBUIA:
4245 case RISCV::TH_LBUIB:
4246 case RISCV::TH_LHIA:
4247 case RISCV::TH_LHIB:
4248 case RISCV::TH_LHUIA:
4249 case RISCV::TH_LHUIB:
4250 case RISCV::TH_LWIA:
4251 case RISCV::TH_LWIB:
4252 case RISCV::TH_LWUIA:
4253 case RISCV::TH_LWUIB:
4254 case RISCV::TH_LDIA:
4255 case RISCV::TH_LDIB:
4257 return Error(
Operands[1]->getStartLoc(),
"rd and rs1 must be different");
4260 case RISCV::TH_LWUD:
4261 case RISCV::TH_LWD: {
4267 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
4268 SMLoc Loc =
Operands[1]->getStartLoc();
4269 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
4275 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
4279 SMLoc Loc =
Operands[1]->getStartLoc();
4280 return Error(Loc,
"rs1 and rs2 must be different");
4285 auto CheckOperandDoesNotOverlapV0 = [&](
int OperandIdx,
4286 unsigned ParsedIdx) {
4289 "vd, vs1, and vs2 cannot overlap v0.scale");
4294 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4296 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4298 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4299 assert(DestIdx >= 0 && VS1Idx >= 0 && VS2Idx >= 0 &&
4300 "Unexpected Zvvfmm scaled operand list");
4302 if (CheckOperandDoesNotOverlapV0(DestIdx, 1) ||
4303 CheckOperandDoesNotOverlapV0(VS1Idx, 2) ||
4304 CheckOperandDoesNotOverlapV0(VS2Idx, 3))
4308 const MCInstrDesc &MCID = MII.
get(Opcode);
4312 int DestIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4316 const MCParsedAsmOperand *ParsedOp =
Operands[1].get();
4317 if (!ParsedOp->
isReg()) {
4322 assert(ParsedOp->
getReg() == DestReg &&
"Can't find parsed dest operand");
4326 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4330 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4331 assert(VS2Idx >= 0 &&
"No vs2 operand?");
4332 unsigned CheckEncoding =
4335 for (
unsigned i = 0; i < std::max(NF, Lmul); i++) {
4336 if ((DestEncoding + i) == CheckEncoding)
4337 return Error(Loc,
"the destination vector register group cannot overlap"
4338 " the source vector register group");
4343 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4347 unsigned CheckEncoding =
4349 for (
unsigned i = 0; i < Lmul; i++) {
4350 if ((DestEncoding + i) == CheckEncoding)
4352 "the destination vector register group cannot overlap"
4353 " the source vector register group");
4359 int VMIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vm);
4360 assert(VMIdx >= 0 &&
"No vm operand?");
4362 if (DestReg == RISCV::V0) {
4365 return Error(Loc,
"the destination vector register group cannot be V0");
4373 "Unexpected mask operand register");
4375 return Error(Loc,
"the destination vector register group cannot overlap"
4376 " the mask register");
4384 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vmask);
4386 if (MaskReg != RISCV::V0 && MaskReg != RISCV::V1)
4388 "vmask operand only supports v0 or v1");
4391 RISCV::OpName RegOps[] = {RISCV::OpName::vd, RISCV::OpName::vs1,
4392 RISCV::OpName::vs2};
4393 for (RISCV::OpName OpN : RegOps) {
4394 int Idx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), OpN);
4400 for (
unsigned i = 0; i < RegLmul; i++) {
4401 if ((RegEnc + i) == MaskEnc) {
4404 Twine(
"register conflicts with vmask register ") +
4414bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
4422 case RISCV::MOP_RR_7: {
4434 case RISCV::MOP_R_28: {
4452 case RISCV::PseudoC_ADDI_NOP: {
4454 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
4464 if (getSTI().
hasFeature(RISCV::Feature64Bit))
4466 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV32)
4471 case RISCV::PACKW: {
4475 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV64)
4480 case RISCV::PseudoLLAImm:
4481 case RISCV::PseudoLAImm:
4482 case RISCV::PseudoLI: {
4488 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
4500 emitLoadImm(
Reg,
Imm, Out);
4503 case RISCV::PseudoLLA:
4504 emitLoadLocalAddress(Inst, IDLoc, Out);
4506 case RISCV::PseudoLGA:
4507 emitLoadGlobalAddress(Inst, IDLoc, Out);
4509 case RISCV::PseudoLA:
4510 emitLoadAddress(Inst, IDLoc, Out);
4512 case RISCV::PseudoLA_TLS_IE:
4513 emitLoadTLSIEAddress(Inst, IDLoc, Out);
4515 case RISCV::PseudoLA_TLS_GD:
4516 emitLoadTLSGDAddress(Inst, IDLoc, Out);
4518 case RISCV::PseudoLB:
4519 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
4521 case RISCV::PseudoLBU:
4522 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
4524 case RISCV::PseudoLH:
4525 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
4527 case RISCV::PseudoLHU:
4528 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
4530 case RISCV::PseudoLW:
4531 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
4533 case RISCV::PseudoLWU:
4534 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
4536 case RISCV::PseudoLD:
4537 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
4539 case RISCV::PseudoLD_RV32:
4540 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
4542 case RISCV::PseudoFLH:
4543 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
4545 case RISCV::PseudoFLW:
4546 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
4548 case RISCV::PseudoFLD:
4549 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
4551 case RISCV::PseudoFLQ:
4552 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
4554 case RISCV::PseudoSB:
4555 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
4557 case RISCV::PseudoSH:
4558 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
4560 case RISCV::PseudoSW:
4561 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
4563 case RISCV::PseudoSD:
4564 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
4566 case RISCV::PseudoSD_RV32:
4567 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
4569 case RISCV::PseudoQC_E_LB:
4570 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLB, IDLoc, Out,
4573 case RISCV::PseudoQC_E_LBU:
4574 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLBU, IDLoc, Out,
4577 case RISCV::PseudoQC_E_LH:
4578 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLH, IDLoc, Out,
4581 case RISCV::PseudoQC_E_LHU:
4582 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLHU, IDLoc, Out,
4585 case RISCV::PseudoQC_E_LW:
4586 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLW, IDLoc, Out,
4589 case RISCV::PseudoQC_E_SB:
4590 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSB, IDLoc, Out,
4593 case RISCV::PseudoQC_E_SH:
4594 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSH, IDLoc, Out,
4597 case RISCV::PseudoQC_E_SW:
4598 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSW, IDLoc, Out,
4601 case RISCV::PseudoFSH:
4602 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
4604 case RISCV::PseudoFSW:
4605 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
4607 case RISCV::PseudoFSD:
4608 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4610 case RISCV::PseudoFSQ:
4611 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4613 case RISCV::PseudoAddTPRel:
4614 if (checkPseudoAddTPRel(Inst,
Operands))
4617 case RISCV::PseudoTLSDESCCall:
4618 if (checkPseudoTLSDESCCall(Inst,
Operands))
4621 case RISCV::PseudoSEXT_B:
4622 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4624 case RISCV::PseudoSEXT_H:
4625 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4627 case RISCV::PseudoZEXT_H:
4628 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4630 case RISCV::PseudoZEXT_W:
4631 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4633 case RISCV::PseudoVMSGEU_VX_M:
4634 case RISCV::PseudoVMSGEU_VX_M_T:
4635 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4637 case RISCV::PseudoVMSGE_VX_M:
4638 case RISCV::PseudoVMSGE_VX_M_T:
4639 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4641 case RISCV::PseudoVMSGE_VI:
4642 case RISCV::PseudoVMSLT_VI: {
4646 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4648 emitToStreamer(Out, MCInstBuilder(
Opc)
4656 case RISCV::PseudoVMSGEU_VI:
4657 case RISCV::PseudoVMSLTU_VI: {
4664 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4667 emitToStreamer(Out, MCInstBuilder(
Opc)
4675 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4678 emitToStreamer(Out, MCInstBuilder(
Opc)
4688 case RISCV::PseudoCV_ELW:
4689 emitLoadStoreSymbol(Inst, RISCV::CV_ELW, IDLoc, Out,
false);
4693 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 MCTargetOptions & getTargetOptions() const
const AsmToken & getTok()
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
MCStreamer & getStreamer()
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
const MCObjectFileInfo * getObjectFileInfo() const
LLVM_ABI MCSymbol * createNamedTempSymbol()
Create a temporary symbol with a unique name whose name cannot be omitted in the symbol table.
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
ArrayRef< MCOperandInfo > operands() const
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
StringRef getName(unsigned Opcode) const
Returns the name for the instructions with the given opcode.
bool isPositionIndependent() const
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual MCRegister getReg() const =0
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const FeatureBitset & getFeatureBits() const
const FeatureBitset & ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
ArrayRef< SubtargetFeatureKV > getAllProcessorFeatures() const
Return processor features.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
const MCSymbol * getAddSym() const
uint32_t getSpecifier() const
const MCSymbol * getSubSym() const
Ternary parse status returned by various parse* methods.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
static LLVM_ABI bool isSupportedExtensionFeature(StringRef Ext)
static LLVM_ABI std::string getTargetFeatureForExtension(StringRef Ext)
static LLVM_ABI llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseArchString(StringRef Arch, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck=true)
Parse RISC-V ISA info from arch string.
static const char * getRegisterName(const RISCVMCOptions &CLOpts, MCRegister Reg)
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
reference emplace_back(ArgTypes &&... Args)
Represent a constant reference to a string, i.e.
std::string str() const
Get the contents as an std::string.
char back() const
Get the last character in the string.
A switch()-like statement whose cases are string literals.
StringSwitch & Cases(std::initializer_list< StringLiteral > CaseStrings, T Value)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const AArch64MCOptions & getCLOpts(const MCTargetOptions &Options)
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
uint16_t StackAdjustment(const RuntimeFunction &RF)
StackAdjustment - calculated stack adjustment in words.
LLVM_ABI std::optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)
MCExpr const & getExpr(MCExpr const &Expr)
Expected< ABI > computeTargetABI(const MCSubtargetInfo &STI, StringRef ABIName)
LLVM_ABI const TagNameMap & getRISCVAttributeTags()
static RoundingMode stringToRoundingMode(StringRef Str)
llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseFeatureBits(const MCSubtargetInfo &STI)
int getLoadFPImm(APFloat FPImm)
getLoadFPImm - Return a 5-bit binary encoding of the floating-point immediate value.
void generateMCInstSeq(int64_t Val, const MCSubtargetInfo &STI, MCRegister DestReg, SmallVectorImpl< MCInst > &Insts)
bool compress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI)
static VLMUL encodeLMUL(unsigned LMUL, bool Fractional)
LLVM_ABI unsigned encodeXSfmmVType(unsigned SEW, unsigned Widen, bool AltFmt)
static bool isValidLMUL(unsigned LMUL, bool Fractional)
static bool isValidSEW(unsigned SEW)
LLVM_ABI void printVType(unsigned VType, raw_ostream &OS)
static bool isValidXSfmmVType(unsigned VTypeI)
LLVM_ABI unsigned encodeVTYPE(VLMUL VLMUL, unsigned SEW, bool TailAgnostic, bool MaskAgnostic, bool AltFmt=false)
unsigned encodeRegList(MCRegister EndReg, bool IsRVE=false)
static unsigned getStackAdjBase(unsigned RlistVal, bool IsRV64)
void printRegList(unsigned RlistEncode, raw_ostream &OS)
const RISCVMCOptions & getCLOpts(const MCTargetOptions &Options)
Specifier parseSpecifierName(StringRef name)
void updateCZceFeatureImplications(MCSubtargetInfo &STI)
bool isValidYBNDSWImm(int64_t Imm)
@ CE
Windows NT (Windows on ARM)
static SMTVTypeMode stringToSMTVTypeMode(StringRef Str)
static bool isValidSMTVTypeMode(unsigned Mode)
@ Valid
The data is already valid.
std::function< llvm::json::Value()> Lambda
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
testing::Matcher< const detail::ErrorHolder & > Failed()
Target & getTheRISCV32Target()
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Target & getTheRISCV64beTarget()
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isDigit(char C)
Checks if character C is one of the 10 decimal digits.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
DWARFExpression::Operation Op
Target & getTheRISCV64Target()
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
Target & getTheRISCV32beTarget()
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...