48#define DEBUG_TYPE "riscv-asm-parser"
51 "Number of RISC-V Compressed instructions emitted");
63struct ParserOptionsSet {
75 VTypeState_TailPolicy,
76 VTypeState_MaskPolicy,
83 ParserOptionsSet ParserOptions;
88 bool enableExperimentalExtension()
const {
94 "do not have a target streamer");
100 unsigned Kind)
override;
105 bool generateImmOutOfRangeError(
SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
111 bool MatchingInlineAsm)
override;
116 SMLoc &EndLoc)
override;
123 bool parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
unsigned &Sew,
124 unsigned &Lmul,
bool &Fractional,
bool &TailAgnostic,
126 bool generateVTypeError(
SMLoc ErrorLoc);
160 void emitLoadStoreSymbol(
MCInst &Inst,
unsigned Opcode,
SMLoc IDLoc,
164 void emitPseudoExtend(
MCInst &Inst,
bool SignExtend, int64_t Width,
193#define GET_ASSEMBLER_HEADER
194#include "RISCVGenAsmMatcher.inc"
222 bool ExpectNegative =
false);
224 return parseZcmpStackAdj(
Operands,
true);
229 bool parseDirectiveOption();
230 bool parseDirectiveAttribute();
231 bool parseDirectiveInsn(
SMLoc L);
232 bool parseDirectiveVariantCC();
238 bool FromOptionDirective);
241 if (!(
getSTI().hasFeature(Feature))) {
249 if (
getSTI().hasFeature(Feature)) {
256 void pushFeatureBits() {
258 "These two stacks must be kept synchronized");
260 ParserOptionsStack.
push_back(ParserOptions);
263 bool popFeatureBits() {
265 "These two stacks must be kept synchronized");
266 if (FeatureBitStack.
empty())
278 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
279 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
280 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
283 enum RISCVMatchResultTy :
unsigned {
285#define GET_OPERAND_DIAGNOSTIC_TYPES
286#include "RISCVGenAsmMatcher.inc"
287#undef GET_OPERAND_DIAGNOSTIC_TYPES
290 static bool classifySymbolRef(
const MCExpr *Expr,
292 static bool isSymbolDiff(
const MCExpr *Expr);
306 if (ABIName.ends_with(
"f") && !getSTI().hasFeature(RISCV::FeatureStdExtF)) {
307 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
308 "doesn't support the F instruction set extension (ignoring "
310 }
else if (ABIName.ends_with(
"d") &&
311 !getSTI().hasFeature(RISCV::FeatureStdExtD)) {
312 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
313 "doesn't support the D instruction set extension (ignoring "
326 getTargetStreamer().emitTargetAttributes(STI,
false);
395 SMLoc StartLoc, EndLoc;
401 struct SysRegOp SysReg;
402 struct VTypeOp VType;
404 struct FenceOp Fence;
405 struct RlistOp Rlist;
406 struct SpimmOp Spimm;
410 RISCVOperand(KindTy K) :
Kind(
K) {}
415 StartLoc =
o.StartLoc;
418 case KindTy::Register:
421 case KindTy::Immediate:
424 case KindTy::FPImmediate:
430 case KindTy::SystemRegister:
454 bool isToken()
const override {
return Kind == KindTy::Token; }
455 bool isReg()
const override {
return Kind == KindTy::Register; }
456 bool isV0Reg()
const {
457 return Kind == KindTy::Register &&
Reg.RegNum == RISCV::V0;
459 bool isAnyReg()
const {
460 return Kind == KindTy::Register &&
461 (RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.RegNum) ||
462 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg.RegNum) ||
463 RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg.RegNum));
465 bool isAnyRegC()
const {
466 return Kind == KindTy::Register &&
467 (RISCVMCRegisterClasses[RISCV::GPRCRegClassID].contains(
469 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
472 bool isImm()
const override {
return Kind == KindTy::Immediate; }
473 bool isMem()
const override {
return false; }
474 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
475 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
476 bool isRlist()
const {
return Kind == KindTy::Rlist; }
477 bool isSpimm()
const {
return Kind == KindTy::Spimm; }
480 return Kind == KindTy::Register &&
481 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.RegNum);
484 bool isGPRPair()
const {
485 return Kind == KindTy::Register &&
486 RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(
490 bool isGPRF16()
const {
491 return Kind == KindTy::Register &&
492 RISCVMCRegisterClasses[RISCV::GPRF16RegClassID].contains(
Reg.RegNum);
495 bool isGPRF32()
const {
496 return Kind == KindTy::Register &&
497 RISCVMCRegisterClasses[RISCV::GPRF32RegClassID].contains(
Reg.RegNum);
500 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
501 bool isGPRAsFPR16()
const {
return isGPRF16() &&
Reg.IsGPRAsFPR; }
502 bool isGPRAsFPR32()
const {
return isGPRF32() &&
Reg.IsGPRAsFPR; }
503 bool isGPRPairAsFPR64()
const {
return isGPRPair() &&
Reg.IsGPRAsFPR; }
505 static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &Imm,
507 if (
auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
509 return RE->evaluateAsConstant(Imm);
512 if (
auto CE = dyn_cast<MCConstantExpr>(Expr)) {
514 Imm =
CE->getValue();
523 template <
int N>
bool isBareSimmNLsb0()
const {
528 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
531 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
533 IsValid =
isShiftedInt<
N - 1, 1>(fixImmediateForRV32(Imm, isRV64Imm()));
539 bool isBareSymbol()
const {
543 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
545 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
549 bool isCallSymbol()
const {
553 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
555 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
560 bool isPseudoJumpSymbol()
const {
564 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
566 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
570 bool isTPRelAddSymbol()
const {
574 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
576 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
580 bool isTLSDESCCallSymbol()
const {
584 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
586 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
590 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
592 bool isVTypeImm(
unsigned N)
const {
597 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
603 bool isVTypeI10()
const {
604 if (Kind == KindTy::Immediate)
605 return isVTypeImm(10);
606 return Kind == KindTy::VType;
608 bool isVTypeI11()
const {
609 if (Kind == KindTy::Immediate)
610 return isVTypeImm(11);
611 return Kind == KindTy::VType;
616 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
619 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
620 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
624 bool isLoadFPImm()
const {
627 if (Kind != KindTy::FPImmediate)
630 APFloat(APFloat::IEEEdouble(),
APInt(64, getFPConst())));
633 return Idx >= 0 &&
Idx != 1;
636 bool isImmXLenLI()
const {
641 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
651 (isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm)));
654 return RISCVAsmParser::isSymbolDiff(getImm());
657 bool isImmXLenLI_Restricted()
const {
662 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
665 (isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm)));
668 bool isUImmLog2XLen()
const {
673 if (!evaluateConstantImm(getImm(), Imm, VK) ||
676 return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm);
679 bool isUImmLog2XLenNonZero()
const {
684 if (!evaluateConstantImm(getImm(), Imm, VK) ||
689 return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm);
692 bool isUImmLog2XLenHalf()
const {
697 if (!evaluateConstantImm(getImm(), Imm, VK) ||
700 return (isRV64Imm() && isUInt<5>(Imm)) || isUInt<4>(Imm);
703 template <
unsigned N>
bool IsUImm()
const {
708 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
712 bool isUImm1()
const {
return IsUImm<1>(); }
713 bool isUImm2()
const {
return IsUImm<2>(); }
714 bool isUImm3()
const {
return IsUImm<3>(); }
715 bool isUImm4()
const {
return IsUImm<4>(); }
716 bool isUImm5()
const {
return IsUImm<5>(); }
717 bool isUImm6()
const {
return IsUImm<6>(); }
718 bool isUImm7()
const {
return IsUImm<7>(); }
719 bool isUImm8()
const {
return IsUImm<8>(); }
720 bool isUImm10()
const {
return IsUImm<10>(); }
721 bool isUImm11()
const {
return IsUImm<11>(); }
722 bool isUImm16()
const {
return IsUImm<16>(); }
723 bool isUImm20()
const {
return IsUImm<20>(); }
724 bool isUImm32()
const {
return IsUImm<32>(); }
725 bool isUImm48()
const {
return IsUImm<48>(); }
726 bool isUImm64()
const {
return IsUImm<64>(); }
728 bool isUImm5NonZero()
const {
733 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
734 return IsConstantImm && isUInt<5>(Imm) && (
Imm != 0) &&
738 bool isUImm5GT3()
const {
743 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
744 return IsConstantImm && isUInt<5>(Imm) && (
Imm > 3) &&
748 bool isUImm8GE32()
const {
753 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
754 return IsConstantImm && isUInt<8>(Imm) &&
Imm >= 32 &&
758 bool isRnumArg()
const {
763 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
764 return IsConstantImm &&
Imm >= INT64_C(0) &&
Imm <= INT64_C(10) &&
768 bool isRnumArg_0_7()
const {
773 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
774 return IsConstantImm &&
Imm >= INT64_C(0) &&
Imm <= INT64_C(7) &&
778 bool isRnumArg_1_10()
const {
783 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
784 return IsConstantImm &&
Imm >= INT64_C(1) &&
Imm <= INT64_C(10) &&
788 bool isRnumArg_2_14()
const {
793 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
794 return IsConstantImm &&
Imm >= INT64_C(2) &&
Imm <= INT64_C(14) &&
798 bool isSImm5()
const {
803 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
804 return IsConstantImm && isInt<5>(fixImmediateForRV32(Imm, isRV64Imm())) &&
808 bool isSImm6()
const {
813 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
814 return IsConstantImm && isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) &&
818 bool isSImm6NonZero()
const {
823 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
824 return IsConstantImm &&
Imm != 0 &&
825 isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) &&
829 bool isCLUIImm()
const {
834 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
835 return IsConstantImm && (
Imm != 0) &&
836 (isUInt<5>(Imm) || (
Imm >= 0xfffe0 &&
Imm <= 0xfffff)) &&
840 bool isUImm2Lsb0()
const {
845 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
846 return IsConstantImm && isShiftedUInt<1, 1>(Imm) &&
850 bool isUImm5Lsb0()
const {
855 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
856 return IsConstantImm && isShiftedUInt<4, 1>(Imm) &&
860 bool isUImm6Lsb0()
const {
865 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
866 return IsConstantImm && isShiftedUInt<5, 1>(Imm) &&
870 bool isUImm7Lsb00()
const {
875 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
876 return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
880 bool isUImm7Lsb000()
const {
885 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
886 return IsConstantImm && isShiftedUInt<4, 3>(Imm) &&
890 bool isUImm8Lsb00()
const {
895 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
896 return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
900 bool isUImm8Lsb000()
const {
905 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
906 return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
910 bool isSImm9Lsb0()
const {
return isBareSimmNLsb0<9>(); }
912 bool isUImm9Lsb000()
const {
917 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
918 return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
922 bool isUImm10Lsb00NonZero()
const {
927 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
928 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (
Imm != 0) &&
934 static int64_t fixImmediateForRV32(int64_t Imm,
bool IsRV64Imm) {
935 if (IsRV64Imm || !isUInt<32>(Imm))
937 return SignExtend64<32>(Imm);
940 bool isSImm12()
const {
946 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
948 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
950 IsValid = isInt<12>(fixImmediateForRV32(Imm, isRV64Imm()));
959 bool isSImm12Lsb0()
const {
return isBareSimmNLsb0<12>(); }
961 bool isSImm12Lsb00000()
const {
966 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
967 return IsConstantImm &&
968 isShiftedInt<7, 5>(fixImmediateForRV32(Imm, isRV64Imm())) &&
972 bool isSImm13Lsb0()
const {
return isBareSimmNLsb0<13>(); }
974 bool isSImm10Lsb0000NonZero()
const {
979 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
980 return IsConstantImm && (
Imm != 0) &&
981 isShiftedInt<6, 4>(fixImmediateForRV32(Imm, isRV64Imm())) &&
985 bool isUImm20LUI()
const {
991 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
992 if (!IsConstantImm) {
993 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
1003 bool isUImm20AUIPC()
const {
1009 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
1010 if (!IsConstantImm) {
1011 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
1027 bool isSImm21Lsb0JAL()
const {
return isBareSimmNLsb0<21>(); }
1029 bool isImmZero()
const {
1034 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
1038 bool isSImm5Plus1()
const {
1043 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
1044 return IsConstantImm &&
1045 isInt<5>(fixImmediateForRV32(Imm, isRV64Imm()) - 1) &&
1049 bool isSImm26()
const {
1054 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
1056 isInt<26>(fixImmediateForRV32(Imm, isRV64Imm()));
1060 SMLoc getStartLoc()
const override {
return StartLoc; }
1062 SMLoc getEndLoc()
const override {
return EndLoc; }
1064 bool isRV64Imm()
const {
1065 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
1070 assert(Kind == KindTy::Register &&
"Invalid type access!");
1075 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
1076 return StringRef(SysReg.Data, SysReg.Length);
1079 const MCExpr *getImm()
const {
1080 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
1085 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1090 assert(Kind == KindTy::Token &&
"Invalid type access!");
1094 unsigned getVType()
const {
1095 assert(Kind == KindTy::VType &&
"Invalid type access!");
1100 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1104 unsigned getFence()
const {
1105 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1118 case KindTy::Immediate:
1119 OS <<
"<imm: " << *
Imm.Val <<
" " << (
Imm.IsRV64 ?
"rv64" :
"rv32")
1122 case KindTy::FPImmediate:
1123 OS <<
"<fpimm: " << FPImm.Val <<
">";
1125 case KindTy::Register:
1127 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1130 OS <<
"'" << getToken() <<
"'";
1132 case KindTy::SystemRegister:
1133 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1142 roundingModeToString(getFRM());
1160 case KindTy::RegReg:
1167 static std::unique_ptr<RISCVOperand> createToken(
StringRef Str,
SMLoc S) {
1168 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1175 static std::unique_ptr<RISCVOperand>
1177 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1178 Op->Reg.RegNum =
Reg.id();
1179 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1185 static std::unique_ptr<RISCVOperand> createImm(
const MCExpr *Val,
SMLoc S,
1187 auto Op = std::make_unique<RISCVOperand>(KindTy::Immediate);
1189 Op->Imm.IsRV64 = IsRV64;
1195 static std::unique_ptr<RISCVOperand> createFPImm(
uint64_t Val,
SMLoc S) {
1196 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1197 Op->FPImm.Val = Val;
1203 static std::unique_ptr<RISCVOperand> createSysReg(
StringRef Str,
SMLoc S,
1204 unsigned Encoding) {
1205 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1206 Op->SysReg.Data = Str.data();
1207 Op->SysReg.Length = Str.size();
1214 static std::unique_ptr<RISCVOperand>
1216 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1223 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val,
SMLoc S) {
1224 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1225 Op->Fence.Val = Val;
1231 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI,
SMLoc S) {
1232 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1233 Op->VType.Val = VTypeI;
1239 static std::unique_ptr<RISCVOperand> createRlist(
unsigned RlistEncode,
1241 auto Op = std::make_unique<RISCVOperand>(KindTy::Rlist);
1242 Op->Rlist.Val = RlistEncode;
1247 static std::unique_ptr<RISCVOperand> createRegReg(
MCRegister Reg1,
1249 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1250 Op->RegReg.Reg1 = Reg1.
id();
1251 Op->RegReg.Reg2 = Reg2.
id();
1257 static std::unique_ptr<RISCVOperand> createSpimm(
unsigned Spimm,
SMLoc S) {
1258 auto Op = std::make_unique<RISCVOperand>(KindTy::Spimm);
1259 Op->Spimm.Val = Spimm;
1264 static void addExpr(
MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1265 assert(Expr &&
"Expr shouldn't be null!");
1268 bool IsConstant = evaluateConstantImm(Expr, Imm, VK);
1278 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1279 assert(
N == 1 &&
"Invalid number of operands!");
1283 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1284 assert(
N == 1 &&
"Invalid number of operands!");
1285 addExpr(Inst, getImm(), isRV64Imm());
1288 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
1289 assert(
N == 1 &&
"Invalid number of operands!");
1291 addExpr(Inst, getImm(), isRV64Imm());
1296 APFloat(APFloat::IEEEdouble(),
APInt(64, getFPConst())));
1300 void addFenceArgOperands(
MCInst &Inst,
unsigned N)
const {
1301 assert(
N == 1 &&
"Invalid number of operands!");
1305 void addCSRSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
1306 assert(
N == 1 &&
"Invalid number of operands!");
1313 void addVTypeIOperands(
MCInst &Inst,
unsigned N)
const {
1314 assert(
N == 1 &&
"Invalid number of operands!");
1316 if (Kind == KindTy::Immediate) {
1318 [[maybe_unused]]
bool IsConstantImm =
1319 evaluateConstantImm(getImm(), Imm, VK);
1320 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1327 void addRlistOperands(
MCInst &Inst,
unsigned N)
const {
1328 assert(
N == 1 &&
"Invalid number of operands!");
1332 void addRegRegOperands(
MCInst &Inst,
unsigned N)
const {
1333 assert(
N == 2 &&
"Invalid number of operands!");
1338 void addSpimmOperands(
MCInst &Inst,
unsigned N)
const {
1339 assert(
N == 1 &&
"Invalid number of operands!");
1343 void addFRMArgOperands(
MCInst &Inst,
unsigned N)
const {
1344 assert(
N == 1 &&
"Invalid number of operands!");
1350#define GET_REGISTER_MATCHER
1351#define GET_SUBTARGET_FEATURE_NAME
1352#define GET_MATCHER_IMPLEMENTATION
1353#define GET_MNEMONIC_SPELL_CHECKER
1354#include "RISCVGenAsmMatcher.inc"
1357 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1358 return Reg - RISCV::F0_D + RISCV::F0_H;
1362 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1363 return Reg - RISCV::F0_D + RISCV::F0_F;
1368 unsigned RegClassID;
1369 if (Kind == MCK_VRM2)
1370 RegClassID = RISCV::VRM2RegClassID;
1371 else if (Kind == MCK_VRM4)
1372 RegClassID = RISCV::VRM4RegClassID;
1373 else if (Kind == MCK_VRM8)
1374 RegClassID = RISCV::VRM8RegClassID;
1378 &RISCVMCRegisterClasses[RegClassID]);
1383 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1385 return Match_InvalidOperand;
1389 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg);
1391 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg);
1392 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg);
1396 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1397 (IsRegFPR64C &&
Kind == MCK_FPR32C)) {
1399 return Match_Success;
1403 if (IsRegFPR64 && Kind == MCK_FPR16) {
1405 return Match_Success;
1407 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1408 Op.Reg.RegNum =
Reg - RISCV::X0 + RISCV::X0_H;
1409 return Match_Success;
1411 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1412 Op.Reg.RegNum =
Reg - RISCV::X0 + RISCV::X0_W;
1413 return Match_Success;
1420 if (RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg) &&
1421 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1423 return Match_Success;
1427 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1430 return Match_InvalidOperand;
1431 return Match_Success;
1433 return Match_InvalidOperand;
1436bool RISCVAsmParser::generateImmOutOfRangeError(
1438 const Twine &Msg =
"immediate must be an integer in the range") {
1442bool RISCVAsmParser::generateImmOutOfRangeError(
1444 const Twine &Msg =
"immediate must be an integer in the range") {
1446 return generateImmOutOfRangeError(ErrorLoc,
Lower,
Upper, Msg);
1449bool RISCVAsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1453 bool MatchingInlineAsm) {
1463 if (validateInstruction(Inst,
Operands))
1465 return processInstruction(Inst, IDLoc,
Operands, Out);
1466 case Match_MissingFeature: {
1467 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1468 bool FirstFeature =
true;
1469 std::string Msg =
"instruction requires the following:";
1470 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1471 if (MissingFeatures[i]) {
1472 Msg += FirstFeature ?
" " :
", ";
1474 FirstFeature =
false;
1477 return Error(IDLoc, Msg);
1479 case Match_MnemonicFail: {
1480 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1481 std::string Suggestion = RISCVMnemonicSpellCheck(
1482 ((RISCVOperand &)*
Operands[0]).getToken(), FBS, 0);
1483 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1485 case Match_InvalidOperand: {
1486 SMLoc ErrorLoc = IDLoc;
1489 return Error(ErrorLoc,
"too few operands for instruction");
1492 if (ErrorLoc ==
SMLoc())
1495 return Error(ErrorLoc,
"invalid operand for instruction");
1502 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1503 SMLoc ErrorLoc = IDLoc;
1505 return Error(ErrorLoc,
"too few operands for instruction");
1511 case Match_InvalidImmXLenLI:
1514 return Error(ErrorLoc,
"operand must be a constant 64-bit integer");
1517 std::numeric_limits<int32_t>::min(),
1518 std::numeric_limits<uint32_t>::max());
1519 case Match_InvalidImmXLenLI_Restricted:
1522 return Error(ErrorLoc,
"operand either must be a constant 64-bit integer "
1523 "or a bare symbol name");
1525 return generateImmOutOfRangeError(
1527 std::numeric_limits<uint32_t>::max(),
1528 "operand either must be a bare symbol name or an immediate integer in "
1530 case Match_InvalidUImmLog2XLen:
1534 case Match_InvalidUImmLog2XLenNonZero:
1538 case Match_InvalidUImm1:
1540 case Match_InvalidUImm2:
1542 case Match_InvalidUImm2Lsb0:
1544 "immediate must be one of");
1545 case Match_InvalidUImm3:
1547 case Match_InvalidUImm4:
1549 case Match_InvalidUImm5:
1551 case Match_InvalidUImm5NonZero:
1553 case Match_InvalidUImm5GT3:
1555 case Match_InvalidUImm6:
1557 case Match_InvalidUImm7:
1559 case Match_InvalidUImm8:
1561 case Match_InvalidUImm8GE32:
1563 case Match_InvalidSImm5:
1566 case Match_InvalidSImm6:
1569 case Match_InvalidSImm6NonZero:
1570 return generateImmOutOfRangeError(
1572 "immediate must be non-zero in the range");
1573 case Match_InvalidCLUIImm:
1574 return generateImmOutOfRangeError(
1576 "immediate must be in [0xfffe0, 0xfffff] or");
1577 case Match_InvalidUImm5Lsb0:
1578 return generateImmOutOfRangeError(
1580 "immediate must be a multiple of 2 bytes in the range");
1581 case Match_InvalidUImm6Lsb0:
1582 return generateImmOutOfRangeError(
1584 "immediate must be a multiple of 2 bytes in the range");
1585 case Match_InvalidUImm7Lsb00:
1586 return generateImmOutOfRangeError(
1588 "immediate must be a multiple of 4 bytes in the range");
1589 case Match_InvalidUImm8Lsb00:
1590 return generateImmOutOfRangeError(
1592 "immediate must be a multiple of 4 bytes in the range");
1593 case Match_InvalidUImm8Lsb000:
1594 return generateImmOutOfRangeError(
1596 "immediate must be a multiple of 8 bytes in the range");
1597 case Match_InvalidSImm9Lsb0:
1598 return generateImmOutOfRangeError(
1600 "immediate must be a multiple of 2 bytes in the range");
1601 case Match_InvalidUImm9Lsb000:
1602 return generateImmOutOfRangeError(
1604 "immediate must be a multiple of 8 bytes in the range");
1605 case Match_InvalidUImm10Lsb00NonZero:
1606 return generateImmOutOfRangeError(
1608 "immediate must be a multiple of 4 bytes in the range");
1609 case Match_InvalidSImm10Lsb0000NonZero:
1610 return generateImmOutOfRangeError(
1612 "immediate must be a multiple of 16 bytes and non-zero in the range");
1613 case Match_InvalidUImm10:
1615 case Match_InvalidUImm11:
1617 case Match_InvalidSImm12:
1618 return generateImmOutOfRangeError(
1620 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an "
1621 "integer in the range");
1622 case Match_InvalidSImm12Lsb0:
1623 return generateImmOutOfRangeError(
1625 "immediate must be a multiple of 2 bytes in the range");
1626 case Match_InvalidSImm12Lsb00000:
1627 return generateImmOutOfRangeError(
1629 "immediate must be a multiple of 32 bytes in the range");
1630 case Match_InvalidSImm13Lsb0:
1631 return generateImmOutOfRangeError(
1633 "immediate must be a multiple of 2 bytes in the range");
1634 case Match_InvalidUImm20LUI:
1636 "operand must be a symbol with "
1637 "%hi/%tprel_hi modifier or an integer in "
1639 case Match_InvalidUImm20:
1641 case Match_InvalidUImm20AUIPC:
1642 return generateImmOutOfRangeError(
1644 "operand must be a symbol with a "
1645 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
1646 "an integer in the range");
1647 case Match_InvalidSImm21Lsb0JAL:
1648 return generateImmOutOfRangeError(
1650 "immediate must be a multiple of 2 bytes in the range");
1651 case Match_InvalidCSRSystemRegister: {
1653 "operand must be a valid system register "
1654 "name or an integer in the range");
1656 case Match_InvalidVTypeI: {
1658 return generateVTypeError(ErrorLoc);
1660 case Match_InvalidSImm5Plus1: {
1663 "immediate must be in the range");
1665 case Match_InvalidSImm26:
1668 case Match_InvalidRnumArg: {
1673 if (
const char *MatchDiag = getMatchKindDiag((RISCVMatchResultTy)Result)) {
1675 return Error(ErrorLoc, MatchDiag);
1692 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1693 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1696 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1703 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1704 return Error(StartLoc,
"invalid register name");
1710 const AsmToken &Tok = getParser().getTok();
1725 SMLoc FirstS = getLoc();
1726 bool HadParens =
false;
1733 size_t ReadCount = getLexer().peekTokens(Buf);
1736 LParen = getParser().getTok();
1741 switch (getLexer().getKind()) {
1744 getLexer().UnLex(LParen);
1752 getLexer().UnLex(LParen);
1756 Operands.push_back(RISCVOperand::createToken(
"(", FirstS));
1760 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
1765 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
1776 switch (getLexer().getKind()) {
1786 if (getParser().parseExpression(Res,
E))
1789 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1791 int64_t
Imm =
CE->getValue();
1792 if (isUInt<7>(Imm)) {
1793 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1802 if (getParser().parseIdentifier(Identifier))
1805 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1807 assert(isUInt<7>(Opcode->Value) && (Opcode->Value & 0x3) == 3 &&
1808 "Unexpected opcode");
1811 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1821 return generateImmOutOfRangeError(
1823 "opcode must be a valid opcode name or an immediate in the range");
1831 switch (getLexer().getKind()) {
1841 if (getParser().parseExpression(Res,
E))
1844 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1846 int64_t
Imm =
CE->getValue();
1847 if (Imm >= 0 && Imm <= 2) {
1848 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1857 if (getParser().parseIdentifier(Identifier))
1861 if (Identifier ==
"C0")
1863 else if (Identifier ==
"C1")
1865 else if (Identifier ==
"C2")
1872 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1881 return generateImmOutOfRangeError(
1883 "opcode must be a valid opcode name or an immediate in the range");
1890 auto SysRegFromConstantInt = [
this](
const MCExpr *
E,
SMLoc S) {
1891 if (
auto *CE = dyn_cast<MCConstantExpr>(
E)) {
1892 int64_t
Imm =
CE->getValue();
1893 if (isUInt<12>(Imm)) {
1894 auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
1898 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
1901 return RISCVOperand::createSysReg(
Reg.Name, S, Imm);
1905 return RISCVOperand::createSysReg(
"", S, Imm);
1908 return std::unique_ptr<RISCVOperand>();
1911 switch (getLexer().getKind()) {
1921 if (getParser().parseExpression(Res))
1924 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
1925 Operands.push_back(std::move(SysOpnd));
1929 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1933 if (getParser().parseIdentifier(Identifier))
1936 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1939 if (SysReg->IsDeprecatedName) {
1941 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
1943 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
1945 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
1951 const auto &FeatureBits = getSTI().getFeatureBits();
1952 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
1954 return SysReg->FeaturesRequired[Feature.Value];
1956 auto ErrorMsg = std::string(
"system register '") + SysReg->Name +
"' ";
1957 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
1958 ErrorMsg +=
"is RV32 only";
1960 ErrorMsg +=
" and ";
1964 "requires '" + std::string(Feature->Key) +
"' to be enabled";
1967 return Error(S, ErrorMsg);
1970 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
1975 MCSymbol *
Sym = getContext().lookupSymbol(Identifier);
1976 if (
Sym &&
Sym->isVariable()) {
1979 if (
auto SysOpnd = SysRegFromConstantInt(
1980 Sym->getVariableValue(
false), S)) {
1981 Operands.push_back(std::move(SysOpnd));
1986 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
1987 "operand must be a valid system register "
1988 "name or an integer in the range");
1992 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2005 if (
Identifier.compare_insensitive(
"inf") == 0) {
2008 getTok().getEndLoc(), isRV64()));
2009 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2012 getTok().getEndLoc(), isRV64()));
2013 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2016 getTok().getEndLoc(), isRV64()));
2018 return TokError(
"invalid floating point literal");
2031 return TokError(
"invalid floating point immediate");
2034 APFloat RealVal(APFloat::IEEEdouble());
2036 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2038 return TokError(
"invalid floating point representation");
2041 RealVal.changeSign();
2043 Operands.push_back(RISCVOperand::createFPImm(
2044 RealVal.bitcastToAPInt().getZExtValue(), S));
2056 switch (getLexer().getKind()) {
2068 if (getParser().parseExpression(Res,
E))
2072 return parseOperandWithModifier(
Operands);
2075 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2087 return Error(getLoc(),
"expected valid identifier for operand modifier");
2091 return Error(getLoc(),
"unrecognized operand modifier");
2098 if (getParser().parseParenExpression(SubExpr,
E))
2102 Operands.push_back(RISCVOperand::createImm(ModExpr, S,
E, isRV64()));
2114 AsmToken Tok = getLexer().getTok();
2116 if (getParser().parseIdentifier(Identifier))
2122 return Error(getLoc(),
"'@plt' operand not valid for instruction");
2124 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
2126 if (
Sym->isVariable()) {
2127 const MCExpr *
V =
Sym->getVariableValue(
false);
2128 if (!isa<MCSymbolRefExpr>(V)) {
2129 getLexer().UnLex(Tok);
2137 switch (getLexer().getKind()) {
2139 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2152 if (getParser().parseExpression(Expr,
E))
2155 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2171 if (getParser().parseIdentifier(Identifier))
2179 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
2182 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2191 if (getParser().parseExpression(Res,
E))
2194 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef ||
2195 cast<MCSymbolRefExpr>(Res)->getKind() ==
2196 MCSymbolRefExpr::VariantKind::VK_PLT)
2197 return Error(S,
"operand must be a valid jump target");
2200 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2221bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2222 unsigned &Sew,
unsigned &Lmul,
2223 bool &Fractional,
bool &TailAgnostic,
2224 bool &MaskAgnostic) {
2231 case VTypeState_SEW:
2238 State = VTypeState_LMUL;
2240 case VTypeState_LMUL: {
2250 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2251 unsigned MinLMUL = ELEN / 8;
2254 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2255 Twine(MinLMUL) +
" is reserved");
2258 State = VTypeState_TailPolicy;
2261 case VTypeState_TailPolicy:
2262 if (Identifier ==
"ta")
2263 TailAgnostic =
true;
2264 else if (Identifier ==
"tu")
2265 TailAgnostic =
false;
2268 State = VTypeState_MaskPolicy;
2270 case VTypeState_MaskPolicy:
2271 if (Identifier ==
"ma")
2272 MaskAgnostic =
true;
2273 else if (Identifier ==
"mu")
2274 MaskAgnostic =
false;
2277 State = VTypeState_Done;
2279 case VTypeState_Done:
2292 bool Fractional =
false;
2293 bool TailAgnostic =
false;
2294 bool MaskAgnostic =
false;
2296 VTypeState State = VTypeState_SEW;
2299 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2306 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2316 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2317 unsigned MaxSEW = ELEN / Lmul;
2319 if (MaxSEW >= 8 && Sew > MaxSEW)
2321 "use of vtype encodings with SEW > " +
Twine(MaxSEW) +
2322 " and LMUL == mf" +
Twine(Lmul) +
2323 " may not be compatible with all RVV implementations");
2328 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2332 return generateVTypeError(S);
2335bool RISCVAsmParser::generateVTypeError(
SMLoc ErrorLoc) {
2339 "e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2347 if (!
Name.consume_back(
".t"))
2348 return Error(getLoc(),
"expected '.t' suffix");
2353 if (
Reg != RISCV::V0)
2358 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2363 if (!isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2381 Operands.push_back(RISCVOperand::createReg(
2382 Reg, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2387 if (isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2399 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2402 if ((
Reg - RISCV::X0) & 1) {
2405 if (getSTI().hasFeature(RISCV::FeatureStdExtZfinx))
2406 return TokError(
"double precision floating point operands must use even "
2407 "numbered X register");
2417 Reg, RISCV::sub_gpr_even,
2418 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2419 Operands.push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2423template <
bool IsRV64>
2425 return parseGPRPair(
Operands, IsRV64);
2435 if (!IsRV64Inst && isRV64())
2447 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2450 if ((
Reg - RISCV::X0) & 1)
2451 return TokError(
"register must be even");
2459 Reg, RISCV::sub_gpr_even,
2460 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2461 Operands.push_back(RISCVOperand::createReg(Pair, S,
E));
2468 "operand must be a valid floating point rounding mode mnemonic");
2470 StringRef Str = getLexer().getTok().getIdentifier();
2475 "operand must be a valid floating point rounding mode mnemonic");
2477 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2483 const AsmToken &Tok = getLexer().getTok();
2489 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2503 for (
char c : Str) {
2532 Operands.push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2538 return TokError(
"operand must be formed of letters selected in-order from "
2545 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
2547 if (!parseRegister(
Operands).isSuccess())
2548 return Error(getLoc(),
"expected register");
2552 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2576 std::unique_ptr<RISCVOperand> OptionalImmOp;
2583 SMLoc ImmStart = getLoc();
2584 if (getParser().parseIntToken(ImmVal,
2585 "expected '(' or optional integer offset"))
2590 SMLoc ImmEnd = getLoc();
2593 ImmStart, ImmEnd, isRV64());
2597 OptionalImmOp ?
"expected '(' after optional integer offset"
2598 :
"expected '(' or optional integer offset"))
2601 if (!parseRegister(
Operands).isSuccess())
2602 return Error(getLoc(),
"expected register");
2608 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2610 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2611 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2624 return Error(getLoc(),
"invalid register");
2631 return Error(getLoc(),
"expected register");
2633 StringRef Reg2Name = getLexer().getTok().getIdentifier();
2636 return Error(getLoc(),
"invalid register");
2642 Operands.push_back(RISCVOperand::createRegReg(
Reg, Reg2, getLoc()));
2655 bool IsEABI = isRVE();
2658 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2663 if (RegStart != RISCV::X1)
2664 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2670 return Error(getLoc(),
"invalid register");
2674 return Error(getLoc(),
"invalid register");
2675 if (RegStart != RISCV::X8)
2676 return Error(getLoc(),
2677 "continuous register list must start from 's0' or 'x8'");
2683 StringRef EndName = getLexer().getTok().getIdentifier();
2687 return Error(getLoc(),
"invalid register");
2688 if (IsEABI && RegEnd != RISCV::X9)
2689 return Error(getLoc(),
"contiguous register list of EABI can only be "
2690 "'s0-s1' or 'x8-x9' pair");
2697 if (RegEnd != RISCV::X9)
2700 "first contiguous registers pair of register list must be 'x8-x9'");
2704 return Error(getLoc(),
"invalid register");
2705 StringRef EndName = getLexer().getTok().getIdentifier();
2707 return Error(getLoc(),
2708 "second contiguous registers pair of register list "
2709 "must start from 'x18'");
2715 return Error(getLoc(),
"invalid register");
2716 EndName = getLexer().getTok().getIdentifier();
2718 return Error(getLoc(),
"invalid register");
2725 if (RegEnd == RISCV::X26)
2726 return Error(getLoc(),
"invalid register list, {ra, s0-s10} or {x1, x8-x9, "
2727 "x18-x26} is not supported");
2737 return Error(S,
"invalid register list");
2738 Operands.push_back(RISCVOperand::createRlist(Encode, S));
2744 bool ExpectNegative) {
2750 unsigned RlistVal =
static_cast<RISCVOperand *
>(
Operands[1].get())->Rlist.Val;
2752 if (Negative != ExpectNegative ||
2755 Operands.push_back(RISCVOperand::createSpimm(Spimm << 4, S));
2767 MatchOperandParserImpl(
Operands, Mnemonic,
true);
2774 if (parseRegister(
Operands,
true).isSuccess())
2781 return !parseMemOpBaseReg(
Operands).isSuccess();
2786 Error(getLoc(),
"unknown operand");
2799 if (getSTI().hasFeature(RISCV::FeatureRelax)) {
2800 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
2801 if (Assembler !=
nullptr) {
2809 Operands.push_back(RISCVOperand::createToken(
Name, NameLoc));
2828 if (getParser().parseEOL(
"unexpected token")) {
2829 getParser().eatToEndOfStatement();
2835bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
2839 if (
const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
2840 Kind = RE->getKind();
2841 Expr = RE->getSubExpr();
2851bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
2864 if (IDVal ==
".option")
2865 return parseDirectiveOption();
2866 if (IDVal ==
".attribute")
2867 return parseDirectiveAttribute();
2868 if (IDVal ==
".insn")
2869 return parseDirectiveInsn(DirectiveID.
getLoc());
2870 if (IDVal ==
".variant_cc")
2871 return parseDirectiveVariantCC();
2876bool RISCVAsmParser::resetToArch(
StringRef Arch,
SMLoc Loc, std::string &Result,
2877 bool FromOptionDirective) {
2880 clearFeatureBits(Feature.Value, Feature.Key);
2889 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
2890 << ErrMsg.getMessage();
2893 return Error(Loc, OutputErrMsg.str());
2898 if (ISAInfo->hasExtension(Feature.Key))
2899 setFeatureBits(Feature.Value, Feature.Key);
2901 if (FromOptionDirective) {
2902 if (ISAInfo->getXLen() == 32 && isRV64())
2903 return Error(Loc,
"bad arch string switching from rv64 to rv32");
2904 else if (ISAInfo->getXLen() == 64 && !isRV64())
2905 return Error(Loc,
"bad arch string switching from rv32 to rv64");
2908 if (ISAInfo->getXLen() == 32)
2909 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
2910 else if (ISAInfo->getXLen() == 64)
2911 setFeatureBits(RISCV::Feature64Bit,
"64bit");
2913 return Error(Loc,
"bad arch string " + Arch);
2915 Result = ISAInfo->toString();
2919bool RISCVAsmParser::parseDirectiveOption() {
2930 if (Option ==
"push") {
2934 getTargetStreamer().emitDirectiveOptionPush();
2939 if (Option ==
"pop") {
2944 getTargetStreamer().emitDirectiveOptionPop();
2945 if (popFeatureBits())
2946 return Error(StartLoc,
".option pop with no .option push");
2951 if (Option ==
"arch") {
2959 Type = RISCVOptionArchArgType::Plus;
2961 Type = RISCVOptionArchArgType::Minus;
2962 else if (!
Args.empty())
2964 "unexpected token, expected + or -");
2966 Type = RISCVOptionArchArgType::Full;
2970 "unexpected token, expected identifier");
2976 if (
Type == RISCVOptionArchArgType::Full) {
2978 if (resetToArch(Arch, Loc, Result,
true))
2987 Loc,
"extension version number parsing not currently implemented");
2990 if (!enableExperimentalExtension() &&
2992 return Error(Loc,
"unexpected experimental extensions");
2995 return Error(Loc,
"unknown extension feature");
2999 if (
Type == RISCVOptionArchArgType::Plus) {
3002 setFeatureBits(
Ext->Value,
Ext->Key);
3005 copySTI().setFeatureBits(OldFeatureBits);
3006 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3011 OutputErrMsg << ErrMsg.getMessage();
3014 return Error(Loc, OutputErrMsg.str());
3017 assert(
Type == RISCVOptionArchArgType::Minus);
3022 if (getSTI().hasFeature(Feature.Value) &&
3023 Feature.Implies.test(
Ext->Value))
3025 " extension; " + Feature.Key +
3026 " extension requires " +
Ext->Key +
3030 clearFeatureBits(
Ext->Value,
Ext->Key);
3037 getTargetStreamer().emitDirectiveOptionArch(Args);
3041 if (Option ==
"rvc") {
3045 getTargetStreamer().emitDirectiveOptionRVC();
3046 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3050 if (Option ==
"norvc") {
3054 getTargetStreamer().emitDirectiveOptionNoRVC();
3055 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3056 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3060 if (Option ==
"pic") {
3064 getTargetStreamer().emitDirectiveOptionPIC();
3065 ParserOptions.IsPicEnabled =
true;
3069 if (Option ==
"nopic") {
3073 getTargetStreamer().emitDirectiveOptionNoPIC();
3074 ParserOptions.IsPicEnabled =
false;
3078 if (Option ==
"relax") {
3082 getTargetStreamer().emitDirectiveOptionRelax();
3083 setFeatureBits(RISCV::FeatureRelax,
"relax");
3087 if (Option ==
"norelax") {
3091 getTargetStreamer().emitDirectiveOptionNoRelax();
3092 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3098 "'rvc', 'norvc', 'arch', 'relax' or "
3107bool RISCVAsmParser::parseDirectiveAttribute() {
3114 std::optional<unsigned>
Ret =
3117 return Error(TagLoc,
"attribute name not recognised: " +
Name);
3128 if (check(!CE, TagLoc,
"expected numeric constant"))
3131 Tag =
CE->getValue();
3138 int64_t IntegerValue = 0;
3139 bool IsIntegerValue =
true;
3144 IsIntegerValue =
false;
3147 if (IsIntegerValue) {
3154 return Error(ValueExprLoc,
"expected numeric constant");
3155 IntegerValue =
CE->getValue();
3168 getTargetStreamer().emitAttribute(Tag, IntegerValue);
3170 getTargetStreamer().emitTextAttribute(Tag, StringValue);
3173 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3177 getTargetStreamer().emitTextAttribute(Tag, Result);
3185 .
Cases(
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s",
true)
3186 .
Cases(
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj", AllowC)
3194bool RISCVAsmParser::parseDirectiveInsn(
SMLoc L) {
3197 bool AllowC = getSTI().hasFeature(RISCV::FeatureStdExtC) ||
3198 getSTI().hasFeature(RISCV::FeatureStdExtZca);
3205 std::optional<int64_t>
Length;
3215 return Error(ErrorLoc,
3216 "instruction lengths must be a non-zero multiple of two");
3220 return Error(ErrorLoc,
3221 "instruction lengths over 64 bits are not supported");
3227 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3232 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3233 return Error(ErrorLoc,
3234 "instruction length does not match the encoding");
3237 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3240 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3243 if (!AllowC && (EncodingDerivedLength == 2))
3244 return Error(ErrorLoc,
"compressed instructions are not allowed");
3246 if (getParser().parseEOL(
"invalid operand for instruction")) {
3247 getParser().eatToEndOfStatement();
3255 Opcode = RISCV::Insn16;
3258 Opcode = RISCV::Insn32;
3261 Opcode = RISCV::Insn48;
3264 Opcode = RISCV::Insn64;
3270 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3277 return Error(ErrorLoc,
"invalid instruction format");
3279 std::string FormatName = (
".insn_" +
Format).str();
3296bool RISCVAsmParser::parseDirectiveVariantCC() {
3298 if (getParser().parseIdentifier(
Name))
3299 return TokError(
"expected symbol name");
3302 getTargetStreamer().emitDirectiveVariantCC(
3303 *getContext().getOrCreateSymbol(
Name));
3311 ++RISCVNumInstrsCompressed;
3320 for (
MCInst &Inst : Seq) {
3321 emitToStreamer(Out, Inst);
3328 unsigned SecondOpcode,
SMLoc IDLoc,
3342 const MCExpr *RefToLinkTmpLabel =
3349 .addExpr(RefToLinkTmpLabel));
3352void RISCVAsmParser::emitLoadLocalAddress(
MCInst &Inst,
SMLoc IDLoc,
3363 RISCV::ADDI, IDLoc, Out);
3366void RISCVAsmParser::emitLoadGlobalAddress(
MCInst &Inst,
SMLoc IDLoc,
3376 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3378 SecondOpcode, IDLoc, Out);
3381void RISCVAsmParser::emitLoadAddress(
MCInst &Inst,
SMLoc IDLoc,
3390 if (ParserOptions.IsPicEnabled)
3391 emitLoadGlobalAddress(Inst, IDLoc, Out);
3393 emitLoadLocalAddress(Inst, IDLoc, Out);
3396void RISCVAsmParser::emitLoadTLSIEAddress(
MCInst &Inst,
SMLoc IDLoc,
3406 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3408 SecondOpcode, IDLoc, Out);
3411void RISCVAsmParser::emitLoadTLSGDAddress(
MCInst &Inst,
SMLoc IDLoc,
3422 RISCV::ADDI, IDLoc, Out);
3425void RISCVAsmParser::emitLoadStoreSymbol(
MCInst &Inst,
unsigned Opcode,
3435 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3437 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3441 Opcode, IDLoc, Out);
3444void RISCVAsmParser::emitPseudoExtend(
MCInst &Inst,
bool SignExtend,
3445 int64_t Width,
SMLoc IDLoc,
3457 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3458 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3460 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3473void RISCVAsmParser::emitVMSGE(
MCInst &Inst,
unsigned Opcode,
SMLoc IDLoc,
3497 "The destination register should not be V0.");
3516 "The destination register should be V0.");
3518 "The temporary vector register should not be V0.");
3537 "The temporary vector register should not be V0.");
3562bool RISCVAsmParser::checkPseudoAddTPRel(
MCInst &Inst,
3564 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3567 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3568 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3569 "%tprel_add modifier");
3575bool RISCVAsmParser::checkPseudoTLSDESCCall(
MCInst &Inst,
3577 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
3580 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3581 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
3582 "%tlsdesc_call modifier");
3588std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3592std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3593 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3597std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3598 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3602bool RISCVAsmParser::validateInstruction(
MCInst &Inst,
3606 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3607 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3610 if (DestReg == TempReg) {
3612 return Error(Loc,
"the temporary vector register cannot be the same as "
3613 "the destination register");
3617 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3618 Opcode == RISCV::TH_LWD) {
3623 if (Rs1 == Rd1 && Rs1 == Rd2) {
3625 return Error(Loc,
"rs1, rd1, and rd2 cannot all be the same");
3629 if (Opcode == RISCV::CM_MVSA01) {
3634 return Error(Loc,
"rs1 and rs2 must be different");
3638 bool IsTHeadMemPair32 = (Opcode == RISCV::TH_LWD ||
3639 Opcode == RISCV::TH_LWUD || Opcode == RISCV::TH_SWD);
3640 bool IsTHeadMemPair64 = (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_SDD);
3645 return Error(Loc,
"operand must be constant 3");
3648 return Error(Loc,
"operand must be constant 4");
3655 if (Opcode == RISCV::VC_V_XVW || Opcode == RISCV::VC_V_IVW ||
3656 Opcode == RISCV::VC_V_FVW || Opcode == RISCV::VC_V_VVW) {
3662 if (VCIXDst == VCIXRs1)
3663 return Error(VCIXDstLoc,
"the destination vector register group cannot"
3664 " overlap the source vector register group");
3668 if (VCIXDst == VCIXRs2)
3669 return Error(VCIXDstLoc,
"the destination vector register group cannot"
3670 " overlap the source vector register group");
3685 if (DestReg == CheckReg)
3686 return Error(Loc,
"the destination vector register group cannot overlap"
3687 " the source vector register group");
3691 if (DestReg == CheckReg)
3692 return Error(Loc,
"the destination vector register group cannot overlap"
3693 " the source vector register group");
3698 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM ||
3699 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM ||
3700 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM ||
3701 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM ||
3702 Opcode == RISCV::VMERGE_VXM)
3703 return Error(Loc,
"the destination vector register group cannot be V0");
3710 assert((CheckReg == RISCV::V0 || !CheckReg) &&
3711 "Unexpected register for mask operand");
3713 if (DestReg == CheckReg)
3714 return Error(Loc,
"the destination vector register group cannot overlap"
3715 " the mask register");
3720bool RISCVAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
3728 case RISCV::PseudoC_ADDI_NOP:
3731 case RISCV::PseudoLLAImm:
3732 case RISCV::PseudoLAImm:
3733 case RISCV::PseudoLI: {
3750 Imm = SignExtend64<32>(Imm);
3751 emitLoadImm(
Reg, Imm, Out);
3754 case RISCV::PseudoLLA:
3755 emitLoadLocalAddress(Inst, IDLoc, Out);
3757 case RISCV::PseudoLGA:
3758 emitLoadGlobalAddress(Inst, IDLoc, Out);
3760 case RISCV::PseudoLA:
3761 emitLoadAddress(Inst, IDLoc, Out);
3763 case RISCV::PseudoLA_TLS_IE:
3764 emitLoadTLSIEAddress(Inst, IDLoc, Out);
3766 case RISCV::PseudoLA_TLS_GD:
3767 emitLoadTLSGDAddress(Inst, IDLoc, Out);
3769 case RISCV::PseudoLB:
3770 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
3772 case RISCV::PseudoLBU:
3773 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
3775 case RISCV::PseudoLH:
3776 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
3778 case RISCV::PseudoLHU:
3779 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
3781 case RISCV::PseudoLW:
3782 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
3784 case RISCV::PseudoLWU:
3785 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
3787 case RISCV::PseudoLD:
3788 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
3790 case RISCV::PseudoFLH:
3791 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
3793 case RISCV::PseudoFLW:
3794 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
3796 case RISCV::PseudoFLD:
3797 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
3799 case RISCV::PseudoSB:
3800 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
3802 case RISCV::PseudoSH:
3803 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
3805 case RISCV::PseudoSW:
3806 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
3808 case RISCV::PseudoSD:
3809 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
3811 case RISCV::PseudoFSH:
3812 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
3814 case RISCV::PseudoFSW:
3815 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
3817 case RISCV::PseudoFSD:
3818 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
3820 case RISCV::PseudoAddTPRel:
3821 if (checkPseudoAddTPRel(Inst,
Operands))
3824 case RISCV::PseudoTLSDESCCall:
3825 if (checkPseudoTLSDESCCall(Inst,
Operands))
3828 case RISCV::PseudoSEXT_B:
3829 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
3831 case RISCV::PseudoSEXT_H:
3832 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
3834 case RISCV::PseudoZEXT_H:
3835 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
3837 case RISCV::PseudoZEXT_W:
3838 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
3840 case RISCV::PseudoVMSGEU_VX:
3841 case RISCV::PseudoVMSGEU_VX_M:
3842 case RISCV::PseudoVMSGEU_VX_M_T:
3843 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
3845 case RISCV::PseudoVMSGE_VX:
3846 case RISCV::PseudoVMSGE_VX_M:
3847 case RISCV::PseudoVMSGE_VX_M_T:
3848 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
3850 case RISCV::PseudoVMSGE_VI:
3851 case RISCV::PseudoVMSLT_VI: {
3855 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
3865 case RISCV::PseudoVMSGEU_VI:
3866 case RISCV::PseudoVMSLTU_VI: {
3873 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3884 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3899 emitToStreamer(Out, Inst);
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
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 void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, MCRegister &Reg, StringRef Name)
#define LLVM_EXTERNAL_VISIBILITY
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
mir Rename Register Operands
static unsigned 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 GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
PowerPC TLS Dynamic Call Fixup
bool isValidInsnFormat(StringRef Format, bool AllowC)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser()
static MCRegister convertFPR64ToFPR32(MCRegister Reg)
static cl::opt< bool > AddBuildAttributes("riscv-add-build-attributes", cl::init(false))
static MCRegister convertFPR64ToFPR16(MCRegister Reg)
static MCRegister convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg, unsigned Kind)
static bool isDigit(const char C)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector 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)
bool parseImmediate(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes)
Class for arbitrary precision integers.
Target independent representation for an assembler token.
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
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
This class represents an Operation in the Expression.
Encoding
Size and signedness of expression operations' operands.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Container class for subtarget features.
constexpr size_t size() const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
MCStreamer & getStreamer()
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
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.
virtual MCContext & getContext()=0
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCObjectFileInfo * getObjectFileInfo() const
MCSymbol * createNamedTempSymbol()
Create a temporary symbol with a unique name whose name cannot be omitted in the symbol table.
Base class for the full range of assembler expressions which are needed for parsing.
bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specified operand constraint if it is present.
Interface to description of machine instruction set.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
bool isPositionIndependent() const
Instances of this class represent operands of the MCInst class.
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.
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.
Wrapper class representing physical registers. Should be passed by value.
constexpr unsigned id() const
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
MCTargetStreamer * getTargetStreamer()
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
void setFeatureBits(const FeatureBitset &FeatureBits_)
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() 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)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual ParseStatus parseDirective(AsmToken DirectiveID)
Parses a target-specific assembler directive.
virtual bool parseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
Parse one assembly instruction.
MCSubtargetInfo & copySTI()
Create a copy of STI and return a non-const reference to it.
@ FIRST_TARGET_MATCH_RESULT_TY
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
virtual bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
Recognize a series of operands of a parsed instruction as an actual MCInst and emit it to the specifi...
void setAvailableFeatures(const FeatureBitset &Value)
const MCSubtargetInfo & getSTI() const
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)
Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...
Target specific streamer interface.
This represents an "assembler immediate".
uint32_t getRefKind() const
const MCSymbolRefExpr * getSymB() const
const MCSymbolRefExpr * getSymA() const
This class represents success/failure for parsing-like operations that find it important to chain tog...
Ternary parse status returned by various parse* methods.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
static bool isSupportedExtensionFeature(StringRef Ext)
static std::string getTargetFeatureForExtension(StringRef Ext)
static llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseArchString(StringRef Arch, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck=true)
Parse RISC-V ISA info from arch string.
static const char * getRegisterName(MCRegister Reg)
static const RISCVMCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx)
@ VK_RISCV_TLSDESC_ADD_LO
@ VK_RISCV_TLSDESC_LOAD_LO
static VariantKind getVariantKindForName(StringRef name)
Wrapper class representing virtual and physical registers.
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
Represents a range in source code.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class wraps a string in an Error.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
char back() const
back - Get the last character in the string.
A switch()-like statement whose cases are string literals.
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
#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.
std::optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)
ABI computeTargetABI(const Triple &TT, const FeatureBitset &FeatureBits, StringRef ABIName)
const TagNameMap & getRISCVAttributeTags()
static RoundingMode stringToRoundingMode(StringRef Str)
llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseFeatureBits(bool IsRV64, const FeatureBitset &FeatureBits)
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 bool isValidLMUL(unsigned LMUL, bool Fractional)
static RISCVII::VLMUL encodeLMUL(unsigned LMUL, bool Fractional)
static bool isValidSEW(unsigned SEW)
void printVType(unsigned VType, raw_ostream &OS)
unsigned encodeVTYPE(RISCVII::VLMUL VLMUL, unsigned SEW, bool TailAgnostic, bool MaskAgnostic)
unsigned encodeRlist(MCRegister EndReg, bool IsRV32E=false)
void printRlist(unsigned SlistEncode, raw_ostream &OS)
static bool getSpimm(unsigned RlistVal, unsigned &SpimmVal, int64_t StackAdjustment, bool IsRV64)
@ CE
Windows NT (Windows on ARM)
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Target & getTheRISCV32Target()
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
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()
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.
const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures]
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
Used to provide key value pairs for feature and CPU bit flags.