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 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 isUImm8Lsb00()
const {
885 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
886 return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
890 bool isUImm8Lsb000()
const {
895 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
896 return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
900 bool isSImm9Lsb0()
const {
return isBareSimmNLsb0<9>(); }
902 bool isUImm9Lsb000()
const {
907 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
908 return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
912 bool isUImm10Lsb00NonZero()
const {
917 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
918 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (
Imm != 0) &&
924 static int64_t fixImmediateForRV32(int64_t Imm,
bool IsRV64Imm) {
925 if (IsRV64Imm || !isUInt<32>(Imm))
927 return SignExtend64<32>(Imm);
930 bool isSImm12()
const {
936 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
938 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
940 IsValid = isInt<12>(fixImmediateForRV32(Imm, isRV64Imm()));
949 bool isSImm12Lsb0()
const {
return isBareSimmNLsb0<12>(); }
951 bool isSImm12Lsb00000()
const {
956 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
957 return IsConstantImm &&
958 isShiftedInt<7, 5>(fixImmediateForRV32(Imm, isRV64Imm())) &&
962 bool isSImm13Lsb0()
const {
return isBareSimmNLsb0<13>(); }
964 bool isSImm10Lsb0000NonZero()
const {
969 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
970 return IsConstantImm && (
Imm != 0) &&
971 isShiftedInt<6, 4>(fixImmediateForRV32(Imm, isRV64Imm())) &&
975 bool isUImm20LUI()
const {
981 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
982 if (!IsConstantImm) {
983 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
993 bool isUImm20AUIPC()
const {
999 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
1000 if (!IsConstantImm) {
1001 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
1017 bool isSImm21Lsb0JAL()
const {
return isBareSimmNLsb0<21>(); }
1019 bool isImmZero()
const {
1024 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
1028 bool isSImm5Plus1()
const {
1033 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
1034 return IsConstantImm &&
1035 isInt<5>(fixImmediateForRV32(Imm, isRV64Imm()) - 1) &&
1040 SMLoc getStartLoc()
const override {
return StartLoc; }
1042 SMLoc getEndLoc()
const override {
return EndLoc; }
1044 bool isRV64Imm()
const {
1045 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
1050 assert(Kind == KindTy::Register &&
"Invalid type access!");
1055 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
1056 return StringRef(SysReg.Data, SysReg.Length);
1059 const MCExpr *getImm()
const {
1060 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
1065 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1070 assert(Kind == KindTy::Token &&
"Invalid type access!");
1074 unsigned getVType()
const {
1075 assert(Kind == KindTy::VType &&
"Invalid type access!");
1080 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1084 unsigned getFence()
const {
1085 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1098 case KindTy::Immediate:
1101 case KindTy::FPImmediate:
1103 case KindTy::Register:
1107 OS <<
"'" << getToken() <<
"'";
1109 case KindTy::SystemRegister:
1110 OS <<
"<sysreg: " << getSysReg() <<
'>';
1119 roundingModeToString(getFRM());
1137 case KindTy::RegReg:
1144 static std::unique_ptr<RISCVOperand> createToken(
StringRef Str,
SMLoc S) {
1145 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1152 static std::unique_ptr<RISCVOperand>
1154 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1155 Op->Reg.RegNum =
Reg.id();
1156 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1162 static std::unique_ptr<RISCVOperand> createImm(
const MCExpr *Val,
SMLoc S,
1164 auto Op = std::make_unique<RISCVOperand>(KindTy::Immediate);
1166 Op->Imm.IsRV64 = IsRV64;
1172 static std::unique_ptr<RISCVOperand> createFPImm(
uint64_t Val,
SMLoc S) {
1173 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1174 Op->FPImm.Val = Val;
1180 static std::unique_ptr<RISCVOperand> createSysReg(
StringRef Str,
SMLoc S,
1181 unsigned Encoding) {
1182 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1183 Op->SysReg.Data = Str.data();
1184 Op->SysReg.Length = Str.size();
1191 static std::unique_ptr<RISCVOperand>
1193 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1200 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val,
SMLoc S) {
1201 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1202 Op->Fence.Val = Val;
1208 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI,
SMLoc S) {
1209 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1210 Op->VType.Val = VTypeI;
1216 static std::unique_ptr<RISCVOperand> createRlist(
unsigned RlistEncode,
1218 auto Op = std::make_unique<RISCVOperand>(KindTy::Rlist);
1219 Op->Rlist.Val = RlistEncode;
1224 static std::unique_ptr<RISCVOperand> createRegReg(
MCRegister Reg1,
1226 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1227 Op->RegReg.Reg1 = Reg1.
id();
1228 Op->RegReg.Reg2 = Reg2.
id();
1234 static std::unique_ptr<RISCVOperand> createSpimm(
unsigned Spimm,
SMLoc S) {
1235 auto Op = std::make_unique<RISCVOperand>(KindTy::Spimm);
1236 Op->Spimm.Val = Spimm;
1241 static void addExpr(
MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1242 assert(Expr &&
"Expr shouldn't be null!");
1245 bool IsConstant = evaluateConstantImm(Expr, Imm, VK);
1255 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1256 assert(
N == 1 &&
"Invalid number of operands!");
1260 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1261 assert(
N == 1 &&
"Invalid number of operands!");
1262 addExpr(Inst, getImm(), isRV64Imm());
1265 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
1266 assert(
N == 1 &&
"Invalid number of operands!");
1268 addExpr(Inst, getImm(), isRV64Imm());
1273 APFloat(APFloat::IEEEdouble(),
APInt(64, getFPConst())));
1277 void addFenceArgOperands(
MCInst &Inst,
unsigned N)
const {
1278 assert(
N == 1 &&
"Invalid number of operands!");
1282 void addCSRSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
1283 assert(
N == 1 &&
"Invalid number of operands!");
1290 void addVTypeIOperands(
MCInst &Inst,
unsigned N)
const {
1291 assert(
N == 1 &&
"Invalid number of operands!");
1293 if (Kind == KindTy::Immediate) {
1295 [[maybe_unused]]
bool IsConstantImm =
1296 evaluateConstantImm(getImm(), Imm, VK);
1297 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1304 void addRlistOperands(
MCInst &Inst,
unsigned N)
const {
1305 assert(
N == 1 &&
"Invalid number of operands!");
1309 void addRegRegOperands(
MCInst &Inst,
unsigned N)
const {
1310 assert(
N == 2 &&
"Invalid number of operands!");
1315 void addSpimmOperands(
MCInst &Inst,
unsigned N)
const {
1316 assert(
N == 1 &&
"Invalid number of operands!");
1320 void addFRMArgOperands(
MCInst &Inst,
unsigned N)
const {
1321 assert(
N == 1 &&
"Invalid number of operands!");
1327#define GET_REGISTER_MATCHER
1328#define GET_SUBTARGET_FEATURE_NAME
1329#define GET_MATCHER_IMPLEMENTATION
1330#define GET_MNEMONIC_SPELL_CHECKER
1331#include "RISCVGenAsmMatcher.inc"
1334 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1335 return Reg - RISCV::F0_D + RISCV::F0_H;
1339 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1340 return Reg - RISCV::F0_D + RISCV::F0_F;
1345 unsigned RegClassID;
1346 if (Kind == MCK_VRM2)
1347 RegClassID = RISCV::VRM2RegClassID;
1348 else if (Kind == MCK_VRM4)
1349 RegClassID = RISCV::VRM4RegClassID;
1350 else if (Kind == MCK_VRM8)
1351 RegClassID = RISCV::VRM8RegClassID;
1355 &RISCVMCRegisterClasses[RegClassID]);
1360 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1362 return Match_InvalidOperand;
1366 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg);
1368 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg);
1369 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg);
1373 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1374 (IsRegFPR64C &&
Kind == MCK_FPR32C)) {
1376 return Match_Success;
1380 if (IsRegFPR64 && Kind == MCK_FPR16) {
1382 return Match_Success;
1384 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1385 Op.Reg.RegNum =
Reg - RISCV::X0 + RISCV::X0_H;
1386 return Match_Success;
1388 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1389 Op.Reg.RegNum =
Reg - RISCV::X0 + RISCV::X0_W;
1390 return Match_Success;
1397 if (RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg) &&
1398 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1400 return Match_Success;
1404 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1407 return Match_InvalidOperand;
1408 return Match_Success;
1410 return Match_InvalidOperand;
1413bool RISCVAsmParser::generateImmOutOfRangeError(
1415 const Twine &Msg =
"immediate must be an integer in the range") {
1419bool RISCVAsmParser::generateImmOutOfRangeError(
1421 const Twine &Msg =
"immediate must be an integer in the range") {
1423 return generateImmOutOfRangeError(ErrorLoc,
Lower,
Upper, Msg);
1426bool RISCVAsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1430 bool MatchingInlineAsm) {
1440 if (validateInstruction(Inst,
Operands))
1442 return processInstruction(Inst, IDLoc,
Operands, Out);
1443 case Match_MissingFeature: {
1444 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1445 bool FirstFeature =
true;
1446 std::string Msg =
"instruction requires the following:";
1447 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1448 if (MissingFeatures[i]) {
1449 Msg += FirstFeature ?
" " :
", ";
1451 FirstFeature =
false;
1454 return Error(IDLoc, Msg);
1456 case Match_MnemonicFail: {
1457 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1458 std::string Suggestion = RISCVMnemonicSpellCheck(
1459 ((RISCVOperand &)*
Operands[0]).getToken(), FBS, 0);
1460 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1462 case Match_InvalidOperand: {
1463 SMLoc ErrorLoc = IDLoc;
1466 return Error(ErrorLoc,
"too few operands for instruction");
1469 if (ErrorLoc ==
SMLoc())
1472 return Error(ErrorLoc,
"invalid operand for instruction");
1479 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1480 SMLoc ErrorLoc = IDLoc;
1482 return Error(ErrorLoc,
"too few operands for instruction");
1488 case Match_InvalidImmXLenLI:
1491 return Error(ErrorLoc,
"operand must be a constant 64-bit integer");
1494 std::numeric_limits<int32_t>::min(),
1495 std::numeric_limits<uint32_t>::max());
1496 case Match_InvalidImmXLenLI_Restricted:
1499 return Error(ErrorLoc,
"operand either must be a constant 64-bit integer "
1500 "or a bare symbol name");
1502 return generateImmOutOfRangeError(
1504 std::numeric_limits<uint32_t>::max(),
1505 "operand either must be a bare symbol name or an immediate integer in "
1507 case Match_InvalidImmZero: {
1509 return Error(ErrorLoc,
"immediate must be zero");
1511 case Match_InvalidUImmLog2XLen:
1515 case Match_InvalidUImmLog2XLenNonZero:
1519 case Match_InvalidUImm1:
1521 case Match_InvalidUImm2:
1523 case Match_InvalidUImm2Lsb0:
1525 "immediate must be one of");
1526 case Match_InvalidUImm3:
1528 case Match_InvalidUImm4:
1530 case Match_InvalidUImm5:
1532 case Match_InvalidUImm5NonZero:
1534 case Match_InvalidUImm5GT3:
1536 case Match_InvalidUImm6:
1538 case Match_InvalidUImm7:
1540 case Match_InvalidUImm8:
1542 case Match_InvalidUImm8GE32:
1544 case Match_InvalidSImm5:
1547 case Match_InvalidSImm6:
1550 case Match_InvalidSImm6NonZero:
1551 return generateImmOutOfRangeError(
1553 "immediate must be non-zero in the range");
1554 case Match_InvalidCLUIImm:
1555 return generateImmOutOfRangeError(
1557 "immediate must be in [0xfffe0, 0xfffff] or");
1558 case Match_InvalidUImm5Lsb0:
1559 return generateImmOutOfRangeError(
1561 "immediate must be a multiple of 2 bytes in the range");
1562 case Match_InvalidUImm6Lsb0:
1563 return generateImmOutOfRangeError(
1565 "immediate must be a multiple of 2 bytes in the range");
1566 case Match_InvalidUImm7Lsb00:
1567 return generateImmOutOfRangeError(
1569 "immediate must be a multiple of 4 bytes in the range");
1570 case Match_InvalidUImm8Lsb00:
1571 return generateImmOutOfRangeError(
1573 "immediate must be a multiple of 4 bytes in the range");
1574 case Match_InvalidUImm8Lsb000:
1575 return generateImmOutOfRangeError(
1577 "immediate must be a multiple of 8 bytes in the range");
1578 case Match_InvalidSImm9Lsb0:
1579 return generateImmOutOfRangeError(
1581 "immediate must be a multiple of 2 bytes in the range");
1582 case Match_InvalidUImm9Lsb000:
1583 return generateImmOutOfRangeError(
1585 "immediate must be a multiple of 8 bytes in the range");
1586 case Match_InvalidUImm10Lsb00NonZero:
1587 return generateImmOutOfRangeError(
1589 "immediate must be a multiple of 4 bytes in the range");
1590 case Match_InvalidSImm10Lsb0000NonZero:
1591 return generateImmOutOfRangeError(
1593 "immediate must be a multiple of 16 bytes and non-zero in the range");
1594 case Match_InvalidUImm10:
1596 case Match_InvalidUImm11:
1598 case Match_InvalidSImm12:
1599 return generateImmOutOfRangeError(
1601 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an "
1602 "integer in the range");
1603 case Match_InvalidSImm12Lsb0:
1604 return generateImmOutOfRangeError(
1606 "immediate must be a multiple of 2 bytes in the range");
1607 case Match_InvalidSImm12Lsb00000:
1608 return generateImmOutOfRangeError(
1610 "immediate must be a multiple of 32 bytes in the range");
1611 case Match_InvalidSImm13Lsb0:
1612 return generateImmOutOfRangeError(
1614 "immediate must be a multiple of 2 bytes in the range");
1615 case Match_InvalidUImm20LUI:
1617 "operand must be a symbol with "
1618 "%hi/%tprel_hi modifier or an integer in "
1620 case Match_InvalidUImm20:
1622 case Match_InvalidUImm20AUIPC:
1623 return generateImmOutOfRangeError(
1625 "operand must be a symbol with a "
1626 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
1627 "an integer in the range");
1628 case Match_InvalidSImm21Lsb0JAL:
1629 return generateImmOutOfRangeError(
1631 "immediate must be a multiple of 2 bytes in the range");
1632 case Match_InvalidCSRSystemRegister: {
1634 "operand must be a valid system register "
1635 "name or an integer in the range");
1637 case Match_InvalidLoadFPImm: {
1639 return Error(ErrorLoc,
"operand must be a valid floating-point constant");
1641 case Match_InvalidBareSymbol: {
1643 return Error(ErrorLoc,
"operand must be a bare symbol name");
1645 case Match_InvalidPseudoJumpSymbol: {
1647 return Error(ErrorLoc,
"operand must be a valid jump target");
1649 case Match_InvalidCallSymbol: {
1651 return Error(ErrorLoc,
"operand must be a bare symbol name");
1653 case Match_InvalidTPRelAddSymbol: {
1655 return Error(ErrorLoc,
"operand must be a symbol with %tprel_add modifier");
1657 case Match_InvalidTLSDESCCallSymbol: {
1659 return Error(ErrorLoc,
1660 "operand must be a symbol with %tlsdesc_call modifier");
1662 case Match_InvalidRTZArg: {
1664 return Error(ErrorLoc,
"operand must be 'rtz' floating-point rounding mode");
1666 case Match_InvalidVTypeI: {
1668 return generateVTypeError(ErrorLoc);
1670 case Match_InvalidVMaskRegister: {
1672 return Error(ErrorLoc,
"operand must be v0.t");
1674 case Match_InvalidSImm5Plus1: {
1677 "immediate must be in the range");
1679 case Match_InvalidRlist: {
1683 "operand must be {ra [, s0[-sN]]} or {x1 [, x8[-x9][, x18[-xN]]]}");
1685 case Match_InvalidStackAdj: {
1689 "stack adjustment is invalid for this instruction and register list; "
1690 "refer to Zc spec for a detailed range of stack adjustment");
1692 case Match_InvalidRnumArg: {
1695 case Match_InvalidRegReg: {
1697 return Error(ErrorLoc,
"operands must be register and register");
1715 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1716 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1719 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1726 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1727 return Error(StartLoc,
"invalid register name");
1733 const AsmToken &Tok = getParser().getTok();
1748 SMLoc FirstS = getLoc();
1749 bool HadParens =
false;
1756 size_t ReadCount = getLexer().peekTokens(Buf);
1759 LParen = getParser().getTok();
1764 switch (getLexer().getKind()) {
1767 getLexer().UnLex(LParen);
1775 getLexer().UnLex(LParen);
1779 Operands.push_back(RISCVOperand::createToken(
"(", FirstS));
1783 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
1788 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
1799 switch (getLexer().getKind()) {
1809 if (getParser().parseExpression(Res,
E))
1812 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1814 int64_t
Imm =
CE->getValue();
1815 if (isUInt<7>(Imm)) {
1816 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1825 if (getParser().parseIdentifier(Identifier))
1828 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1830 assert(isUInt<7>(Opcode->Value) && (Opcode->Value & 0x3) == 3 &&
1831 "Unexpected opcode");
1834 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1844 return generateImmOutOfRangeError(
1846 "opcode must be a valid opcode name or an immediate in the range");
1854 switch (getLexer().getKind()) {
1864 if (getParser().parseExpression(Res,
E))
1867 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1869 int64_t
Imm =
CE->getValue();
1870 if (Imm >= 0 && Imm <= 2) {
1871 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1880 if (getParser().parseIdentifier(Identifier))
1884 if (Identifier ==
"C0")
1886 else if (Identifier ==
"C1")
1888 else if (Identifier ==
"C2")
1895 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1904 return generateImmOutOfRangeError(
1906 "opcode must be a valid opcode name or an immediate in the range");
1913 auto SysRegFromConstantInt = [
this](
const MCExpr *
E,
SMLoc S) {
1914 if (
auto *CE = dyn_cast<MCConstantExpr>(
E)) {
1915 int64_t
Imm =
CE->getValue();
1916 if (isUInt<12>(Imm)) {
1917 auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
1921 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
1924 return RISCVOperand::createSysReg(
Reg.Name, S, Imm);
1928 return RISCVOperand::createSysReg(
"", S, Imm);
1931 return std::unique_ptr<RISCVOperand>();
1934 switch (getLexer().getKind()) {
1944 if (getParser().parseExpression(Res))
1947 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
1948 Operands.push_back(std::move(SysOpnd));
1952 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1956 if (getParser().parseIdentifier(Identifier))
1959 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1962 if (SysReg->IsDeprecatedName) {
1964 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
1966 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
1968 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
1974 const auto &FeatureBits = getSTI().getFeatureBits();
1975 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
1977 return SysReg->FeaturesRequired[Feature.Value];
1979 auto ErrorMsg = std::string(
"system register '") + SysReg->Name +
"' ";
1980 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
1981 ErrorMsg +=
"is RV32 only";
1983 ErrorMsg +=
" and ";
1987 "requires '" + std::string(Feature->Key) +
"' to be enabled";
1990 return Error(S, ErrorMsg);
1993 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
1998 MCSymbol *
Sym = getContext().lookupSymbol(Identifier);
1999 if (
Sym &&
Sym->isVariable()) {
2002 if (
auto SysOpnd = SysRegFromConstantInt(
2003 Sym->getVariableValue(
false), S)) {
2004 Operands.push_back(std::move(SysOpnd));
2009 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2010 "operand must be a valid system register "
2011 "name or an integer in the range");
2015 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2028 if (
Identifier.compare_insensitive(
"inf") == 0) {
2031 getTok().getEndLoc(), isRV64()));
2032 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2035 getTok().getEndLoc(), isRV64()));
2036 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2039 getTok().getEndLoc(), isRV64()));
2041 return TokError(
"invalid floating point literal");
2054 return TokError(
"invalid floating point immediate");
2057 APFloat RealVal(APFloat::IEEEdouble());
2059 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2061 return TokError(
"invalid floating point representation");
2064 RealVal.changeSign();
2066 Operands.push_back(RISCVOperand::createFPImm(
2067 RealVal.bitcastToAPInt().getZExtValue(), S));
2079 switch (getLexer().getKind()) {
2091 if (getParser().parseExpression(Res,
E))
2095 return parseOperandWithModifier(
Operands);
2098 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2110 return Error(getLoc(),
"expected valid identifier for operand modifier");
2114 return Error(getLoc(),
"unrecognized operand modifier");
2121 if (getParser().parseParenExpression(SubExpr,
E))
2125 Operands.push_back(RISCVOperand::createImm(ModExpr, S,
E, isRV64()));
2137 AsmToken Tok = getLexer().getTok();
2139 if (getParser().parseIdentifier(Identifier))
2145 return Error(getLoc(),
"'@plt' operand not valid for instruction");
2147 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
2149 if (
Sym->isVariable()) {
2150 const MCExpr *
V =
Sym->getVariableValue(
false);
2151 if (!isa<MCSymbolRefExpr>(V)) {
2152 getLexer().UnLex(Tok);
2160 switch (getLexer().getKind()) {
2162 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2175 if (getParser().parseExpression(Expr,
E))
2178 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2194 if (getParser().parseIdentifier(Identifier))
2202 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
2205 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2214 if (getParser().parseExpression(Res,
E))
2217 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef ||
2218 cast<MCSymbolRefExpr>(Res)->getKind() ==
2219 MCSymbolRefExpr::VariantKind::VK_PLT)
2220 return Error(S,
"operand must be a valid jump target");
2223 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2244bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2245 unsigned &Sew,
unsigned &Lmul,
2246 bool &Fractional,
bool &TailAgnostic,
2247 bool &MaskAgnostic) {
2254 case VTypeState_SEW:
2261 State = VTypeState_LMUL;
2263 case VTypeState_LMUL: {
2273 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2274 unsigned MinLMUL = ELEN / 8;
2277 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2278 Twine(MinLMUL) +
" is reserved");
2281 State = VTypeState_TailPolicy;
2284 case VTypeState_TailPolicy:
2285 if (Identifier ==
"ta")
2286 TailAgnostic =
true;
2287 else if (Identifier ==
"tu")
2288 TailAgnostic =
false;
2291 State = VTypeState_MaskPolicy;
2293 case VTypeState_MaskPolicy:
2294 if (Identifier ==
"ma")
2295 MaskAgnostic =
true;
2296 else if (Identifier ==
"mu")
2297 MaskAgnostic =
false;
2300 State = VTypeState_Done;
2302 case VTypeState_Done:
2315 bool Fractional =
false;
2316 bool TailAgnostic =
false;
2317 bool MaskAgnostic =
false;
2319 VTypeState State = VTypeState_SEW;
2322 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2329 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2339 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2340 unsigned MaxSEW = ELEN / Lmul;
2342 if (MaxSEW >= 8 && Sew > MaxSEW)
2344 "use of vtype encodings with SEW > " +
Twine(MaxSEW) +
2345 " and LMUL == mf" +
Twine(Lmul) +
2346 " may not be compatible with all RVV implementations");
2351 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2355 return generateVTypeError(S);
2358bool RISCVAsmParser::generateVTypeError(
SMLoc ErrorLoc) {
2362 "e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2370 if (!
Name.consume_back(
".t"))
2371 return Error(getLoc(),
"expected '.t' suffix");
2376 if (
Reg != RISCV::V0)
2381 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2386 if (!isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2404 Operands.push_back(RISCVOperand::createReg(
2405 Reg, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2410 if (isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2422 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2425 if ((
Reg - RISCV::X0) & 1) {
2428 if (getSTI().hasFeature(RISCV::FeatureStdExtZfinx))
2429 return TokError(
"double precision floating point operands must use even "
2430 "numbered X register");
2440 Reg, RISCV::sub_gpr_even,
2441 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2442 Operands.push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2446template <
bool IsRV64>
2448 return parseGPRPair(
Operands, IsRV64);
2458 if (!IsRV64Inst && isRV64())
2470 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2473 if ((
Reg - RISCV::X0) & 1)
2474 return TokError(
"register must be even");
2482 Reg, RISCV::sub_gpr_even,
2483 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2484 Operands.push_back(RISCVOperand::createReg(Pair, S,
E));
2491 "operand must be a valid floating point rounding mode mnemonic");
2493 StringRef Str = getLexer().getTok().getIdentifier();
2498 "operand must be a valid floating point rounding mode mnemonic");
2500 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2506 const AsmToken &Tok = getLexer().getTok();
2512 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2526 for (
char c : Str) {
2555 Operands.push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2561 return TokError(
"operand must be formed of letters selected in-order from "
2568 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
2570 if (!parseRegister(
Operands).isSuccess())
2571 return Error(getLoc(),
"expected register");
2575 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2599 std::unique_ptr<RISCVOperand> OptionalImmOp;
2606 SMLoc ImmStart = getLoc();
2607 if (getParser().parseIntToken(ImmVal,
2608 "expected '(' or optional integer offset"))
2613 SMLoc ImmEnd = getLoc();
2616 ImmStart, ImmEnd, isRV64());
2620 OptionalImmOp ?
"expected '(' after optional integer offset"
2621 :
"expected '(' or optional integer offset"))
2624 if (!parseRegister(
Operands).isSuccess())
2625 return Error(getLoc(),
"expected register");
2631 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2633 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2634 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2647 return Error(getLoc(),
"invalid register");
2654 return Error(getLoc(),
"expected register");
2656 StringRef Reg2Name = getLexer().getTok().getIdentifier();
2659 return Error(getLoc(),
"invalid register");
2665 Operands.push_back(RISCVOperand::createRegReg(
Reg, Reg2, getLoc()));
2678 bool IsEABI = isRVE();
2681 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2686 if (RegStart != RISCV::X1)
2687 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2693 return Error(getLoc(),
"invalid register");
2697 return Error(getLoc(),
"invalid register");
2698 if (RegStart != RISCV::X8)
2699 return Error(getLoc(),
2700 "continuous register list must start from 's0' or 'x8'");
2706 StringRef EndName = getLexer().getTok().getIdentifier();
2710 return Error(getLoc(),
"invalid register");
2711 if (IsEABI && RegEnd != RISCV::X9)
2712 return Error(getLoc(),
"contiguous register list of EABI can only be "
2713 "'s0-s1' or 'x8-x9' pair");
2720 if (RegEnd != RISCV::X9)
2723 "first contiguous registers pair of register list must be 'x8-x9'");
2727 return Error(getLoc(),
"invalid register");
2728 StringRef EndName = getLexer().getTok().getIdentifier();
2730 return Error(getLoc(),
2731 "second contiguous registers pair of register list "
2732 "must start from 'x18'");
2738 return Error(getLoc(),
"invalid register");
2739 EndName = getLexer().getTok().getIdentifier();
2741 return Error(getLoc(),
"invalid register");
2748 if (RegEnd == RISCV::X26)
2749 return Error(getLoc(),
"invalid register list, {ra, s0-s10} or {x1, x8-x9, "
2750 "x18-x26} is not supported");
2760 return Error(S,
"invalid register list");
2761 Operands.push_back(RISCVOperand::createRlist(Encode, S));
2767 bool ExpectNegative) {
2773 unsigned RlistVal =
static_cast<RISCVOperand *
>(
Operands[1].get())->Rlist.Val;
2775 if (Negative != ExpectNegative ||
2778 Operands.push_back(RISCVOperand::createSpimm(Spimm << 4, S));
2790 MatchOperandParserImpl(
Operands, Mnemonic,
true);
2797 if (parseRegister(
Operands,
true).isSuccess())
2804 return !parseMemOpBaseReg(
Operands).isSuccess();
2809 Error(getLoc(),
"unknown operand");
2822 if (getSTI().hasFeature(RISCV::FeatureRelax)) {
2823 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
2824 if (Assembler !=
nullptr) {
2832 Operands.push_back(RISCVOperand::createToken(
Name, NameLoc));
2851 if (getParser().parseEOL(
"unexpected token")) {
2852 getParser().eatToEndOfStatement();
2858bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
2862 if (
const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
2863 Kind = RE->getKind();
2864 Expr = RE->getSubExpr();
2874bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
2887 if (IDVal ==
".option")
2888 return parseDirectiveOption();
2889 if (IDVal ==
".attribute")
2890 return parseDirectiveAttribute();
2891 if (IDVal ==
".insn")
2892 return parseDirectiveInsn(DirectiveID.
getLoc());
2893 if (IDVal ==
".variant_cc")
2894 return parseDirectiveVariantCC();
2899bool RISCVAsmParser::resetToArch(
StringRef Arch,
SMLoc Loc, std::string &Result,
2900 bool FromOptionDirective) {
2903 clearFeatureBits(Feature.Value, Feature.Key);
2912 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
2913 << ErrMsg.getMessage();
2916 return Error(Loc, OutputErrMsg.str());
2921 if (ISAInfo->hasExtension(Feature.Key))
2922 setFeatureBits(Feature.Value, Feature.Key);
2924 if (FromOptionDirective) {
2925 if (ISAInfo->getXLen() == 32 && isRV64())
2926 return Error(Loc,
"bad arch string switching from rv64 to rv32");
2927 else if (ISAInfo->getXLen() == 64 && !isRV64())
2928 return Error(Loc,
"bad arch string switching from rv32 to rv64");
2931 if (ISAInfo->getXLen() == 32)
2932 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
2933 else if (ISAInfo->getXLen() == 64)
2934 setFeatureBits(RISCV::Feature64Bit,
"64bit");
2936 return Error(Loc,
"bad arch string " + Arch);
2938 Result = ISAInfo->toString();
2942bool RISCVAsmParser::parseDirectiveOption() {
2953 if (Option ==
"push") {
2957 getTargetStreamer().emitDirectiveOptionPush();
2962 if (Option ==
"pop") {
2967 getTargetStreamer().emitDirectiveOptionPop();
2968 if (popFeatureBits())
2969 return Error(StartLoc,
".option pop with no .option push");
2974 if (Option ==
"arch") {
2982 Type = RISCVOptionArchArgType::Plus;
2984 Type = RISCVOptionArchArgType::Minus;
2985 else if (!
Args.empty())
2987 "unexpected token, expected + or -");
2989 Type = RISCVOptionArchArgType::Full;
2993 "unexpected token, expected identifier");
2999 if (
Type == RISCVOptionArchArgType::Full) {
3001 if (resetToArch(Arch, Loc, Result,
true))
3010 Loc,
"extension version number parsing not currently implemented");
3013 if (!enableExperimentalExtension() &&
3015 return Error(Loc,
"unexpected experimental extensions");
3018 return Error(Loc,
"unknown extension feature");
3022 if (
Type == RISCVOptionArchArgType::Plus) {
3025 setFeatureBits(
Ext->Value,
Ext->Key);
3028 copySTI().setFeatureBits(OldFeatureBits);
3029 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3034 OutputErrMsg << ErrMsg.getMessage();
3037 return Error(Loc, OutputErrMsg.str());
3040 assert(
Type == RISCVOptionArchArgType::Minus);
3045 if (getSTI().hasFeature(Feature.Value) &&
3046 Feature.Implies.test(
Ext->Value))
3048 " extension; " + Feature.Key +
3049 " extension requires " +
Ext->Key +
3053 clearFeatureBits(
Ext->Value,
Ext->Key);
3060 getTargetStreamer().emitDirectiveOptionArch(Args);
3064 if (Option ==
"rvc") {
3068 getTargetStreamer().emitDirectiveOptionRVC();
3069 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3073 if (Option ==
"norvc") {
3077 getTargetStreamer().emitDirectiveOptionNoRVC();
3078 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3079 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3083 if (Option ==
"pic") {
3087 getTargetStreamer().emitDirectiveOptionPIC();
3088 ParserOptions.IsPicEnabled =
true;
3092 if (Option ==
"nopic") {
3096 getTargetStreamer().emitDirectiveOptionNoPIC();
3097 ParserOptions.IsPicEnabled =
false;
3101 if (Option ==
"relax") {
3105 getTargetStreamer().emitDirectiveOptionRelax();
3106 setFeatureBits(RISCV::FeatureRelax,
"relax");
3110 if (Option ==
"norelax") {
3114 getTargetStreamer().emitDirectiveOptionNoRelax();
3115 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3121 "'rvc', 'norvc', 'arch', 'relax' or "
3130bool RISCVAsmParser::parseDirectiveAttribute() {
3137 std::optional<unsigned>
Ret =
3140 return Error(TagLoc,
"attribute name not recognised: " +
Name);
3151 if (check(!CE, TagLoc,
"expected numeric constant"))
3154 Tag =
CE->getValue();
3161 int64_t IntegerValue = 0;
3162 bool IsIntegerValue =
true;
3167 IsIntegerValue =
false;
3170 if (IsIntegerValue) {
3177 return Error(ValueExprLoc,
"expected numeric constant");
3178 IntegerValue =
CE->getValue();
3191 getTargetStreamer().emitAttribute(Tag, IntegerValue);
3193 getTargetStreamer().emitTextAttribute(Tag, StringValue);
3196 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3200 getTargetStreamer().emitTextAttribute(Tag, Result);
3208 .
Cases(
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s",
true)
3209 .
Cases(
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj", AllowC)
3217bool RISCVAsmParser::parseDirectiveInsn(
SMLoc L) {
3220 bool AllowC = getSTI().hasFeature(RISCV::FeatureStdExtC) ||
3221 getSTI().hasFeature(RISCV::FeatureStdExtZca);
3228 std::optional<int64_t>
Length;
3238 return Error(ErrorLoc,
3239 "instruction lengths must be a non-zero multiple of two");
3243 return Error(ErrorLoc,
3244 "instruction lengths over 64 bits are not supported");
3250 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3255 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3256 return Error(ErrorLoc,
3257 "instruction length does not match the encoding");
3260 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3263 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3266 if (!AllowC && (EncodingDerivedLength == 2))
3267 return Error(ErrorLoc,
"compressed instructions are not allowed");
3269 if (getParser().parseEOL(
"invalid operand for instruction")) {
3270 getParser().eatToEndOfStatement();
3278 Opcode = RISCV::Insn16;
3281 Opcode = RISCV::Insn32;
3284 Opcode = RISCV::Insn48;
3287 Opcode = RISCV::Insn64;
3293 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3300 return Error(ErrorLoc,
"invalid instruction format");
3302 std::string FormatName = (
".insn_" +
Format).str();
3319bool RISCVAsmParser::parseDirectiveVariantCC() {
3321 if (getParser().parseIdentifier(
Name))
3322 return TokError(
"expected symbol name");
3325 getTargetStreamer().emitDirectiveVariantCC(
3326 *getContext().getOrCreateSymbol(
Name));
3334 ++RISCVNumInstrsCompressed;
3343 for (
MCInst &Inst : Seq) {
3344 emitToStreamer(Out, Inst);
3351 unsigned SecondOpcode,
SMLoc IDLoc,
3365 const MCExpr *RefToLinkTmpLabel =
3372 .addExpr(RefToLinkTmpLabel));
3375void RISCVAsmParser::emitLoadLocalAddress(
MCInst &Inst,
SMLoc IDLoc,
3386 RISCV::ADDI, IDLoc, Out);
3389void RISCVAsmParser::emitLoadGlobalAddress(
MCInst &Inst,
SMLoc IDLoc,
3399 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3401 SecondOpcode, IDLoc, Out);
3404void RISCVAsmParser::emitLoadAddress(
MCInst &Inst,
SMLoc IDLoc,
3413 if (ParserOptions.IsPicEnabled)
3414 emitLoadGlobalAddress(Inst, IDLoc, Out);
3416 emitLoadLocalAddress(Inst, IDLoc, Out);
3419void RISCVAsmParser::emitLoadTLSIEAddress(
MCInst &Inst,
SMLoc IDLoc,
3429 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3431 SecondOpcode, IDLoc, Out);
3434void RISCVAsmParser::emitLoadTLSGDAddress(
MCInst &Inst,
SMLoc IDLoc,
3445 RISCV::ADDI, IDLoc, Out);
3448void RISCVAsmParser::emitLoadStoreSymbol(
MCInst &Inst,
unsigned Opcode,
3458 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3460 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3464 Opcode, IDLoc, Out);
3467void RISCVAsmParser::emitPseudoExtend(
MCInst &Inst,
bool SignExtend,
3468 int64_t Width,
SMLoc IDLoc,
3480 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3481 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3483 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3496void RISCVAsmParser::emitVMSGE(
MCInst &Inst,
unsigned Opcode,
SMLoc IDLoc,
3520 "The destination register should not be V0.");
3539 "The destination register should be V0.");
3541 "The temporary vector register should not be V0.");
3560 "The temporary vector register should not be V0.");
3585bool RISCVAsmParser::checkPseudoAddTPRel(
MCInst &Inst,
3587 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3590 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3591 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3592 "%tprel_add modifier");
3598bool RISCVAsmParser::checkPseudoTLSDESCCall(
MCInst &Inst,
3600 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
3603 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3604 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
3605 "%tlsdesc_call modifier");
3611std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3615std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3616 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3620std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3621 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3625bool RISCVAsmParser::validateInstruction(
MCInst &Inst,
3629 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3630 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3633 if (DestReg == TempReg) {
3635 return Error(Loc,
"the temporary vector register cannot be the same as "
3636 "the destination register");
3640 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3641 Opcode == RISCV::TH_LWD) {
3646 if (Rs1 == Rd1 && Rs1 == Rd2) {
3648 return Error(Loc,
"rs1, rd1, and rd2 cannot all be the same");
3652 if (Opcode == RISCV::CM_MVSA01) {
3657 return Error(Loc,
"rs1 and rs2 must be different");
3661 bool IsTHeadMemPair32 = (Opcode == RISCV::TH_LWD ||
3662 Opcode == RISCV::TH_LWUD || Opcode == RISCV::TH_SWD);
3663 bool IsTHeadMemPair64 = (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_SDD);
3668 return Error(Loc,
"operand must be constant 3");
3671 return Error(Loc,
"operand must be constant 4");
3678 if (Opcode == RISCV::VC_V_XVW || Opcode == RISCV::VC_V_IVW ||
3679 Opcode == RISCV::VC_V_FVW || Opcode == RISCV::VC_V_VVW) {
3685 if (VCIXDst == VCIXRs1)
3686 return Error(VCIXDstLoc,
"the destination vector register group cannot"
3687 " overlap the source vector register group");
3691 if (VCIXDst == VCIXRs2)
3692 return Error(VCIXDstLoc,
"the destination vector register group cannot"
3693 " overlap the source vector register group");
3708 if (DestReg == CheckReg)
3709 return Error(Loc,
"the destination vector register group cannot overlap"
3710 " the source vector register group");
3714 if (DestReg == CheckReg)
3715 return Error(Loc,
"the destination vector register group cannot overlap"
3716 " the source vector register group");
3721 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM ||
3722 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM ||
3723 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM ||
3724 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM ||
3725 Opcode == RISCV::VMERGE_VXM)
3726 return Error(Loc,
"the destination vector register group cannot be V0");
3733 assert((CheckReg == RISCV::V0 || !CheckReg) &&
3734 "Unexpected register for mask operand");
3736 if (DestReg == CheckReg)
3737 return Error(Loc,
"the destination vector register group cannot overlap"
3738 " the mask register");
3743bool RISCVAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
3751 case RISCV::PseudoC_ADDI_NOP:
3754 case RISCV::PseudoLLAImm:
3755 case RISCV::PseudoLAImm:
3756 case RISCV::PseudoLI: {
3773 Imm = SignExtend64<32>(Imm);
3774 emitLoadImm(
Reg, Imm, Out);
3777 case RISCV::PseudoLLA:
3778 emitLoadLocalAddress(Inst, IDLoc, Out);
3780 case RISCV::PseudoLGA:
3781 emitLoadGlobalAddress(Inst, IDLoc, Out);
3783 case RISCV::PseudoLA:
3784 emitLoadAddress(Inst, IDLoc, Out);
3786 case RISCV::PseudoLA_TLS_IE:
3787 emitLoadTLSIEAddress(Inst, IDLoc, Out);
3789 case RISCV::PseudoLA_TLS_GD:
3790 emitLoadTLSGDAddress(Inst, IDLoc, Out);
3792 case RISCV::PseudoLB:
3793 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
3795 case RISCV::PseudoLBU:
3796 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
3798 case RISCV::PseudoLH:
3799 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
3801 case RISCV::PseudoLHU:
3802 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
3804 case RISCV::PseudoLW:
3805 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
3807 case RISCV::PseudoLWU:
3808 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
3810 case RISCV::PseudoLD:
3811 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
3813 case RISCV::PseudoFLH:
3814 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
3816 case RISCV::PseudoFLW:
3817 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
3819 case RISCV::PseudoFLD:
3820 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
3822 case RISCV::PseudoSB:
3823 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
3825 case RISCV::PseudoSH:
3826 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
3828 case RISCV::PseudoSW:
3829 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
3831 case RISCV::PseudoSD:
3832 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
3834 case RISCV::PseudoFSH:
3835 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
3837 case RISCV::PseudoFSW:
3838 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
3840 case RISCV::PseudoFSD:
3841 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
3843 case RISCV::PseudoAddTPRel:
3844 if (checkPseudoAddTPRel(Inst,
Operands))
3847 case RISCV::PseudoTLSDESCCall:
3848 if (checkPseudoTLSDESCCall(Inst,
Operands))
3851 case RISCV::PseudoSEXT_B:
3852 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
3854 case RISCV::PseudoSEXT_H:
3855 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
3857 case RISCV::PseudoZEXT_H:
3858 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
3860 case RISCV::PseudoZEXT_W:
3861 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
3863 case RISCV::PseudoVMSGEU_VX:
3864 case RISCV::PseudoVMSGEU_VX_M:
3865 case RISCV::PseudoVMSGEU_VX_M_T:
3866 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
3868 case RISCV::PseudoVMSGE_VX:
3869 case RISCV::PseudoVMSGE_VX_M:
3870 case RISCV::PseudoVMSGE_VX_M_T:
3871 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
3873 case RISCV::PseudoVMSGE_VI:
3874 case RISCV::PseudoVMSLT_VI: {
3878 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
3888 case RISCV::PseudoVMSGEU_VI:
3889 case RISCV::PseudoVMSLTU_VI: {
3896 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3907 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3922 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.