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 {
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 isUImm11()
const {
return IsUImm<11>(); }
721 bool isUImm16()
const {
return IsUImm<16>(); }
722 bool isUImm20()
const {
return IsUImm<20>(); }
723 bool isUImm32()
const {
return IsUImm<32>(); }
724 bool isUImm48()
const {
return IsUImm<48>(); }
725 bool isUImm64()
const {
return IsUImm<64>(); }
727 bool isUImm5NonZero()
const {
732 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
733 return IsConstantImm && isUInt<5>(Imm) && (
Imm != 0) &&
737 bool isUImm8GE32()
const {
742 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
743 return IsConstantImm && isUInt<8>(Imm) &&
Imm >= 32 &&
747 bool isRnumArg()
const {
752 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
753 return IsConstantImm &&
Imm >= INT64_C(0) &&
Imm <= INT64_C(10) &&
757 bool isRnumArg_0_7()
const {
762 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
763 return IsConstantImm &&
Imm >= INT64_C(0) &&
Imm <= INT64_C(7) &&
767 bool isRnumArg_1_10()
const {
772 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
773 return IsConstantImm &&
Imm >= INT64_C(1) &&
Imm <= INT64_C(10) &&
777 bool isRnumArg_2_14()
const {
782 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
783 return IsConstantImm &&
Imm >= INT64_C(2) &&
Imm <= INT64_C(14) &&
787 bool isSImm5()
const {
792 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
793 return IsConstantImm && isInt<5>(fixImmediateForRV32(Imm, isRV64Imm())) &&
797 bool isSImm6()
const {
802 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
803 return IsConstantImm && isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) &&
807 bool isSImm6NonZero()
const {
812 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
813 return IsConstantImm &&
Imm != 0 &&
814 isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) &&
818 bool isCLUIImm()
const {
823 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
824 return IsConstantImm && (
Imm != 0) &&
825 (isUInt<5>(Imm) || (
Imm >= 0xfffe0 &&
Imm <= 0xfffff)) &&
829 bool isUImm2Lsb0()
const {
834 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
835 return IsConstantImm && isShiftedUInt<1, 1>(Imm) &&
839 bool isUImm5Lsb0()
const {
844 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
845 return IsConstantImm && isShiftedUInt<4, 1>(Imm) &&
849 bool isUImm6Lsb0()
const {
854 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
855 return IsConstantImm && isShiftedUInt<5, 1>(Imm) &&
859 bool isUImm7Lsb00()
const {
864 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
865 return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
869 bool isUImm8Lsb00()
const {
874 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
875 return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
879 bool isUImm8Lsb000()
const {
884 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
885 return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
889 bool isSImm9Lsb0()
const {
return isBareSimmNLsb0<9>(); }
891 bool isUImm9Lsb000()
const {
896 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
897 return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
901 bool isUImm10Lsb00NonZero()
const {
906 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
907 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (
Imm != 0) &&
913 static int64_t fixImmediateForRV32(int64_t Imm,
bool IsRV64Imm) {
914 if (IsRV64Imm || !isUInt<32>(Imm))
916 return SignExtend64<32>(Imm);
919 bool isSImm12()
const {
925 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
927 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
929 IsValid = isInt<12>(fixImmediateForRV32(Imm, isRV64Imm()));
938 bool isSImm12Lsb0()
const {
return isBareSimmNLsb0<12>(); }
940 bool isSImm12Lsb00000()
const {
945 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
946 return IsConstantImm &&
947 isShiftedInt<7, 5>(fixImmediateForRV32(Imm, isRV64Imm())) &&
951 bool isSImm13Lsb0()
const {
return isBareSimmNLsb0<13>(); }
953 bool isSImm10Lsb0000NonZero()
const {
958 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
959 return IsConstantImm && (
Imm != 0) &&
960 isShiftedInt<6, 4>(fixImmediateForRV32(Imm, isRV64Imm())) &&
964 bool isUImm20LUI()
const {
970 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
971 if (!IsConstantImm) {
972 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
982 bool isUImm20AUIPC()
const {
988 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
989 if (!IsConstantImm) {
990 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
1006 bool isSImm21Lsb0JAL()
const {
return isBareSimmNLsb0<21>(); }
1008 bool isImmZero()
const {
1013 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
1017 bool isSImm5Plus1()
const {
1022 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
1023 return IsConstantImm &&
1024 isInt<5>(fixImmediateForRV32(Imm, isRV64Imm()) - 1) &&
1029 SMLoc getStartLoc()
const override {
return StartLoc; }
1031 SMLoc getEndLoc()
const override {
return EndLoc; }
1033 bool isRV64Imm()
const {
1034 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
1039 assert(Kind == KindTy::Register &&
"Invalid type access!");
1044 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
1045 return StringRef(SysReg.Data, SysReg.Length);
1048 const MCExpr *getImm()
const {
1049 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
1054 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1059 assert(Kind == KindTy::Token &&
"Invalid type access!");
1063 unsigned getVType()
const {
1064 assert(Kind == KindTy::VType &&
"Invalid type access!");
1069 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1073 unsigned getFence()
const {
1074 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1087 case KindTy::Immediate:
1090 case KindTy::FPImmediate:
1092 case KindTy::Register:
1096 OS <<
"'" << getToken() <<
"'";
1098 case KindTy::SystemRegister:
1099 OS <<
"<sysreg: " << getSysReg() <<
'>';
1108 roundingModeToString(getFRM());
1126 case KindTy::RegReg:
1133 static std::unique_ptr<RISCVOperand> createToken(
StringRef Str,
SMLoc S) {
1134 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1141 static std::unique_ptr<RISCVOperand>
1143 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1144 Op->Reg.RegNum =
Reg.id();
1145 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1151 static std::unique_ptr<RISCVOperand> createImm(
const MCExpr *Val,
SMLoc S,
1153 auto Op = std::make_unique<RISCVOperand>(KindTy::Immediate);
1155 Op->Imm.IsRV64 = IsRV64;
1161 static std::unique_ptr<RISCVOperand> createFPImm(
uint64_t Val,
SMLoc S) {
1162 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1163 Op->FPImm.Val = Val;
1169 static std::unique_ptr<RISCVOperand> createSysReg(
StringRef Str,
SMLoc S,
1170 unsigned Encoding) {
1171 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1172 Op->SysReg.Data = Str.data();
1173 Op->SysReg.Length = Str.size();
1180 static std::unique_ptr<RISCVOperand>
1182 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1189 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val,
SMLoc S) {
1190 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1191 Op->Fence.Val = Val;
1197 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI,
SMLoc S) {
1198 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1199 Op->VType.Val = VTypeI;
1205 static std::unique_ptr<RISCVOperand> createRlist(
unsigned RlistEncode,
1207 auto Op = std::make_unique<RISCVOperand>(KindTy::Rlist);
1208 Op->Rlist.Val = RlistEncode;
1213 static std::unique_ptr<RISCVOperand> createRegReg(
MCRegister Reg1,
1215 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1216 Op->RegReg.Reg1 = Reg1.
id();
1217 Op->RegReg.Reg2 = Reg2.
id();
1223 static std::unique_ptr<RISCVOperand> createSpimm(
unsigned Spimm,
SMLoc S) {
1224 auto Op = std::make_unique<RISCVOperand>(KindTy::Spimm);
1225 Op->Spimm.Val = Spimm;
1230 static void addExpr(
MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1231 assert(Expr &&
"Expr shouldn't be null!");
1234 bool IsConstant = evaluateConstantImm(Expr, Imm, VK);
1244 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1245 assert(
N == 1 &&
"Invalid number of operands!");
1249 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1250 assert(
N == 1 &&
"Invalid number of operands!");
1251 addExpr(Inst, getImm(), isRV64Imm());
1254 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
1255 assert(
N == 1 &&
"Invalid number of operands!");
1257 addExpr(Inst, getImm(), isRV64Imm());
1262 APFloat(APFloat::IEEEdouble(),
APInt(64, getFPConst())));
1266 void addFenceArgOperands(
MCInst &Inst,
unsigned N)
const {
1267 assert(
N == 1 &&
"Invalid number of operands!");
1271 void addCSRSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
1272 assert(
N == 1 &&
"Invalid number of operands!");
1279 void addVTypeIOperands(
MCInst &Inst,
unsigned N)
const {
1280 assert(
N == 1 &&
"Invalid number of operands!");
1282 if (Kind == KindTy::Immediate) {
1284 [[maybe_unused]]
bool IsConstantImm =
1285 evaluateConstantImm(getImm(), Imm, VK);
1286 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1293 void addRlistOperands(
MCInst &Inst,
unsigned N)
const {
1294 assert(
N == 1 &&
"Invalid number of operands!");
1298 void addRegRegOperands(
MCInst &Inst,
unsigned N)
const {
1299 assert(
N == 2 &&
"Invalid number of operands!");
1304 void addSpimmOperands(
MCInst &Inst,
unsigned N)
const {
1305 assert(
N == 1 &&
"Invalid number of operands!");
1309 void addFRMArgOperands(
MCInst &Inst,
unsigned N)
const {
1310 assert(
N == 1 &&
"Invalid number of operands!");
1316#define GET_REGISTER_MATCHER
1317#define GET_SUBTARGET_FEATURE_NAME
1318#define GET_MATCHER_IMPLEMENTATION
1319#define GET_MNEMONIC_SPELL_CHECKER
1320#include "RISCVGenAsmMatcher.inc"
1323 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1324 return Reg - RISCV::F0_D + RISCV::F0_H;
1328 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1329 return Reg - RISCV::F0_D + RISCV::F0_F;
1334 unsigned RegClassID;
1335 if (Kind == MCK_VRM2)
1336 RegClassID = RISCV::VRM2RegClassID;
1337 else if (Kind == MCK_VRM4)
1338 RegClassID = RISCV::VRM4RegClassID;
1339 else if (Kind == MCK_VRM8)
1340 RegClassID = RISCV::VRM8RegClassID;
1344 &RISCVMCRegisterClasses[RegClassID]);
1349 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1351 return Match_InvalidOperand;
1355 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg);
1357 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg);
1358 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg);
1362 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1363 (IsRegFPR64C &&
Kind == MCK_FPR32C)) {
1365 return Match_Success;
1369 if (IsRegFPR64 && Kind == MCK_FPR16) {
1371 return Match_Success;
1373 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1374 Op.Reg.RegNum =
Reg - RISCV::X0 + RISCV::X0_H;
1375 return Match_Success;
1377 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1378 Op.Reg.RegNum =
Reg - RISCV::X0 + RISCV::X0_W;
1379 return Match_Success;
1386 if (RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg) &&
1387 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1389 return Match_Success;
1393 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1396 return Match_InvalidOperand;
1397 return Match_Success;
1399 return Match_InvalidOperand;
1402bool RISCVAsmParser::generateImmOutOfRangeError(
1404 const Twine &Msg =
"immediate must be an integer in the range") {
1408bool RISCVAsmParser::generateImmOutOfRangeError(
1410 const Twine &Msg =
"immediate must be an integer in the range") {
1412 return generateImmOutOfRangeError(ErrorLoc,
Lower,
Upper, Msg);
1415bool RISCVAsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1419 bool MatchingInlineAsm) {
1429 if (validateInstruction(Inst,
Operands))
1431 return processInstruction(Inst, IDLoc,
Operands, Out);
1432 case Match_MissingFeature: {
1433 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1434 bool FirstFeature =
true;
1435 std::string Msg =
"instruction requires the following:";
1436 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1437 if (MissingFeatures[i]) {
1438 Msg += FirstFeature ?
" " :
", ";
1440 FirstFeature =
false;
1443 return Error(IDLoc, Msg);
1445 case Match_MnemonicFail: {
1446 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1447 std::string Suggestion = RISCVMnemonicSpellCheck(
1448 ((RISCVOperand &)*
Operands[0]).getToken(), FBS, 0);
1449 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1451 case Match_InvalidOperand: {
1452 SMLoc ErrorLoc = IDLoc;
1455 return Error(ErrorLoc,
"too few operands for instruction");
1458 if (ErrorLoc ==
SMLoc())
1461 return Error(ErrorLoc,
"invalid operand for instruction");
1468 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1469 SMLoc ErrorLoc = IDLoc;
1471 return Error(ErrorLoc,
"too few operands for instruction");
1477 case Match_InvalidImmXLenLI:
1480 return Error(ErrorLoc,
"operand must be a constant 64-bit integer");
1483 std::numeric_limits<int32_t>::min(),
1484 std::numeric_limits<uint32_t>::max());
1485 case Match_InvalidImmXLenLI_Restricted:
1488 return Error(ErrorLoc,
"operand either must be a constant 64-bit integer "
1489 "or a bare symbol name");
1491 return generateImmOutOfRangeError(
1493 std::numeric_limits<uint32_t>::max(),
1494 "operand either must be a bare symbol name or an immediate integer in "
1496 case Match_InvalidImmZero: {
1498 return Error(ErrorLoc,
"immediate must be zero");
1500 case Match_InvalidUImmLog2XLen:
1504 case Match_InvalidUImmLog2XLenNonZero:
1508 case Match_InvalidUImm1:
1510 case Match_InvalidUImm2:
1512 case Match_InvalidUImm2Lsb0:
1514 "immediate must be one of");
1515 case Match_InvalidUImm3:
1517 case Match_InvalidUImm4:
1519 case Match_InvalidUImm5:
1521 case Match_InvalidUImm5NonZero:
1523 case Match_InvalidUImm6:
1525 case Match_InvalidUImm7:
1527 case Match_InvalidUImm8:
1529 case Match_InvalidUImm8GE32:
1531 case Match_InvalidSImm5:
1534 case Match_InvalidSImm6:
1537 case Match_InvalidSImm6NonZero:
1538 return generateImmOutOfRangeError(
1540 "immediate must be non-zero in the range");
1541 case Match_InvalidCLUIImm:
1542 return generateImmOutOfRangeError(
1544 "immediate must be in [0xfffe0, 0xfffff] or");
1545 case Match_InvalidUImm5Lsb0:
1546 return generateImmOutOfRangeError(
1548 "immediate must be a multiple of 2 bytes in the range");
1549 case Match_InvalidUImm6Lsb0:
1550 return generateImmOutOfRangeError(
1552 "immediate must be a multiple of 2 bytes in the range");
1553 case Match_InvalidUImm7Lsb00:
1554 return generateImmOutOfRangeError(
1556 "immediate must be a multiple of 4 bytes in the range");
1557 case Match_InvalidUImm8Lsb00:
1558 return generateImmOutOfRangeError(
1560 "immediate must be a multiple of 4 bytes in the range");
1561 case Match_InvalidUImm8Lsb000:
1562 return generateImmOutOfRangeError(
1564 "immediate must be a multiple of 8 bytes in the range");
1565 case Match_InvalidSImm9Lsb0:
1566 return generateImmOutOfRangeError(
1568 "immediate must be a multiple of 2 bytes in the range");
1569 case Match_InvalidUImm9Lsb000:
1570 return generateImmOutOfRangeError(
1572 "immediate must be a multiple of 8 bytes in the range");
1573 case Match_InvalidUImm10Lsb00NonZero:
1574 return generateImmOutOfRangeError(
1576 "immediate must be a multiple of 4 bytes in the range");
1577 case Match_InvalidSImm10Lsb0000NonZero:
1578 return generateImmOutOfRangeError(
1580 "immediate must be a multiple of 16 bytes and non-zero in the range");
1581 case Match_InvalidUImm11:
1583 case Match_InvalidSImm12:
1584 return generateImmOutOfRangeError(
1586 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an "
1587 "integer in the range");
1588 case Match_InvalidSImm12Lsb0:
1589 return generateImmOutOfRangeError(
1591 "immediate must be a multiple of 2 bytes in the range");
1592 case Match_InvalidSImm12Lsb00000:
1593 return generateImmOutOfRangeError(
1595 "immediate must be a multiple of 32 bytes in the range");
1596 case Match_InvalidSImm13Lsb0:
1597 return generateImmOutOfRangeError(
1599 "immediate must be a multiple of 2 bytes in the range");
1600 case Match_InvalidUImm20LUI:
1602 "operand must be a symbol with "
1603 "%hi/%tprel_hi modifier or an integer in "
1605 case Match_InvalidUImm20:
1607 case Match_InvalidUImm20AUIPC:
1608 return generateImmOutOfRangeError(
1610 "operand must be a symbol with a "
1611 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
1612 "an integer in the range");
1613 case Match_InvalidSImm21Lsb0JAL:
1614 return generateImmOutOfRangeError(
1616 "immediate must be a multiple of 2 bytes in the range");
1617 case Match_InvalidCSRSystemRegister: {
1619 "operand must be a valid system register "
1620 "name or an integer in the range");
1622 case Match_InvalidLoadFPImm: {
1624 return Error(ErrorLoc,
"operand must be a valid floating-point constant");
1626 case Match_InvalidBareSymbol: {
1628 return Error(ErrorLoc,
"operand must be a bare symbol name");
1630 case Match_InvalidPseudoJumpSymbol: {
1632 return Error(ErrorLoc,
"operand must be a valid jump target");
1634 case Match_InvalidCallSymbol: {
1636 return Error(ErrorLoc,
"operand must be a bare symbol name");
1638 case Match_InvalidTPRelAddSymbol: {
1640 return Error(ErrorLoc,
"operand must be a symbol with %tprel_add modifier");
1642 case Match_InvalidTLSDESCCallSymbol: {
1644 return Error(ErrorLoc,
1645 "operand must be a symbol with %tlsdesc_call modifier");
1647 case Match_InvalidRTZArg: {
1649 return Error(ErrorLoc,
"operand must be 'rtz' floating-point rounding mode");
1651 case Match_InvalidVTypeI: {
1653 return generateVTypeError(ErrorLoc);
1655 case Match_InvalidVMaskRegister: {
1657 return Error(ErrorLoc,
"operand must be v0.t");
1659 case Match_InvalidSImm5Plus1: {
1662 "immediate must be in the range");
1664 case Match_InvalidRlist: {
1668 "operand must be {ra [, s0[-sN]]} or {x1 [, x8[-x9][, x18[-xN]]]}");
1670 case Match_InvalidStackAdj: {
1674 "stack adjustment is invalid for this instruction and register list; "
1675 "refer to Zc spec for a detailed range of stack adjustment");
1677 case Match_InvalidRnumArg: {
1680 case Match_InvalidRegReg: {
1682 return Error(ErrorLoc,
"operands must be register and register");
1700 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1701 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1704 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1711 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1712 return Error(StartLoc,
"invalid register name");
1718 const AsmToken &Tok = getParser().getTok();
1733 SMLoc FirstS = getLoc();
1734 bool HadParens =
false;
1741 size_t ReadCount = getLexer().peekTokens(Buf);
1744 LParen = getParser().getTok();
1749 switch (getLexer().getKind()) {
1752 getLexer().UnLex(LParen);
1760 getLexer().UnLex(LParen);
1764 Operands.push_back(RISCVOperand::createToken(
"(", FirstS));
1768 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
1773 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
1784 switch (getLexer().getKind()) {
1794 if (getParser().parseExpression(Res,
E))
1797 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1799 int64_t
Imm =
CE->getValue();
1800 if (isUInt<7>(Imm)) {
1801 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1810 if (getParser().parseIdentifier(Identifier))
1813 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1815 assert(isUInt<7>(Opcode->Value) && (Opcode->Value & 0x3) == 3 &&
1816 "Unexpected opcode");
1819 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1829 return generateImmOutOfRangeError(
1831 "opcode must be a valid opcode name or an immediate in the range");
1839 switch (getLexer().getKind()) {
1849 if (getParser().parseExpression(Res,
E))
1852 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1854 int64_t
Imm =
CE->getValue();
1855 if (Imm >= 0 && Imm <= 2) {
1856 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1865 if (getParser().parseIdentifier(Identifier))
1869 if (Identifier ==
"C0")
1871 else if (Identifier ==
"C1")
1873 else if (Identifier ==
"C2")
1880 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1889 return generateImmOutOfRangeError(
1891 "opcode must be a valid opcode name or an immediate in the range");
1898 auto SysRegFromConstantInt = [
this](
const MCExpr *
E,
SMLoc S) {
1899 if (
auto *CE = dyn_cast<MCConstantExpr>(
E)) {
1900 int64_t
Imm =
CE->getValue();
1901 if (isUInt<12>(Imm)) {
1902 auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
1907 return RISCVOperand::createSysReg(
Reg.Name, S, Imm);
1911 return RISCVOperand::createSysReg(
"", S, Imm);
1914 return std::unique_ptr<RISCVOperand>();
1917 switch (getLexer().getKind()) {
1927 if (getParser().parseExpression(Res))
1930 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
1931 Operands.push_back(std::move(SysOpnd));
1935 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1939 if (getParser().parseIdentifier(Identifier))
1942 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1944 SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier);
1946 if ((SysReg = RISCVSysReg::lookupSysRegByDeprecatedName(Identifier)))
1947 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
1948 SysReg->Name +
"'");
1952 const auto &FeatureBits = getSTI().getFeatureBits();
1953 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
1955 return SysReg->FeaturesRequired[Feature.Value];
1957 auto ErrorMsg = std::string(
"system register '") + SysReg->Name +
"' ";
1958 if (SysReg->isRV32Only && FeatureBits[RISCV::Feature64Bit]) {
1959 ErrorMsg +=
"is RV32 only";
1961 ErrorMsg +=
" and ";
1965 "requires '" + std::string(Feature->Key) +
"' to be enabled";
1968 return Error(S, ErrorMsg);
1971 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
1976 MCSymbol *
Sym = getContext().lookupSymbol(Identifier);
1977 if (
Sym &&
Sym->isVariable()) {
1980 if (
auto SysOpnd = SysRegFromConstantInt(
1981 Sym->getVariableValue(
false), S)) {
1982 Operands.push_back(std::move(SysOpnd));
1987 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
1988 "operand must be a valid system register "
1989 "name or an integer in the range");
1993 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2006 if (
Identifier.compare_insensitive(
"inf") == 0) {
2009 getTok().getEndLoc(), isRV64()));
2010 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2013 getTok().getEndLoc(), isRV64()));
2014 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2017 getTok().getEndLoc(), isRV64()));
2019 return TokError(
"invalid floating point literal");
2032 return TokError(
"invalid floating point immediate");
2035 APFloat RealVal(APFloat::IEEEdouble());
2037 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2039 return TokError(
"invalid floating point representation");
2042 RealVal.changeSign();
2044 Operands.push_back(RISCVOperand::createFPImm(
2045 RealVal.bitcastToAPInt().getZExtValue(), S));
2057 switch (getLexer().getKind()) {
2069 if (getParser().parseExpression(Res,
E))
2073 return parseOperandWithModifier(
Operands);
2076 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2088 return Error(getLoc(),
"expected valid identifier for operand modifier");
2092 return Error(getLoc(),
"unrecognized operand modifier");
2099 if (getParser().parseParenExpression(SubExpr,
E))
2103 Operands.push_back(RISCVOperand::createImm(ModExpr, S,
E, isRV64()));
2115 AsmToken Tok = getLexer().getTok();
2117 if (getParser().parseIdentifier(Identifier))
2123 return Error(getLoc(),
"'@plt' operand not valid for instruction");
2125 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
2127 if (
Sym->isVariable()) {
2128 const MCExpr *
V =
Sym->getVariableValue(
false);
2129 if (!isa<MCSymbolRefExpr>(V)) {
2130 getLexer().UnLex(Tok);
2138 switch (getLexer().getKind()) {
2140 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2153 if (getParser().parseExpression(Expr,
E))
2156 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2172 if (getParser().parseIdentifier(Identifier))
2180 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
2183 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2192 if (getParser().parseExpression(Res,
E))
2195 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef ||
2196 cast<MCSymbolRefExpr>(Res)->getKind() ==
2197 MCSymbolRefExpr::VariantKind::VK_PLT)
2198 return Error(S,
"operand must be a valid jump target");
2201 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2222bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2223 unsigned &Sew,
unsigned &Lmul,
2224 bool &Fractional,
bool &TailAgnostic,
2225 bool &MaskAgnostic) {
2232 case VTypeState_SEW:
2239 State = VTypeState_LMUL;
2241 case VTypeState_LMUL: {
2251 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2252 unsigned MinLMUL = ELEN / 8;
2255 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2256 Twine(MinLMUL) +
" is reserved");
2259 State = VTypeState_TailPolicy;
2262 case VTypeState_TailPolicy:
2263 if (Identifier ==
"ta")
2264 TailAgnostic =
true;
2265 else if (Identifier ==
"tu")
2266 TailAgnostic =
false;
2269 State = VTypeState_MaskPolicy;
2271 case VTypeState_MaskPolicy:
2272 if (Identifier ==
"ma")
2273 MaskAgnostic =
true;
2274 else if (Identifier ==
"mu")
2275 MaskAgnostic =
false;
2278 State = VTypeState_Done;
2280 case VTypeState_Done:
2293 bool Fractional =
false;
2294 bool TailAgnostic =
false;
2295 bool MaskAgnostic =
false;
2297 VTypeState State = VTypeState_SEW;
2300 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2307 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2317 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2318 unsigned MaxSEW = ELEN / Lmul;
2320 if (MaxSEW >= 8 && Sew > MaxSEW)
2322 "use of vtype encodings with SEW > " +
Twine(MaxSEW) +
2323 " and LMUL == mf" +
Twine(Lmul) +
2324 " may not be compatible with all RVV implementations");
2329 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2333 return generateVTypeError(S);
2336bool RISCVAsmParser::generateVTypeError(
SMLoc ErrorLoc) {
2340 "e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2348 if (!
Name.consume_back(
".t"))
2349 return Error(getLoc(),
"expected '.t' suffix");
2354 if (
Reg != RISCV::V0)
2359 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2364 if (!isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2382 Operands.push_back(RISCVOperand::createReg(
2383 Reg, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2388 if (isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2400 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2403 if ((
Reg - RISCV::X0) & 1) {
2406 if (getSTI().hasFeature(RISCV::FeatureStdExtZfinx))
2407 return TokError(
"double precision floating point operands must use even "
2408 "numbered X register");
2418 Reg, RISCV::sub_gpr_even,
2419 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2420 Operands.push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2424template <
bool IsRV64>
2426 return parseGPRPair(
Operands, IsRV64);
2436 if (!IsRV64Inst && isRV64())
2448 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2451 if ((
Reg - RISCV::X0) & 1)
2452 return TokError(
"register must be even");
2460 Reg, RISCV::sub_gpr_even,
2461 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2462 Operands.push_back(RISCVOperand::createReg(Pair, S,
E));
2469 "operand must be a valid floating point rounding mode mnemonic");
2471 StringRef Str = getLexer().getTok().getIdentifier();
2476 "operand must be a valid floating point rounding mode mnemonic");
2478 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2484 const AsmToken &Tok = getLexer().getTok();
2490 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2504 for (
char c : Str) {
2533 Operands.push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2539 return TokError(
"operand must be formed of letters selected in-order from "
2546 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
2548 if (!parseRegister(
Operands).isSuccess())
2549 return Error(getLoc(),
"expected register");
2553 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2577 std::unique_ptr<RISCVOperand> OptionalImmOp;
2584 SMLoc ImmStart = getLoc();
2585 if (getParser().parseIntToken(ImmVal,
2586 "expected '(' or optional integer offset"))
2591 SMLoc ImmEnd = getLoc();
2594 ImmStart, ImmEnd, isRV64());
2598 OptionalImmOp ?
"expected '(' after optional integer offset"
2599 :
"expected '(' or optional integer offset"))
2602 if (!parseRegister(
Operands).isSuccess())
2603 return Error(getLoc(),
"expected register");
2609 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2611 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2612 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2625 return Error(getLoc(),
"invalid register");
2632 return Error(getLoc(),
"expected register");
2634 StringRef Reg2Name = getLexer().getTok().getIdentifier();
2637 return Error(getLoc(),
"invalid register");
2643 Operands.push_back(RISCVOperand::createRegReg(
Reg, Reg2, getLoc()));
2656 bool IsEABI = isRVE();
2659 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2664 if (RegStart != RISCV::X1)
2665 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2671 return Error(getLoc(),
"invalid register");
2675 return Error(getLoc(),
"invalid register");
2676 if (RegStart != RISCV::X8)
2677 return Error(getLoc(),
2678 "continuous register list must start from 's0' or 'x8'");
2684 StringRef EndName = getLexer().getTok().getIdentifier();
2688 return Error(getLoc(),
"invalid register");
2689 if (IsEABI && RegEnd != RISCV::X9)
2690 return Error(getLoc(),
"contiguous register list of EABI can only be "
2691 "'s0-s1' or 'x8-x9' pair");
2698 if (RegEnd != RISCV::X9)
2701 "first contiguous registers pair of register list must be 'x8-x9'");
2705 return Error(getLoc(),
"invalid register");
2706 StringRef EndName = getLexer().getTok().getIdentifier();
2708 return Error(getLoc(),
2709 "second contiguous registers pair of register list "
2710 "must start from 'x18'");
2716 return Error(getLoc(),
"invalid register");
2717 EndName = getLexer().getTok().getIdentifier();
2719 return Error(getLoc(),
"invalid register");
2726 if (RegEnd == RISCV::X26)
2727 return Error(getLoc(),
"invalid register list, {ra, s0-s10} or {x1, x8-x9, "
2728 "x18-x26} is not supported");
2738 return Error(S,
"invalid register list");
2739 Operands.push_back(RISCVOperand::createRlist(Encode, S));
2745 bool ExpectNegative) {
2751 unsigned RlistVal =
static_cast<RISCVOperand *
>(
Operands[1].get())->Rlist.Val;
2753 if (Negative != ExpectNegative ||
2756 Operands.push_back(RISCVOperand::createSpimm(Spimm << 4, S));
2768 MatchOperandParserImpl(
Operands, Mnemonic,
true);
2775 if (parseRegister(
Operands,
true).isSuccess())
2782 return !parseMemOpBaseReg(
Operands).isSuccess();
2787 Error(getLoc(),
"unknown operand");
2800 if (getSTI().hasFeature(RISCV::FeatureRelax)) {
2801 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
2802 if (Assembler !=
nullptr) {
2810 Operands.push_back(RISCVOperand::createToken(
Name, NameLoc));
2829 if (getParser().parseEOL(
"unexpected token")) {
2830 getParser().eatToEndOfStatement();
2836bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
2840 if (
const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
2841 Kind = RE->getKind();
2842 Expr = RE->getSubExpr();
2852bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
2865 if (IDVal ==
".option")
2866 return parseDirectiveOption();
2867 if (IDVal ==
".attribute")
2868 return parseDirectiveAttribute();
2869 if (IDVal ==
".insn")
2870 return parseDirectiveInsn(DirectiveID.
getLoc());
2871 if (IDVal ==
".variant_cc")
2872 return parseDirectiveVariantCC();
2877bool RISCVAsmParser::resetToArch(
StringRef Arch,
SMLoc Loc, std::string &Result,
2878 bool FromOptionDirective) {
2881 clearFeatureBits(Feature.Value, Feature.Key);
2890 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
2891 << ErrMsg.getMessage();
2894 return Error(Loc, OutputErrMsg.str());
2899 if (ISAInfo->hasExtension(Feature.Key))
2900 setFeatureBits(Feature.Value, Feature.Key);
2902 if (FromOptionDirective) {
2903 if (ISAInfo->getXLen() == 32 && isRV64())
2904 return Error(Loc,
"bad arch string switching from rv64 to rv32");
2905 else if (ISAInfo->getXLen() == 64 && !isRV64())
2906 return Error(Loc,
"bad arch string switching from rv32 to rv64");
2909 if (ISAInfo->getXLen() == 32)
2910 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
2911 else if (ISAInfo->getXLen() == 64)
2912 setFeatureBits(RISCV::Feature64Bit,
"64bit");
2914 return Error(Loc,
"bad arch string " + Arch);
2916 Result = ISAInfo->toString();
2920bool RISCVAsmParser::parseDirectiveOption() {
2931 if (Option ==
"push") {
2935 getTargetStreamer().emitDirectiveOptionPush();
2940 if (Option ==
"pop") {
2945 getTargetStreamer().emitDirectiveOptionPop();
2946 if (popFeatureBits())
2947 return Error(StartLoc,
".option pop with no .option push");
2952 if (Option ==
"arch") {
2960 Type = RISCVOptionArchArgType::Plus;
2962 Type = RISCVOptionArchArgType::Minus;
2963 else if (!
Args.empty())
2965 "unexpected token, expected + or -");
2967 Type = RISCVOptionArchArgType::Full;
2971 "unexpected token, expected identifier");
2977 if (
Type == RISCVOptionArchArgType::Full) {
2979 if (resetToArch(Arch, Loc, Result,
true))
2988 Loc,
"extension version number parsing not currently implemented");
2991 if (!enableExperimentalExtension() &&
2993 return Error(Loc,
"unexpected experimental extensions");
2996 return Error(Loc,
"unknown extension feature");
3000 if (
Type == RISCVOptionArchArgType::Plus) {
3003 setFeatureBits(
Ext->Value,
Ext->Key);
3006 copySTI().setFeatureBits(OldFeatureBits);
3007 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3012 OutputErrMsg << ErrMsg.getMessage();
3015 return Error(Loc, OutputErrMsg.str());
3018 assert(
Type == RISCVOptionArchArgType::Minus);
3023 if (getSTI().hasFeature(Feature.Value) &&
3024 Feature.Implies.test(
Ext->Value))
3026 " extension; " + Feature.Key +
3027 " extension requires " +
Ext->Key +
3031 clearFeatureBits(
Ext->Value,
Ext->Key);
3038 getTargetStreamer().emitDirectiveOptionArch(Args);
3042 if (Option ==
"rvc") {
3046 getTargetStreamer().emitDirectiveOptionRVC();
3047 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3051 if (Option ==
"norvc") {
3055 getTargetStreamer().emitDirectiveOptionNoRVC();
3056 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3057 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3061 if (Option ==
"pic") {
3065 getTargetStreamer().emitDirectiveOptionPIC();
3066 ParserOptions.IsPicEnabled =
true;
3070 if (Option ==
"nopic") {
3074 getTargetStreamer().emitDirectiveOptionNoPIC();
3075 ParserOptions.IsPicEnabled =
false;
3079 if (Option ==
"relax") {
3083 getTargetStreamer().emitDirectiveOptionRelax();
3084 setFeatureBits(RISCV::FeatureRelax,
"relax");
3088 if (Option ==
"norelax") {
3092 getTargetStreamer().emitDirectiveOptionNoRelax();
3093 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3099 "'rvc', 'norvc', 'arch', 'relax' or "
3108bool RISCVAsmParser::parseDirectiveAttribute() {
3115 std::optional<unsigned>
Ret =
3118 return Error(TagLoc,
"attribute name not recognised: " +
Name);
3129 if (check(!CE, TagLoc,
"expected numeric constant"))
3132 Tag =
CE->getValue();
3139 int64_t IntegerValue = 0;
3140 bool IsIntegerValue =
true;
3145 IsIntegerValue =
false;
3148 if (IsIntegerValue) {
3155 return Error(ValueExprLoc,
"expected numeric constant");
3156 IntegerValue =
CE->getValue();
3169 getTargetStreamer().emitAttribute(Tag, IntegerValue);
3171 getTargetStreamer().emitTextAttribute(Tag, StringValue);
3174 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3178 getTargetStreamer().emitTextAttribute(Tag, Result);
3186 .
Cases(
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s",
true)
3187 .
Cases(
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj", AllowC)
3195bool RISCVAsmParser::parseDirectiveInsn(
SMLoc L) {
3198 bool AllowC = getSTI().hasFeature(RISCV::FeatureStdExtC) ||
3199 getSTI().hasFeature(RISCV::FeatureStdExtZca);
3206 std::optional<int64_t>
Length;
3216 return Error(ErrorLoc,
3217 "instruction lengths must be a non-zero multiple of two");
3221 return Error(ErrorLoc,
3222 "instruction lengths over 64 bits are not supported");
3228 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3233 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3234 return Error(ErrorLoc,
3235 "instruction length does not match the encoding");
3238 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3241 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3244 if (!AllowC && (EncodingDerivedLength == 2))
3245 return Error(ErrorLoc,
"compressed instructions are not allowed");
3247 if (getParser().parseEOL(
"invalid operand for instruction")) {
3248 getParser().eatToEndOfStatement();
3256 Opcode = RISCV::Insn16;
3259 Opcode = RISCV::Insn32;
3262 Opcode = RISCV::Insn48;
3265 Opcode = RISCV::Insn64;
3271 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3278 return Error(ErrorLoc,
"invalid instruction format");
3280 std::string FormatName = (
".insn_" +
Format).str();
3297bool RISCVAsmParser::parseDirectiveVariantCC() {
3299 if (getParser().parseIdentifier(
Name))
3300 return TokError(
"expected symbol name");
3303 getTargetStreamer().emitDirectiveVariantCC(
3304 *getContext().getOrCreateSymbol(
Name));
3312 ++RISCVNumInstrsCompressed;
3321 for (
MCInst &Inst : Seq) {
3322 emitToStreamer(Out, Inst);
3329 unsigned SecondOpcode,
SMLoc IDLoc,
3343 const MCExpr *RefToLinkTmpLabel =
3350 .addExpr(RefToLinkTmpLabel));
3353void RISCVAsmParser::emitLoadLocalAddress(
MCInst &Inst,
SMLoc IDLoc,
3364 RISCV::ADDI, IDLoc, Out);
3367void RISCVAsmParser::emitLoadGlobalAddress(
MCInst &Inst,
SMLoc IDLoc,
3377 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3379 SecondOpcode, IDLoc, Out);
3382void RISCVAsmParser::emitLoadAddress(
MCInst &Inst,
SMLoc IDLoc,
3391 if (ParserOptions.IsPicEnabled)
3392 emitLoadGlobalAddress(Inst, IDLoc, Out);
3394 emitLoadLocalAddress(Inst, IDLoc, Out);
3397void RISCVAsmParser::emitLoadTLSIEAddress(
MCInst &Inst,
SMLoc IDLoc,
3407 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3409 SecondOpcode, IDLoc, Out);
3412void RISCVAsmParser::emitLoadTLSGDAddress(
MCInst &Inst,
SMLoc IDLoc,
3423 RISCV::ADDI, IDLoc, Out);
3426void RISCVAsmParser::emitLoadStoreSymbol(
MCInst &Inst,
unsigned Opcode,
3436 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3438 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3442 Opcode, IDLoc, Out);
3445void RISCVAsmParser::emitPseudoExtend(
MCInst &Inst,
bool SignExtend,
3446 int64_t Width,
SMLoc IDLoc,
3458 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3459 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3461 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3474void RISCVAsmParser::emitVMSGE(
MCInst &Inst,
unsigned Opcode,
SMLoc IDLoc,
3498 "The destination register should not be V0.");
3517 "The destination register should be V0.");
3519 "The temporary vector register should not be V0.");
3538 "The temporary vector register should not be V0.");
3563bool RISCVAsmParser::checkPseudoAddTPRel(
MCInst &Inst,
3565 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3568 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3569 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3570 "%tprel_add modifier");
3576bool RISCVAsmParser::checkPseudoTLSDESCCall(
MCInst &Inst,
3578 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
3581 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3582 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
3583 "%tlsdesc_call modifier");
3589std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3593std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3594 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3598std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3599 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3603bool RISCVAsmParser::validateInstruction(
MCInst &Inst,
3607 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3608 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3611 if (DestReg == TempReg) {
3613 return Error(Loc,
"the temporary vector register cannot be the same as "
3614 "the destination register");
3618 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3619 Opcode == RISCV::TH_LWD) {
3624 if (Rs1 == Rd1 && Rs1 == Rd2) {
3626 return Error(Loc,
"rs1, rd1, and rd2 cannot all be the same");
3630 if (Opcode == RISCV::CM_MVSA01) {
3635 return Error(Loc,
"rs1 and rs2 must be different");
3639 bool IsTHeadMemPair32 = (Opcode == RISCV::TH_LWD ||
3640 Opcode == RISCV::TH_LWUD || Opcode == RISCV::TH_SWD);
3641 bool IsTHeadMemPair64 = (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_SDD);
3646 return Error(Loc,
"operand must be constant 3");
3649 return Error(Loc,
"operand must be constant 4");
3656 if (Opcode == RISCV::VC_V_XVW || Opcode == RISCV::VC_V_IVW ||
3657 Opcode == RISCV::VC_V_FVW || Opcode == RISCV::VC_V_VVW) {
3663 if (VCIXDst == VCIXRs1)
3664 return Error(VCIXDstLoc,
"the destination vector register group cannot"
3665 " overlap the source vector register group");
3669 if (VCIXDst == VCIXRs2)
3670 return Error(VCIXDstLoc,
"the destination vector register group cannot"
3671 " overlap the source vector register group");
3686 if (DestReg == CheckReg)
3687 return Error(Loc,
"the destination vector register group cannot overlap"
3688 " the source vector register group");
3692 if (DestReg == CheckReg)
3693 return Error(Loc,
"the destination vector register group cannot overlap"
3694 " the source vector register group");
3699 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM ||
3700 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM ||
3701 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM ||
3702 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM ||
3703 Opcode == RISCV::VMERGE_VXM)
3704 return Error(Loc,
"the destination vector register group cannot be V0");
3711 assert((CheckReg == RISCV::V0 || !CheckReg) &&
3712 "Unexpected register for mask operand");
3714 if (DestReg == CheckReg)
3715 return Error(Loc,
"the destination vector register group cannot overlap"
3716 " the mask register");
3721bool RISCVAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
3729 case RISCV::PseudoC_ADDI_NOP:
3732 case RISCV::PseudoLLAImm:
3733 case RISCV::PseudoLAImm:
3734 case RISCV::PseudoLI: {
3751 Imm = SignExtend64<32>(Imm);
3752 emitLoadImm(
Reg, Imm, Out);
3755 case RISCV::PseudoLLA:
3756 emitLoadLocalAddress(Inst, IDLoc, Out);
3758 case RISCV::PseudoLGA:
3759 emitLoadGlobalAddress(Inst, IDLoc, Out);
3761 case RISCV::PseudoLA:
3762 emitLoadAddress(Inst, IDLoc, Out);
3764 case RISCV::PseudoLA_TLS_IE:
3765 emitLoadTLSIEAddress(Inst, IDLoc, Out);
3767 case RISCV::PseudoLA_TLS_GD:
3768 emitLoadTLSGDAddress(Inst, IDLoc, Out);
3770 case RISCV::PseudoLB:
3771 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
3773 case RISCV::PseudoLBU:
3774 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
3776 case RISCV::PseudoLH:
3777 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
3779 case RISCV::PseudoLHU:
3780 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
3782 case RISCV::PseudoLW:
3783 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
3785 case RISCV::PseudoLWU:
3786 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
3788 case RISCV::PseudoLD:
3789 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
3791 case RISCV::PseudoFLH:
3792 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
3794 case RISCV::PseudoFLW:
3795 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
3797 case RISCV::PseudoFLD:
3798 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
3800 case RISCV::PseudoSB:
3801 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
3803 case RISCV::PseudoSH:
3804 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
3806 case RISCV::PseudoSW:
3807 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
3809 case RISCV::PseudoSD:
3810 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
3812 case RISCV::PseudoFSH:
3813 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
3815 case RISCV::PseudoFSW:
3816 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
3818 case RISCV::PseudoFSD:
3819 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
3821 case RISCV::PseudoAddTPRel:
3822 if (checkPseudoAddTPRel(Inst,
Operands))
3825 case RISCV::PseudoTLSDESCCall:
3826 if (checkPseudoTLSDESCCall(Inst,
Operands))
3829 case RISCV::PseudoSEXT_B:
3830 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
3832 case RISCV::PseudoSEXT_H:
3833 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
3835 case RISCV::PseudoZEXT_H:
3836 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
3838 case RISCV::PseudoZEXT_W:
3839 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
3841 case RISCV::PseudoVMSGEU_VX:
3842 case RISCV::PseudoVMSGEU_VX_M:
3843 case RISCV::PseudoVMSGEU_VX_M_T:
3844 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
3846 case RISCV::PseudoVMSGE_VX:
3847 case RISCV::PseudoVMSGE_VX_M:
3848 case RISCV::PseudoVMSGE_VX_M_T:
3849 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
3851 case RISCV::PseudoVMSGE_VI:
3852 case RISCV::PseudoVMSLT_VI: {
3856 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
3866 case RISCV::PseudoVMSGEU_VI:
3867 case RISCV::PseudoVMSLTU_VI: {
3874 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3885 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3900 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.