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) {
3250 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
3253 clearFeatureBits(Feature.Value, Feature.key());
3260 raw_string_ostream OutputErrMsg(Buffer);
3261 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3262 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
3263 << ErrMsg.getMessage();
3266 return Error(Loc, OutputErrMsg.str());
3268 auto &ISAInfo = *ParseResult;
3271 if (ISAInfo->hasExtension(Feature.key()))
3272 setFeatureBits(Feature.Value, Feature.key());
3274 if (FromOptionDirective) {
3275 if (ISAInfo->getXLen() == 32 && isRV64())
3276 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3277 else if (ISAInfo->getXLen() == 64 && !isRV64())
3278 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3281 if (ISAInfo->getXLen() == 32)
3282 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
3283 else if (ISAInfo->getXLen() == 64)
3284 setFeatureBits(RISCV::Feature64Bit,
"64bit");
3286 return Error(Loc,
"bad arch string " + Arch);
3288 Result = ISAInfo->toString();
3292bool RISCVAsmParser::parseDirectiveOption() {
3293 MCAsmParser &Parser = getParser();
3295 AsmToken Tok = Parser.
getTok();
3303 if (Option ==
"push") {
3307 getTargetStreamer().emitDirectiveOptionPush();
3312 if (Option ==
"pop") {
3317 getTargetStreamer().emitDirectiveOptionPop();
3318 if (popFeatureBits())
3319 return Error(StartLoc,
".option pop with no .option push");
3324 if (Option ==
"arch") {
3332 Type = RISCVOptionArchArgType::Plus;
3334 Type = RISCVOptionArchArgType::Minus;
3335 else if (!
Args.empty())
3337 "unexpected token, expected + or -");
3339 Type = RISCVOptionArchArgType::Full;
3343 "unexpected token, expected identifier");
3349 if (
Type == RISCVOptionArchArgType::Full) {
3351 if (resetToArch(Arch, Loc, Result,
true))
3360 Loc,
"extension version number parsing not currently implemented");
3363 if (!enableExperimentalExtension() &&
3365 return Error(Loc,
"unexpected experimental extensions");
3366 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
3368 if (Ext == std::end(
AllFeatures) || StringRef(Ext->key()) != Feature)
3369 return Error(Loc,
"unknown extension feature");
3373 if (
Type == RISCVOptionArchArgType::Plus) {
3376 setFeatureBits(Ext->Value, Ext->key());
3379 copySTI().setFeatureBits(OldFeatureBits);
3380 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3383 raw_string_ostream OutputErrMsg(Buffer);
3384 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3385 OutputErrMsg << ErrMsg.getMessage();
3388 return Error(Loc, OutputErrMsg.str());
3391 assert(
Type == RISCVOptionArchArgType::Minus);
3397 Feature.Implies.test(Ext->Value))
3398 return Error(Loc, Twine(
"can't disable ") + Ext->key() +
3399 " extension; " + Feature.key() +
3400 " extension requires " + Ext->key() +
3404 clearFeatureBits(Ext->Value, Ext->key());
3411 getTargetStreamer().emitDirectiveOptionArch(Args);
3414 getTargetStreamer().setArchString((*ParseResult)->toString());
3418 if (Option ==
"exact") {
3422 getTargetStreamer().emitDirectiveOptionExact();
3423 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3424 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3428 if (Option ==
"noexact") {
3432 getTargetStreamer().emitDirectiveOptionNoExact();
3433 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3434 setFeatureBits(RISCV::FeatureRelax,
"relax");
3438 if (Option ==
"rvc") {
3442 getTargetStreamer().emitDirectiveOptionRVC();
3443 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3445 getTargetStreamer().setArchString((*ParseResult)->toString());
3449 if (Option ==
"norvc") {
3453 getTargetStreamer().emitDirectiveOptionNoRVC();
3454 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3455 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3457 getTargetStreamer().setArchString((*ParseResult)->toString());
3461 if (Option ==
"pic") {
3465 getTargetStreamer().emitDirectiveOptionPIC();
3466 ParserOptions.IsPicEnabled =
true;
3470 if (Option ==
"nopic") {
3474 getTargetStreamer().emitDirectiveOptionNoPIC();
3475 ParserOptions.IsPicEnabled =
false;
3479 if (Option ==
"relax") {
3483 getTargetStreamer().emitDirectiveOptionRelax();
3484 setFeatureBits(RISCV::FeatureRelax,
"relax");
3488 if (Option ==
"norelax") {
3492 getTargetStreamer().emitDirectiveOptionNoRelax();
3493 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3499 "unknown option, expected 'push', 'pop', "
3500 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3501 "'exact', or 'noexact'");
3509bool RISCVAsmParser::parseDirectiveAttribute() {
3510 MCAsmParser &Parser = getParser();
3516 std::optional<unsigned> Ret =
3519 return Error(TagLoc,
"attribute name not recognised: " + Name);
3523 const MCExpr *AttrExpr;
3530 if (check(!CE, TagLoc,
"expected numeric constant"))
3533 Tag =
CE->getValue();
3539 StringRef StringValue;
3540 int64_t IntegerValue = 0;
3541 bool IsIntegerValue =
true;
3546 IsIntegerValue =
false;
3549 if (IsIntegerValue) {
3550 const MCExpr *ValueExpr;
3556 return Error(ValueExprLoc,
"expected numeric constant");
3557 IntegerValue =
CE->getValue();
3570 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3572 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3575 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3579 getTargetStreamer().emitTextAttribute(
Tag, Result);
3583 getTargetStreamer().setArchString(Result);
3591 .
Cases({
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s"},
true)
3592 .Cases({
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj"},
3594 .
Cases({
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es"},
3603bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3604 MCAsmParser &Parser = getParser();
3611 std::optional<int64_t>
Length;
3621 return Error(ErrorLoc,
3622 "instruction lengths must be a non-zero multiple of two");
3626 return Error(ErrorLoc,
3627 "instruction lengths over 64 bits are not supported");
3633 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3638 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3639 return Error(ErrorLoc,
3640 "instruction length does not match the encoding");
3643 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3646 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3649 if (!getSTI().
hasFeature(RISCV::FeatureStdExtZca) &&
3650 (EncodingDerivedLength == 2))
3651 return Error(ErrorLoc,
"compressed instructions are not allowed");
3653 if (getParser().parseEOL(
"invalid operand for instruction")) {
3654 getParser().eatToEndOfStatement();
3662 Opcode = RISCV::Insn16;
3665 Opcode = RISCV::Insn32;
3668 Opcode = RISCV::Insn48;
3671 Opcode = RISCV::Insn64;
3677 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3679 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3684 return Error(ErrorLoc,
"invalid instruction format");
3686 std::string FormatName = (
".insn_" +
Format).str();
3688 ParseInstructionInfo
Info;
3691 if (parseInstruction(Info, FormatName, L,
Operands))
3703bool RISCVAsmParser::parseDirectiveVariantCC() {
3705 if (getParser().parseIdentifier(Name))
3706 return TokError(
"expected symbol name");
3709 getTargetStreamer().emitDirectiveVariantCC(
3714void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3717 const MCSubtargetInfo &STI = getSTI();
3718 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3721 ++RISCVNumInstrsCompressed;
3725void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3730 for (MCInst &Inst : Seq) {
3731 emitToStreamer(Out, Inst);
3735void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3736 const MCExpr *Symbol,
3738 unsigned SecondOpcode, SMLoc IDLoc,
3746 Out.emitLabel(TmpLabel);
3750 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3755 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3758 .addExpr(RefToLinkTmpLabel));
3761void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3772 STI->
hasFeature(RISCV::FeatureVendorXqcili) &&
3773 !ParserOptions.IsPicEnabled)
3775 Out, MCInstBuilder(RISCV::QC_E_LI).addReg(DestReg).addExpr(Symbol));
3781void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3791 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3792 emitAuipcInstPair(DestReg, DestReg, Symbol,
RISCV::S_GOT_HI, SecondOpcode,
3796void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3805 if (ParserOptions.IsPicEnabled)
3806 emitLoadGlobalAddress(Inst, IDLoc, Out);
3808 emitLoadLocalAddress(Inst, IDLoc, Out);
3811void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3821 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3822 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3823 SecondOpcode, IDLoc, Out);
3826void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3836 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3837 RISCV::ADDI, IDLoc, Out);
3840void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3841 SMLoc IDLoc, MCStreamer &Out,
3850 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3852 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3856 if (getRISCVMCRegisterClass(RISCV::GPRPairRegClassID).
contains(TmpReg)) {
3857 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3858 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3866void RISCVAsmParser::emitQCELILoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3867 SMLoc IDLoc, MCStreamer &Out,
3877 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3881 MCInstBuilder(RISCV::QC_E_LI).addReg(AddrReg).addExpr(Symbol));
3884 const MCExpr *AccessExpr =
3890 struct CompressedForm {
3894 std::optional<CompressedForm> Compressed;
3898 case RISCV::PseudoQCAccessLBU:
3899 Compressed = {RISCV::PseudoQCAccessC_LBU, RISCV::FeatureStdExtZcb};
3901 case RISCV::PseudoQCAccessLH:
3902 Compressed = {RISCV::PseudoQCAccessC_LH, RISCV::FeatureStdExtZcb};
3904 case RISCV::PseudoQCAccessLHU:
3905 Compressed = {RISCV::PseudoQCAccessC_LHU, RISCV::FeatureStdExtZcb};
3907 case RISCV::PseudoQCAccessLW:
3908 Compressed = {RISCV::PseudoQCAccessC_LW, RISCV::FeatureStdExtZca};
3910 case RISCV::PseudoQCAccessSB:
3911 Compressed = {RISCV::PseudoQCAccessC_SB, RISCV::FeatureStdExtZcb};
3913 case RISCV::PseudoQCAccessSH:
3914 Compressed = {RISCV::PseudoQCAccessC_SH, RISCV::FeatureStdExtZcb};
3916 case RISCV::PseudoQCAccessSW:
3917 Compressed = {RISCV::PseudoQCAccessC_SW, RISCV::FeatureStdExtZca};
3924 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(AddrReg);
3925 if (HasTmpReg && CanUseGPRC) {
3928 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(DataReg);
3931 bool UseCompressed =
3932 Compressed && getSTI().hasFeature(Compressed->Feature) && CanUseGPRC;
3934 unsigned ActualOpcode = UseCompressed ? Compressed->Opcode : Opcode;
3937 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3941 .addExpr(AccessExpr));
3943 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3947 .addExpr(AccessExpr));
3951void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3952 int64_t Width, SMLoc IDLoc,
3961 const MCOperand &DestReg = Inst.
getOperand(0);
3962 const MCOperand &SourceReg = Inst.
getOperand(1);
3964 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3965 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3967 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3969 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3974 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3980void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
3987 emitToStreamer(Out, MCInstBuilder(Opcode)
3991 .addReg(MCRegister())
3993 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
4004 "The destination register should not be V0.");
4006 emitToStreamer(Out, MCInstBuilder(Opcode)
4012 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
4024 "The temporary vector register should not be V0.");
4025 emitToStreamer(Out, MCInstBuilder(Opcode)
4029 .addReg(MCRegister())
4031 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4043 "The temporary vector register should not be V0.");
4044 emitToStreamer(Out, MCInstBuilder(Opcode)
4048 .addReg(MCRegister())
4050 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4055 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4060 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
4068bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
4070 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
4073 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
4074 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
4075 "%tprel_add specifier");
4081bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
4083 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
4086 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
4087 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
4088 "%tlsdesc_call specifier");
4094std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
4095 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
4098std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
4099 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
4103std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
4104 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
4108std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultZeroOffset() {
4110 llvm::SMLoc(), llvm::SMLoc(), isRV64());
4117 case RISCV::VLOXSEG2EI8_V:
4118 case RISCV::VLOXSEG2EI16_V:
4119 case RISCV::VLOXSEG2EI32_V:
4120 case RISCV::VLOXSEG2EI64_V:
4121 case RISCV::VLUXSEG2EI8_V:
4122 case RISCV::VLUXSEG2EI16_V:
4123 case RISCV::VLUXSEG2EI32_V:
4124 case RISCV::VLUXSEG2EI64_V:
4126 case RISCV::VLOXSEG3EI8_V:
4127 case RISCV::VLOXSEG3EI16_V:
4128 case RISCV::VLOXSEG3EI32_V:
4129 case RISCV::VLOXSEG3EI64_V:
4130 case RISCV::VLUXSEG3EI8_V:
4131 case RISCV::VLUXSEG3EI16_V:
4132 case RISCV::VLUXSEG3EI32_V:
4133 case RISCV::VLUXSEG3EI64_V:
4135 case RISCV::VLOXSEG4EI8_V:
4136 case RISCV::VLOXSEG4EI16_V:
4137 case RISCV::VLOXSEG4EI32_V:
4138 case RISCV::VLOXSEG4EI64_V:
4139 case RISCV::VLUXSEG4EI8_V:
4140 case RISCV::VLUXSEG4EI16_V:
4141 case RISCV::VLUXSEG4EI32_V:
4142 case RISCV::VLUXSEG4EI64_V:
4144 case RISCV::VLOXSEG5EI8_V:
4145 case RISCV::VLOXSEG5EI16_V:
4146 case RISCV::VLOXSEG5EI32_V:
4147 case RISCV::VLOXSEG5EI64_V:
4148 case RISCV::VLUXSEG5EI8_V:
4149 case RISCV::VLUXSEG5EI16_V:
4150 case RISCV::VLUXSEG5EI32_V:
4151 case RISCV::VLUXSEG5EI64_V:
4153 case RISCV::VLOXSEG6EI8_V:
4154 case RISCV::VLOXSEG6EI16_V:
4155 case RISCV::VLOXSEG6EI32_V:
4156 case RISCV::VLOXSEG6EI64_V:
4157 case RISCV::VLUXSEG6EI8_V:
4158 case RISCV::VLUXSEG6EI16_V:
4159 case RISCV::VLUXSEG6EI32_V:
4160 case RISCV::VLUXSEG6EI64_V:
4162 case RISCV::VLOXSEG7EI8_V:
4163 case RISCV::VLOXSEG7EI16_V:
4164 case RISCV::VLOXSEG7EI32_V:
4165 case RISCV::VLOXSEG7EI64_V:
4166 case RISCV::VLUXSEG7EI8_V:
4167 case RISCV::VLUXSEG7EI16_V:
4168 case RISCV::VLUXSEG7EI32_V:
4169 case RISCV::VLUXSEG7EI64_V:
4171 case RISCV::VLOXSEG8EI8_V:
4172 case RISCV::VLOXSEG8EI16_V:
4173 case RISCV::VLOXSEG8EI32_V:
4174 case RISCV::VLOXSEG8EI64_V:
4175 case RISCV::VLUXSEG8EI8_V:
4176 case RISCV::VLUXSEG8EI16_V:
4177 case RISCV::VLUXSEG8EI32_V:
4178 case RISCV::VLUXSEG8EI64_V:
4184 if (getRISCVMCRegisterClass(RISCV::VRM2RegClassID).
contains(
Reg))
4186 if (getRISCVMCRegisterClass(RISCV::VRM4RegClassID).
contains(
Reg))
4188 if (getRISCVMCRegisterClass(RISCV::VRM8RegClassID).
contains(
Reg))
4195 case RISCV::VFWMMACC_VV_SCALE:
4196 case RISCV::VFQMMACC_VV_SCALE:
4197 case RISCV::VF8WMMACC_VV_SCALE:
4198 case RISCV::VFWIMMACC_VV:
4199 case RISCV::VFQIMMACC_VV:
4200 case RISCV::VF8WIMMACC_VV:
4207bool RISCVAsmParser::validateInstruction(MCInst &Inst,
4211 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
4212 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
4215 if (DestReg == TempReg) {
4216 SMLoc Loc =
Operands.back()->getStartLoc();
4217 return Error(Loc,
"the temporary vector register cannot be the same as "
4218 "the destination register");
4222 if (Opcode == RISCV::PseudoVMSGEU_VX_M || Opcode == RISCV::PseudoVMSGE_VX_M) {
4225 if (MaskReg == RISCV::V0 && DestReg == RISCV::V0) {
4226 SMLoc Loc =
Operands.back()->getStartLoc();
4227 return Error(Loc,
"the destination vector register cannot overlap the "
4228 "mask register unless a temporary register is "
4233 if (Opcode == RISCV::CV_INSERT &&
4236 "the sum of the immediate operands must be less than 32");
4241 case RISCV::TH_LBIA:
4242 case RISCV::TH_LBIB:
4243 case RISCV::TH_LBUIA:
4244 case RISCV::TH_LBUIB:
4245 case RISCV::TH_LHIA:
4246 case RISCV::TH_LHIB:
4247 case RISCV::TH_LHUIA:
4248 case RISCV::TH_LHUIB:
4249 case RISCV::TH_LWIA:
4250 case RISCV::TH_LWIB:
4251 case RISCV::TH_LWUIA:
4252 case RISCV::TH_LWUIB:
4253 case RISCV::TH_LDIA:
4254 case RISCV::TH_LDIB:
4256 return Error(
Operands[1]->getStartLoc(),
"rd and rs1 must be different");
4259 case RISCV::TH_LWUD:
4260 case RISCV::TH_LWD: {
4266 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
4267 SMLoc Loc =
Operands[1]->getStartLoc();
4268 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
4274 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
4278 SMLoc Loc =
Operands[1]->getStartLoc();
4279 return Error(Loc,
"rs1 and rs2 must be different");
4284 auto CheckOperandDoesNotOverlapV0 = [&](
int OperandIdx,
4285 unsigned ParsedIdx) {
4288 "vd, vs1, and vs2 cannot overlap v0.scale");
4293 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4295 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4297 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4298 assert(DestIdx >= 0 && VS1Idx >= 0 && VS2Idx >= 0 &&
4299 "Unexpected Zvvfmm scaled operand list");
4301 if (CheckOperandDoesNotOverlapV0(DestIdx, 1) ||
4302 CheckOperandDoesNotOverlapV0(VS1Idx, 2) ||
4303 CheckOperandDoesNotOverlapV0(VS2Idx, 3))
4307 const MCInstrDesc &MCID = MII.
get(Opcode);
4311 int DestIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4315 const MCParsedAsmOperand *ParsedOp =
Operands[1].get();
4316 if (!ParsedOp->
isReg()) {
4321 assert(ParsedOp->
getReg() == DestReg &&
"Can't find parsed dest operand");
4325 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4329 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4330 assert(VS2Idx >= 0 &&
"No vs2 operand?");
4331 unsigned CheckEncoding =
4334 for (
unsigned i = 0; i < std::max(NF, Lmul); i++) {
4335 if ((DestEncoding + i) == CheckEncoding)
4336 return Error(Loc,
"the destination vector register group cannot overlap"
4337 " the source vector register group");
4342 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4346 unsigned CheckEncoding =
4348 for (
unsigned i = 0; i < Lmul; i++) {
4349 if ((DestEncoding + i) == CheckEncoding)
4351 "the destination vector register group cannot overlap"
4352 " the source vector register group");
4358 int VMIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vm);
4359 assert(VMIdx >= 0 &&
"No vm operand?");
4361 if (DestReg == RISCV::V0) {
4364 return Error(Loc,
"the destination vector register group cannot be V0");
4372 "Unexpected mask operand register");
4374 return Error(Loc,
"the destination vector register group cannot overlap"
4375 " the mask register");
4383 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vmask);
4385 if (MaskReg != RISCV::V0 && MaskReg != RISCV::V1)
4387 "vmask operand only supports v0 or v1");
4390 RISCV::OpName RegOps[] = {RISCV::OpName::vd, RISCV::OpName::vs1,
4391 RISCV::OpName::vs2};
4392 for (RISCV::OpName OpN : RegOps) {
4393 int Idx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), OpN);
4399 for (
unsigned i = 0; i < RegLmul; i++) {
4400 if ((RegEnc + i) == MaskEnc) {
4403 Twine(
"register conflicts with vmask register ") +
4413bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
4421 case RISCV::MOP_RR_7: {
4433 case RISCV::MOP_R_28: {
4451 case RISCV::PseudoC_ADDI_NOP: {
4453 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
4463 if (getSTI().
hasFeature(RISCV::Feature64Bit))
4465 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV32)
4470 case RISCV::PACKW: {
4474 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV64)
4479 case RISCV::PseudoLLAImm:
4480 case RISCV::PseudoLAImm:
4481 case RISCV::PseudoLI: {
4487 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
4499 emitLoadImm(
Reg,
Imm, Out);
4502 case RISCV::PseudoLLA:
4503 emitLoadLocalAddress(Inst, IDLoc, Out);
4505 case RISCV::PseudoLGA:
4506 emitLoadGlobalAddress(Inst, IDLoc, Out);
4508 case RISCV::PseudoLA:
4509 emitLoadAddress(Inst, IDLoc, Out);
4511 case RISCV::PseudoLA_TLS_IE:
4512 emitLoadTLSIEAddress(Inst, IDLoc, Out);
4514 case RISCV::PseudoLA_TLS_GD:
4515 emitLoadTLSGDAddress(Inst, IDLoc, Out);
4517 case RISCV::PseudoLB:
4518 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
4520 case RISCV::PseudoLBU:
4521 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
4523 case RISCV::PseudoLH:
4524 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
4526 case RISCV::PseudoLHU:
4527 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
4529 case RISCV::PseudoLW:
4530 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
4532 case RISCV::PseudoLWU:
4533 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
4535 case RISCV::PseudoLD:
4536 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
4538 case RISCV::PseudoLD_RV32:
4539 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
4541 case RISCV::PseudoFLH:
4542 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
4544 case RISCV::PseudoFLW:
4545 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
4547 case RISCV::PseudoFLD:
4548 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
4550 case RISCV::PseudoFLQ:
4551 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
4553 case RISCV::PseudoSB:
4554 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
4556 case RISCV::PseudoSH:
4557 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
4559 case RISCV::PseudoSW:
4560 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
4562 case RISCV::PseudoSD:
4563 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
4565 case RISCV::PseudoSD_RV32:
4566 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
4568 case RISCV::PseudoQC_E_LB:
4569 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLB, IDLoc, Out,
4572 case RISCV::PseudoQC_E_LBU:
4573 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLBU, IDLoc, Out,
4576 case RISCV::PseudoQC_E_LH:
4577 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLH, IDLoc, Out,
4580 case RISCV::PseudoQC_E_LHU:
4581 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLHU, IDLoc, Out,
4584 case RISCV::PseudoQC_E_LW:
4585 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLW, IDLoc, Out,
4588 case RISCV::PseudoQC_E_SB:
4589 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSB, IDLoc, Out,
4592 case RISCV::PseudoQC_E_SH:
4593 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSH, IDLoc, Out,
4596 case RISCV::PseudoQC_E_SW:
4597 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSW, IDLoc, Out,
4600 case RISCV::PseudoFSH:
4601 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
4603 case RISCV::PseudoFSW:
4604 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
4606 case RISCV::PseudoFSD:
4607 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4609 case RISCV::PseudoFSQ:
4610 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4612 case RISCV::PseudoAddTPRel:
4613 if (checkPseudoAddTPRel(Inst,
Operands))
4616 case RISCV::PseudoTLSDESCCall:
4617 if (checkPseudoTLSDESCCall(Inst,
Operands))
4620 case RISCV::PseudoSEXT_B:
4621 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4623 case RISCV::PseudoSEXT_H:
4624 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4626 case RISCV::PseudoZEXT_H:
4627 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4629 case RISCV::PseudoZEXT_W:
4630 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4632 case RISCV::PseudoVMSGEU_VX_M:
4633 case RISCV::PseudoVMSGEU_VX_M_T:
4634 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4636 case RISCV::PseudoVMSGE_VX_M:
4637 case RISCV::PseudoVMSGE_VX_M_T:
4638 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4640 case RISCV::PseudoVMSGE_VI:
4641 case RISCV::PseudoVMSLT_VI: {
4645 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4647 emitToStreamer(Out, MCInstBuilder(
Opc)
4655 case RISCV::PseudoVMSGEU_VI:
4656 case RISCV::PseudoVMSLTU_VI: {
4663 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4666 emitToStreamer(Out, MCInstBuilder(
Opc)
4674 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4677 emitToStreamer(Out, MCInstBuilder(
Opc)
4687 case RISCV::PseudoCV_ELW:
4688 emitLoadStoreSymbol(Inst, RISCV::CV_ELW, IDLoc, Out,
false);
4692 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.
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.
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)
const MipsMCOptions & getCLOpts(const MCTargetOptions &Options)
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,...