47#define DEBUG_TYPE "riscv-asm-parser"
50 "Number of RISC-V Compressed instructions emitted");
62struct ParserOptionsSet {
74 VTypeState_TailPolicy,
75 VTypeState_MaskPolicy,
82 ParserOptionsSet ParserOptions;
87 bool enableExperimentalExtension()
const {
93 "do not have a target streamer");
99 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"
220 bool ExpectNegative =
false);
222 return parseZcmpStackAdj(
Operands,
true);
227 bool parseDirectiveOption();
228 bool parseDirectiveAttribute();
229 bool parseDirectiveInsn(
SMLoc L);
230 bool parseDirectiveVariantCC();
236 bool FromOptionDirective);
239 if (!(
getSTI().hasFeature(Feature))) {
247 if (
getSTI().hasFeature(Feature)) {
254 void pushFeatureBits() {
256 "These two stacks must be kept synchronized");
258 ParserOptionsStack.
push_back(ParserOptions);
261 bool popFeatureBits() {
263 "These two stacks must be kept synchronized");
264 if (FeatureBitStack.
empty())
276 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
277 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
278 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
281 enum RISCVMatchResultTy {
283 Match_RequiresEvenGPRs,
284#define GET_OPERAND_DIAGNOSTIC_TYPES
285#include "RISCVGenAsmMatcher.inc"
286#undef GET_OPERAND_DIAGNOSTIC_TYPES
289 static bool classifySymbolRef(
const MCExpr *Expr,
291 static bool isSymbolDiff(
const MCExpr *Expr);
305 if (ABIName.ends_with(
"f") && !getSTI().hasFeature(RISCV::FeatureStdExtF)) {
306 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
307 "doesn't support the F instruction set extension (ignoring "
309 }
else if (ABIName.ends_with(
"d") &&
310 !getSTI().hasFeature(RISCV::FeatureStdExtD)) {
311 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
312 "doesn't support the D instruction set extension (ignoring "
325 getTargetStreamer().emitTargetAttributes(STI,
false);
394 SMLoc StartLoc, EndLoc;
400 struct SysRegOp SysReg;
401 struct VTypeOp VType;
403 struct FenceOp Fence;
404 struct RlistOp Rlist;
405 struct SpimmOp Spimm;
409 RISCVOperand(KindTy K) :
Kind(
K) {}
414 StartLoc =
o.StartLoc;
417 case KindTy::Register:
420 case KindTy::Immediate:
423 case KindTy::FPImmediate:
429 case KindTy::SystemRegister:
453 bool isToken()
const override {
return Kind == KindTy::Token; }
454 bool isReg()
const override {
return Kind == KindTy::Register; }
455 bool isV0Reg()
const {
456 return Kind == KindTy::Register &&
Reg.RegNum == RISCV::V0;
458 bool isAnyReg()
const {
459 return Kind == KindTy::Register &&
460 (RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.RegNum) ||
461 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg.RegNum) ||
462 RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg.RegNum));
464 bool isAnyRegC()
const {
465 return Kind == KindTy::Register &&
466 (RISCVMCRegisterClasses[RISCV::GPRCRegClassID].contains(
468 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
471 bool isImm()
const override {
return Kind == KindTy::Immediate; }
472 bool isMem()
const override {
return false; }
473 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
474 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
475 bool isRlist()
const {
return Kind == KindTy::Rlist; }
476 bool isSpimm()
const {
return Kind == KindTy::Spimm; }
479 return Kind == KindTy::Register &&
480 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.RegNum);
483 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
485 bool isGPRPair()
const {
486 return Kind == KindTy::Register &&
487 RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(
491 static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &Imm,
493 if (
auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
495 return RE->evaluateAsConstant(Imm);
498 if (
auto CE = dyn_cast<MCConstantExpr>(Expr)) {
500 Imm =
CE->getValue();
509 template <
int N>
bool isBareSimmNLsb0()
const {
514 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
517 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
525 bool isBareSymbol()
const {
529 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
531 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
535 bool isCallSymbol()
const {
539 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
541 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
546 bool isPseudoJumpSymbol()
const {
550 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
552 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
556 bool isTPRelAddSymbol()
const {
560 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
562 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
566 bool isTLSDESCCallSymbol()
const {
570 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
572 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
576 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
578 bool isVTypeImm(
unsigned N)
const {
583 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
589 bool isVTypeI10()
const {
590 if (Kind == KindTy::Immediate)
591 return isVTypeImm(10);
592 return Kind == KindTy::VType;
594 bool isVTypeI11()
const {
595 if (Kind == KindTy::Immediate)
596 return isVTypeImm(11);
597 return Kind == KindTy::VType;
602 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
605 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
606 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
610 bool isLoadFPImm()
const {
613 if (Kind != KindTy::FPImmediate)
616 APFloat(APFloat::IEEEdouble(),
APInt(64, getFPConst())));
619 return Idx >= 0 &&
Idx != 1;
622 bool isImmXLenLI()
const {
627 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
637 (isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm)));
640 return RISCVAsmParser::isSymbolDiff(getImm());
643 bool isImmXLenLI_Restricted()
const {
648 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
651 (isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm)));
654 bool isUImmLog2XLen()
const {
659 if (!evaluateConstantImm(getImm(), Imm, VK) ||
662 return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm);
665 bool isUImmLog2XLenNonZero()
const {
670 if (!evaluateConstantImm(getImm(), Imm, VK) ||
675 return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm);
678 bool isUImmLog2XLenHalf()
const {
683 if (!evaluateConstantImm(getImm(), Imm, VK) ||
686 return (isRV64Imm() && isUInt<5>(Imm)) || isUInt<4>(Imm);
689 template <
unsigned N>
bool IsUImm()
const {
694 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
698 bool isUImm1()
const {
return IsUImm<1>(); }
699 bool isUImm2()
const {
return IsUImm<2>(); }
700 bool isUImm3()
const {
return IsUImm<3>(); }
701 bool isUImm4()
const {
return IsUImm<4>(); }
702 bool isUImm5()
const {
return IsUImm<5>(); }
703 bool isUImm6()
const {
return IsUImm<6>(); }
704 bool isUImm7()
const {
return IsUImm<7>(); }
705 bool isUImm8()
const {
return IsUImm<8>(); }
706 bool isUImm16()
const {
return IsUImm<16>(); }
707 bool isUImm20()
const {
return IsUImm<20>(); }
708 bool isUImm32()
const {
return IsUImm<32>(); }
710 bool isUImm8GE32()
const {
715 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
716 return IsConstantImm && isUInt<8>(Imm) &&
Imm >= 32 &&
720 bool isRnumArg()
const {
725 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
726 return IsConstantImm &&
Imm >= INT64_C(0) &&
Imm <= INT64_C(10) &&
730 bool isRnumArg_0_7()
const {
735 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
736 return IsConstantImm &&
Imm >= INT64_C(0) &&
Imm <= INT64_C(7) &&
740 bool isRnumArg_1_10()
const {
745 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
746 return IsConstantImm &&
Imm >= INT64_C(1) &&
Imm <= INT64_C(10) &&
750 bool isRnumArg_2_14()
const {
755 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
756 return IsConstantImm &&
Imm >= INT64_C(2) &&
Imm <= INT64_C(14) &&
760 bool isSImm5()
const {
765 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
766 return IsConstantImm && isInt<5>(fixImmediateForRV32(Imm, isRV64Imm())) &&
770 bool isSImm6()
const {
775 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
776 return IsConstantImm && isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) &&
780 bool isSImm6NonZero()
const {
785 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
786 return IsConstantImm &&
Imm != 0 &&
787 isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) &&
791 bool isCLUIImm()
const {
796 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
797 return IsConstantImm && (
Imm != 0) &&
798 (isUInt<5>(Imm) || (
Imm >= 0xfffe0 &&
Imm <= 0xfffff)) &&
802 bool isUImm2Lsb0()
const {
807 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
808 return IsConstantImm && isShiftedUInt<1, 1>(Imm) &&
812 bool isUImm5Lsb0()
const {
817 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
818 return IsConstantImm && isShiftedUInt<4, 1>(Imm) &&
822 bool isUImm6Lsb0()
const {
827 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
828 return IsConstantImm && isShiftedUInt<5, 1>(Imm) &&
832 bool isUImm7Lsb00()
const {
837 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
838 return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
842 bool isUImm8Lsb00()
const {
847 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
848 return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
852 bool isUImm8Lsb000()
const {
857 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
858 return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
862 bool isSImm9Lsb0()
const {
return isBareSimmNLsb0<9>(); }
864 bool isUImm9Lsb000()
const {
869 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
870 return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
874 bool isUImm10Lsb00NonZero()
const {
879 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
880 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (
Imm != 0) &&
886 static int64_t fixImmediateForRV32(int64_t Imm,
bool IsRV64Imm) {
887 if (IsRV64Imm || !isUInt<32>(Imm))
889 return SignExtend64<32>(Imm);
892 bool isSImm12()
const {
898 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
900 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
902 IsValid = isInt<12>(fixImmediateForRV32(Imm, isRV64Imm()));
911 bool isSImm12Lsb0()
const {
return isBareSimmNLsb0<12>(); }
913 bool isSImm12Lsb00000()
const {
918 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
919 return IsConstantImm && isShiftedInt<7, 5>(Imm) &&
923 bool isSImm13Lsb0()
const {
return isBareSimmNLsb0<13>(); }
925 bool isSImm10Lsb0000NonZero()
const {
930 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
931 return IsConstantImm && (
Imm != 0) && isShiftedInt<6, 4>(Imm) &&
935 bool isUImm20LUI()
const {
941 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
942 if (!IsConstantImm) {
943 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
953 bool isUImm20AUIPC()
const {
959 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
960 if (!IsConstantImm) {
961 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
977 bool isSImm21Lsb0JAL()
const {
return isBareSimmNLsb0<21>(); }
979 bool isImmZero()
const {
984 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
988 bool isSImm5Plus1()
const {
993 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
994 return IsConstantImm &&
995 isInt<5>(fixImmediateForRV32(Imm, isRV64Imm()) - 1) &&
1000 SMLoc getStartLoc()
const override {
return StartLoc; }
1002 SMLoc getEndLoc()
const override {
return EndLoc; }
1004 bool isRV64Imm()
const {
1005 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
1010 assert(Kind == KindTy::Register &&
"Invalid type access!");
1015 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
1016 return StringRef(SysReg.Data, SysReg.Length);
1019 const MCExpr *getImm()
const {
1020 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
1025 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1030 assert(Kind == KindTy::Token &&
"Invalid type access!");
1034 unsigned getVType()
const {
1035 assert(Kind == KindTy::VType &&
"Invalid type access!");
1040 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1044 unsigned getFence()
const {
1045 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1058 case KindTy::Immediate:
1061 case KindTy::FPImmediate:
1063 case KindTy::Register:
1067 OS <<
"'" << getToken() <<
"'";
1069 case KindTy::SystemRegister:
1070 OS <<
"<sysreg: " << getSysReg() <<
'>';
1079 roundingModeToString(getFRM());
1097 case KindTy::RegReg:
1104 static std::unique_ptr<RISCVOperand> createToken(
StringRef Str,
SMLoc S) {
1105 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1112 static std::unique_ptr<RISCVOperand>
1113 createReg(
unsigned RegNo,
SMLoc S,
SMLoc E,
bool IsGPRAsFPR =
false) {
1114 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1115 Op->Reg.RegNum = RegNo;
1116 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1122 static std::unique_ptr<RISCVOperand> createImm(
const MCExpr *Val,
SMLoc S,
1124 auto Op = std::make_unique<RISCVOperand>(KindTy::Immediate);
1126 Op->Imm.IsRV64 = IsRV64;
1132 static std::unique_ptr<RISCVOperand> createFPImm(
uint64_t Val,
SMLoc S) {
1133 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1134 Op->FPImm.Val = Val;
1140 static std::unique_ptr<RISCVOperand> createSysReg(
StringRef Str,
SMLoc S,
1141 unsigned Encoding) {
1142 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1143 Op->SysReg.Data = Str.data();
1144 Op->SysReg.Length = Str.size();
1151 static std::unique_ptr<RISCVOperand>
1153 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1160 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val,
SMLoc S) {
1161 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1162 Op->Fence.Val = Val;
1168 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI,
SMLoc S) {
1169 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1170 Op->VType.Val = VTypeI;
1176 static std::unique_ptr<RISCVOperand> createRlist(
unsigned RlistEncode,
1178 auto Op = std::make_unique<RISCVOperand>(KindTy::Rlist);
1179 Op->Rlist.Val = RlistEncode;
1184 static std::unique_ptr<RISCVOperand> createRegReg(
unsigned Reg1No,
1185 unsigned Reg2No,
SMLoc S) {
1186 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1187 Op->RegReg.Reg1 = Reg1No;
1188 Op->RegReg.Reg2 = Reg2No;
1194 static std::unique_ptr<RISCVOperand> createSpimm(
unsigned Spimm,
SMLoc S) {
1195 auto Op = std::make_unique<RISCVOperand>(KindTy::Spimm);
1196 Op->Spimm.Val = Spimm;
1201 static void addExpr(
MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1202 assert(Expr &&
"Expr shouldn't be null!");
1205 bool IsConstant = evaluateConstantImm(Expr, Imm, VK);
1215 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1216 assert(
N == 1 &&
"Invalid number of operands!");
1220 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1221 assert(
N == 1 &&
"Invalid number of operands!");
1222 addExpr(Inst, getImm(), isRV64Imm());
1225 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
1226 assert(
N == 1 &&
"Invalid number of operands!");
1228 addExpr(Inst, getImm(), isRV64Imm());
1233 APFloat(APFloat::IEEEdouble(),
APInt(64, getFPConst())));
1237 void addFenceArgOperands(
MCInst &Inst,
unsigned N)
const {
1238 assert(
N == 1 &&
"Invalid number of operands!");
1242 void addCSRSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
1243 assert(
N == 1 &&
"Invalid number of operands!");
1250 void addVTypeIOperands(
MCInst &Inst,
unsigned N)
const {
1251 assert(
N == 1 &&
"Invalid number of operands!");
1253 if (Kind == KindTy::Immediate) {
1255 [[maybe_unused]]
bool IsConstantImm =
1256 evaluateConstantImm(getImm(), Imm, VK);
1257 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1264 void addRlistOperands(
MCInst &Inst,
unsigned N)
const {
1265 assert(
N == 1 &&
"Invalid number of operands!");
1269 void addRegRegOperands(
MCInst &Inst,
unsigned N)
const {
1270 assert(
N == 2 &&
"Invalid number of operands!");
1275 void addSpimmOperands(
MCInst &Inst,
unsigned N)
const {
1276 assert(
N == 1 &&
"Invalid number of operands!");
1280 void addFRMArgOperands(
MCInst &Inst,
unsigned N)
const {
1281 assert(
N == 1 &&
"Invalid number of operands!");
1287#define GET_REGISTER_MATCHER
1288#define GET_SUBTARGET_FEATURE_NAME
1289#define GET_MATCHER_IMPLEMENTATION
1290#define GET_MNEMONIC_SPELL_CHECKER
1291#include "RISCVGenAsmMatcher.inc"
1294 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1295 return Reg - RISCV::F0_D + RISCV::F0_H;
1299 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1300 return Reg - RISCV::F0_D + RISCV::F0_F;
1305 unsigned RegClassID;
1306 if (Kind == MCK_VRM2)
1307 RegClassID = RISCV::VRM2RegClassID;
1308 else if (Kind == MCK_VRM4)
1309 RegClassID = RISCV::VRM4RegClassID;
1310 else if (Kind == MCK_VRM8)
1311 RegClassID = RISCV::VRM8RegClassID;
1315 &RISCVMCRegisterClasses[RegClassID]);
1320 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1322 return Match_InvalidOperand;
1326 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg);
1328 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg);
1329 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg);
1333 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1334 (IsRegFPR64C &&
Kind == MCK_FPR32C)) {
1336 return Match_Success;
1340 if (IsRegFPR64 && Kind == MCK_FPR16) {
1342 return Match_Success;
1346 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1348 if (
Op.Reg.RegNum == 0)
1349 return Match_InvalidOperand;
1350 return Match_Success;
1352 return Match_InvalidOperand;
1355unsigned RISCVAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
1359 if (MCID.
operands()[
I].RegClass == RISCV::GPRPairRegClassID) {
1364 if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].
contains(
Reg))
1368 if (((
Reg.id() - RISCV::X0) & 1) != 0)
1369 return Match_RequiresEvenGPRs;
1373 return Match_Success;
1376bool RISCVAsmParser::generateImmOutOfRangeError(
1378 const Twine &Msg =
"immediate must be an integer in the range") {
1382bool RISCVAsmParser::generateImmOutOfRangeError(
1384 const Twine &Msg =
"immediate must be an integer in the range") {
1386 return generateImmOutOfRangeError(ErrorLoc,
Lower,
Upper, Msg);
1389bool RISCVAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1393 bool MatchingInlineAsm) {
1403 if (validateInstruction(Inst,
Operands))
1405 return processInstruction(Inst, IDLoc,
Operands, Out);
1406 case Match_MissingFeature: {
1407 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1408 bool FirstFeature =
true;
1409 std::string Msg =
"instruction requires the following:";
1410 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1411 if (MissingFeatures[i]) {
1412 Msg += FirstFeature ?
" " :
", ";
1414 FirstFeature =
false;
1417 return Error(IDLoc, Msg);
1419 case Match_MnemonicFail: {
1420 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1421 std::string Suggestion = RISCVMnemonicSpellCheck(
1422 ((RISCVOperand &)*
Operands[0]).getToken(), FBS, 0);
1423 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1425 case Match_InvalidOperand: {
1426 SMLoc ErrorLoc = IDLoc;
1429 return Error(ErrorLoc,
"too few operands for instruction");
1432 if (ErrorLoc ==
SMLoc())
1435 return Error(ErrorLoc,
"invalid operand for instruction");
1442 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1443 SMLoc ErrorLoc = IDLoc;
1445 return Error(ErrorLoc,
"too few operands for instruction");
1451 case Match_RequiresEvenGPRs:
1453 "double precision floating point operands must use even "
1454 "numbered X register");
1455 case Match_InvalidImmXLenLI:
1458 return Error(ErrorLoc,
"operand must be a constant 64-bit integer");
1461 std::numeric_limits<int32_t>::min(),
1462 std::numeric_limits<uint32_t>::max());
1463 case Match_InvalidImmXLenLI_Restricted:
1466 return Error(ErrorLoc,
"operand either must be a constant 64-bit integer "
1467 "or a bare symbol name");
1469 return generateImmOutOfRangeError(
1471 std::numeric_limits<uint32_t>::max(),
1472 "operand either must be a bare symbol name or an immediate integer in "
1474 case Match_InvalidImmZero: {
1476 return Error(ErrorLoc,
"immediate must be zero");
1478 case Match_InvalidUImmLog2XLen:
1482 case Match_InvalidUImmLog2XLenNonZero:
1486 case Match_InvalidUImmLog2XLenHalf:
1490 case Match_InvalidUImm1:
1492 case Match_InvalidUImm2:
1494 case Match_InvalidUImm2Lsb0:
1496 "immediate must be one of");
1497 case Match_InvalidUImm3:
1499 case Match_InvalidUImm4:
1501 case Match_InvalidUImm5:
1503 case Match_InvalidUImm6:
1505 case Match_InvalidUImm7:
1507 case Match_InvalidUImm8:
1509 case Match_InvalidUImm8GE32:
1511 case Match_InvalidSImm5:
1514 case Match_InvalidSImm6:
1517 case Match_InvalidSImm6NonZero:
1518 return generateImmOutOfRangeError(
1520 "immediate must be non-zero in the range");
1521 case Match_InvalidCLUIImm:
1522 return generateImmOutOfRangeError(
1524 "immediate must be in [0xfffe0, 0xfffff] or");
1525 case Match_InvalidUImm5Lsb0:
1526 return generateImmOutOfRangeError(
1528 "immediate must be a multiple of 2 bytes in the range");
1529 case Match_InvalidUImm6Lsb0:
1530 return generateImmOutOfRangeError(
1532 "immediate must be a multiple of 2 bytes in the range");
1533 case Match_InvalidUImm7Lsb00:
1534 return generateImmOutOfRangeError(
1536 "immediate must be a multiple of 4 bytes in the range");
1537 case Match_InvalidUImm8Lsb00:
1538 return generateImmOutOfRangeError(
1540 "immediate must be a multiple of 4 bytes in the range");
1541 case Match_InvalidUImm8Lsb000:
1542 return generateImmOutOfRangeError(
1544 "immediate must be a multiple of 8 bytes in the range");
1545 case Match_InvalidSImm9Lsb0:
1546 return generateImmOutOfRangeError(
1548 "immediate must be a multiple of 2 bytes in the range");
1549 case Match_InvalidUImm9Lsb000:
1550 return generateImmOutOfRangeError(
1552 "immediate must be a multiple of 8 bytes in the range");
1553 case Match_InvalidUImm10Lsb00NonZero:
1554 return generateImmOutOfRangeError(
1556 "immediate must be a multiple of 4 bytes in the range");
1557 case Match_InvalidSImm10Lsb0000NonZero:
1558 return generateImmOutOfRangeError(
1560 "immediate must be a multiple of 16 bytes and non-zero in the range");
1561 case Match_InvalidSImm12:
1562 return generateImmOutOfRangeError(
1564 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an "
1565 "integer in the range");
1566 case Match_InvalidSImm12Lsb0:
1567 return generateImmOutOfRangeError(
1569 "immediate must be a multiple of 2 bytes in the range");
1570 case Match_InvalidSImm12Lsb00000:
1571 return generateImmOutOfRangeError(
1573 "immediate must be a multiple of 32 bytes in the range");
1574 case Match_InvalidSImm13Lsb0:
1575 return generateImmOutOfRangeError(
1577 "immediate must be a multiple of 2 bytes in the range");
1578 case Match_InvalidUImm20LUI:
1580 "operand must be a symbol with "
1581 "%hi/%tprel_hi modifier or an integer in "
1583 case Match_InvalidUImm20:
1585 case Match_InvalidUImm20AUIPC:
1586 return generateImmOutOfRangeError(
1588 "operand must be a symbol with a "
1589 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
1590 "an integer in the range");
1591 case Match_InvalidSImm21Lsb0JAL:
1592 return generateImmOutOfRangeError(
1594 "immediate must be a multiple of 2 bytes in the range");
1595 case Match_InvalidCSRSystemRegister: {
1597 "operand must be a valid system register "
1598 "name or an integer in the range");
1600 case Match_InvalidLoadFPImm: {
1602 return Error(ErrorLoc,
"operand must be a valid floating-point constant");
1604 case Match_InvalidBareSymbol: {
1606 return Error(ErrorLoc,
"operand must be a bare symbol name");
1608 case Match_InvalidPseudoJumpSymbol: {
1610 return Error(ErrorLoc,
"operand must be a valid jump target");
1612 case Match_InvalidCallSymbol: {
1614 return Error(ErrorLoc,
"operand must be a bare symbol name");
1616 case Match_InvalidTPRelAddSymbol: {
1618 return Error(ErrorLoc,
"operand must be a symbol with %tprel_add modifier");
1620 case Match_InvalidTLSDESCCallSymbol: {
1622 return Error(ErrorLoc,
1623 "operand must be a symbol with %tlsdesc_call modifier");
1625 case Match_InvalidRTZArg: {
1627 return Error(ErrorLoc,
"operand must be 'rtz' floating-point rounding mode");
1629 case Match_InvalidVTypeI: {
1631 return generateVTypeError(ErrorLoc);
1633 case Match_InvalidVMaskRegister: {
1635 return Error(ErrorLoc,
"operand must be v0.t");
1637 case Match_InvalidSImm5Plus1: {
1640 "immediate must be in the range");
1642 case Match_InvalidRlist: {
1646 "operand must be {ra [, s0[-sN]]} or {x1 [, x8[-x9][, x18[-xN]]]}");
1648 case Match_InvalidStackAdj: {
1652 "stack adjustment is invalid for this instruction and register list; "
1653 "refer to Zc spec for a detailed range of stack adjustment");
1655 case Match_InvalidRnumArg: {
1658 case Match_InvalidRegReg: {
1660 return Error(ErrorLoc,
"operands must be register and register");
1678 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1679 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1682 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1683 Reg = RISCV::NoRegister;
1689 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1690 return Error(StartLoc,
"invalid register name");
1696 const AsmToken &Tok = getParser().getTok();
1711 SMLoc FirstS = getLoc();
1712 bool HadParens =
false;
1719 size_t ReadCount = getLexer().peekTokens(Buf);
1722 LParen = getParser().getTok();
1727 switch (getLexer().getKind()) {
1730 getLexer().UnLex(LParen);
1738 getLexer().UnLex(LParen);
1742 Operands.push_back(RISCVOperand::createToken(
"(", FirstS));
1746 Operands.push_back(RISCVOperand::createReg(RegNo, S,
E));
1751 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
1762 switch (getLexer().getKind()) {
1772 if (getParser().parseExpression(Res,
E))
1775 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1777 int64_t
Imm =
CE->getValue();
1778 if (isUInt<7>(Imm)) {
1779 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1788 if (getParser().parseIdentifier(Identifier))
1791 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1793 assert(isUInt<7>(Opcode->Value) && (Opcode->Value & 0x3) == 3 &&
1794 "Unexpected opcode");
1797 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1807 return generateImmOutOfRangeError(
1809 "opcode must be a valid opcode name or an immediate in the range");
1817 switch (getLexer().getKind()) {
1827 if (getParser().parseExpression(Res,
E))
1830 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1832 int64_t
Imm =
CE->getValue();
1833 if (Imm >= 0 && Imm <= 2) {
1834 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1843 if (getParser().parseIdentifier(Identifier))
1847 if (Identifier ==
"C0")
1849 else if (Identifier ==
"C1")
1851 else if (Identifier ==
"C2")
1858 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1867 return generateImmOutOfRangeError(
1869 "opcode must be a valid opcode name or an immediate in the range");
1876 switch (getLexer().getKind()) {
1886 if (getParser().parseExpression(Res))
1889 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1891 int64_t
Imm =
CE->getValue();
1892 if (isUInt<12>(Imm)) {
1893 auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
1898 Operands.push_back(RISCVOperand::createSysReg(
Reg.Name, S, Imm));
1904 Operands.push_back(RISCVOperand::createSysReg(
"", S, Imm));
1909 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1913 if (getParser().parseIdentifier(Identifier))
1916 auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1918 SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier);
1920 if ((SysReg = RISCVSysReg::lookupSysRegByDeprecatedName(Identifier)))
1921 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
1922 SysReg->Name +
"'");
1926 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits()))
1927 return Error(S,
"system register use requires an option to be enabled");
1929 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
1933 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
1934 "operand must be a valid system register "
1935 "name or an integer in the range");
1939 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1952 if (
Identifier.compare_insensitive(
"inf") == 0) {
1955 getTok().getEndLoc(), isRV64()));
1956 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
1959 getTok().getEndLoc(), isRV64()));
1960 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
1963 getTok().getEndLoc(), isRV64()));
1965 return TokError(
"invalid floating point literal");
1978 return TokError(
"invalid floating point immediate");
1981 APFloat RealVal(APFloat::IEEEdouble());
1983 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
1985 return TokError(
"invalid floating point representation");
1988 RealVal.changeSign();
1990 Operands.push_back(RISCVOperand::createFPImm(
1991 RealVal.bitcastToAPInt().getZExtValue(), S));
2003 switch (getLexer().getKind()) {
2015 if (getParser().parseExpression(Res,
E))
2019 return parseOperandWithModifier(
Operands);
2022 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2034 return Error(getLoc(),
"expected valid identifier for operand modifier");
2038 return Error(getLoc(),
"unrecognized operand modifier");
2045 if (getParser().parseParenExpression(SubExpr,
E))
2049 Operands.push_back(RISCVOperand::createImm(ModExpr, S,
E, isRV64()));
2061 AsmToken Tok = getLexer().getTok();
2063 if (getParser().parseIdentifier(Identifier))
2069 return Error(getLoc(),
"'@plt' operand not valid for instruction");
2071 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
2073 if (
Sym->isVariable()) {
2074 const MCExpr *
V =
Sym->getVariableValue(
false);
2075 if (!isa<MCSymbolRefExpr>(V)) {
2076 getLexer().UnLex(Tok);
2084 switch (getLexer().getKind()) {
2086 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2099 if (getParser().parseExpression(Expr,
E))
2102 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2118 if (getParser().parseIdentifier(Identifier))
2126 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
2129 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2138 if (getParser().parseExpression(Res,
E))
2141 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef ||
2142 cast<MCSymbolRefExpr>(Res)->getKind() ==
2143 MCSymbolRefExpr::VariantKind::VK_PLT)
2144 return Error(S,
"operand must be a valid jump target");
2147 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2168bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2169 unsigned &Sew,
unsigned &Lmul,
2170 bool &Fractional,
bool &TailAgnostic,
2171 bool &MaskAgnostic) {
2178 case VTypeState_SEW:
2185 State = VTypeState_LMUL;
2187 case VTypeState_LMUL: {
2197 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2198 unsigned MinLMUL = ELEN / 8;
2201 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2202 Twine(MinLMUL) +
" is reserved");
2205 State = VTypeState_TailPolicy;
2208 case VTypeState_TailPolicy:
2209 if (Identifier ==
"ta")
2210 TailAgnostic =
true;
2211 else if (Identifier ==
"tu")
2212 TailAgnostic =
false;
2215 State = VTypeState_MaskPolicy;
2217 case VTypeState_MaskPolicy:
2218 if (Identifier ==
"ma")
2219 MaskAgnostic =
true;
2220 else if (Identifier ==
"mu")
2221 MaskAgnostic =
false;
2224 State = VTypeState_Done;
2226 case VTypeState_Done:
2239 bool Fractional =
false;
2240 bool TailAgnostic =
false;
2241 bool MaskAgnostic =
false;
2243 VTypeState State = VTypeState_SEW;
2246 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2253 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2263 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2264 unsigned MaxSEW = ELEN / Lmul;
2266 if (MaxSEW >= 8 && Sew > MaxSEW)
2268 "use of vtype encodings with SEW > " +
Twine(MaxSEW) +
2269 " and LMUL == mf" +
Twine(Lmul) +
2270 " may not be compatible with all RVV implementations");
2275 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2279 return generateVTypeError(S);
2282bool RISCVAsmParser::generateVTypeError(
SMLoc ErrorLoc) {
2286 "e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2294 if (!
Name.consume_back(
".t"))
2295 return Error(getLoc(),
"expected '.t' suffix");
2300 if (RegNo != RISCV::V0)
2305 Operands.push_back(RISCVOperand::createReg(RegNo, S,
E));
2321 Operands.push_back(RISCVOperand::createReg(
2322 RegNo, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2326template <
bool IsRV64>
2328 return parseGPRPair(
Operands, IsRV64);
2338 if (!IsRV64Inst && isRV64())
2350 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(RegNo))
2353 if ((RegNo - RISCV::X0) & 1)
2354 return TokError(
"register must be even");
2362 RegNo, RISCV::sub_gpr_even,
2363 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2364 Operands.push_back(RISCVOperand::createReg(Pair, S,
E));
2371 "operand must be a valid floating point rounding mode mnemonic");
2373 StringRef Str = getLexer().getTok().getIdentifier();
2378 "operand must be a valid floating point rounding mode mnemonic");
2380 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2386 const AsmToken &Tok = getLexer().getTok();
2392 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2406 for (
char c : Str) {
2435 Operands.push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2441 return TokError(
"operand must be formed of letters selected in-order from "
2448 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
2450 if (!parseRegister(
Operands).isSuccess())
2451 return Error(getLoc(),
"expected register");
2455 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2479 std::unique_ptr<RISCVOperand> OptionalImmOp;
2486 SMLoc ImmStart = getLoc();
2487 if (getParser().parseIntToken(ImmVal,
2488 "expected '(' or optional integer offset"))
2493 SMLoc ImmEnd = getLoc();
2496 ImmStart, ImmEnd, isRV64());
2500 OptionalImmOp ?
"expected '(' after optional integer offset"
2501 :
"expected '(' or optional integer offset"))
2504 if (!parseRegister(
Operands).isSuccess())
2505 return Error(getLoc(),
"expected register");
2511 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2513 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2514 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2527 return Error(getLoc(),
"invalid register");
2534 return Error(getLoc(),
"expected register");
2536 StringRef Reg2Name = getLexer().getTok().getIdentifier();
2539 return Error(getLoc(),
"invalid register");
2545 Operands.push_back(RISCVOperand::createRegReg(
Reg, Reg2, getLoc()));
2558 bool IsEABI = isRVE();
2561 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2566 if (RegStart != RISCV::X1)
2567 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2573 return Error(getLoc(),
"invalid register");
2577 return Error(getLoc(),
"invalid register");
2578 if (RegStart != RISCV::X8)
2579 return Error(getLoc(),
2580 "continuous register list must start from 's0' or 'x8'");
2586 StringRef EndName = getLexer().getTok().getIdentifier();
2590 return Error(getLoc(),
"invalid register");
2591 if (IsEABI && RegEnd != RISCV::X9)
2592 return Error(getLoc(),
"contiguous register list of EABI can only be "
2593 "'s0-s1' or 'x8-x9' pair");
2600 if (RegEnd != RISCV::X9)
2603 "first contiguous registers pair of register list must be 'x8-x9'");
2607 return Error(getLoc(),
"invalid register");
2608 StringRef EndName = getLexer().getTok().getIdentifier();
2610 return Error(getLoc(),
2611 "second contiguous registers pair of register list "
2612 "must start from 'x18'");
2618 return Error(getLoc(),
"invalid register");
2619 EndName = getLexer().getTok().getIdentifier();
2621 return Error(getLoc(),
"invalid register");
2628 if (RegEnd == RISCV::X26)
2629 return Error(getLoc(),
"invalid register list, {ra, s0-s10} or {x1, x8-x9, "
2630 "x18-x26} is not supported");
2635 if (RegEnd == RISCV::NoRegister)
2640 return Error(S,
"invalid register list");
2641 Operands.push_back(RISCVOperand::createRlist(Encode, S));
2647 bool ExpectNegative) {
2653 unsigned RlistVal =
static_cast<RISCVOperand *
>(
Operands[1].get())->Rlist.Val;
2655 if (Negative != ExpectNegative ||
2658 Operands.push_back(RISCVOperand::createSpimm(Spimm << 4, S));
2670 MatchOperandParserImpl(
Operands, Mnemonic,
true);
2677 if (parseRegister(
Operands,
true).isSuccess())
2684 return !parseMemOpBaseReg(
Operands).isSuccess();
2689 Error(getLoc(),
"unknown operand");
2702 if (getSTI().hasFeature(RISCV::FeatureRelax)) {
2703 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
2704 if (Assembler !=
nullptr) {
2712 Operands.push_back(RISCVOperand::createToken(
Name, NameLoc));
2731 if (getParser().parseEOL(
"unexpected token")) {
2732 getParser().eatToEndOfStatement();
2738bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
2742 if (
const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
2743 Kind = RE->getKind();
2744 Expr = RE->getSubExpr();
2754bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
2767 if (IDVal ==
".option")
2768 return parseDirectiveOption();
2769 if (IDVal ==
".attribute")
2770 return parseDirectiveAttribute();
2771 if (IDVal ==
".insn")
2772 return parseDirectiveInsn(DirectiveID.
getLoc());
2773 if (IDVal ==
".variant_cc")
2774 return parseDirectiveVariantCC();
2779bool RISCVAsmParser::resetToArch(
StringRef Arch,
SMLoc Loc, std::string &Result,
2780 bool FromOptionDirective) {
2783 clearFeatureBits(Feature.Value, Feature.Key);
2792 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
2793 << ErrMsg.getMessage();
2796 return Error(Loc, OutputErrMsg.str());
2801 if (ISAInfo->hasExtension(Feature.Key))
2802 setFeatureBits(Feature.Value, Feature.Key);
2804 if (FromOptionDirective) {
2805 if (ISAInfo->getXLen() == 32 && isRV64())
2806 return Error(Loc,
"bad arch string switching from rv64 to rv32");
2807 else if (ISAInfo->getXLen() == 64 && !isRV64())
2808 return Error(Loc,
"bad arch string switching from rv32 to rv64");
2811 if (ISAInfo->getXLen() == 32)
2812 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
2813 else if (ISAInfo->getXLen() == 64)
2814 setFeatureBits(RISCV::Feature64Bit,
"64bit");
2816 return Error(Loc,
"bad arch string " + Arch);
2818 Result = ISAInfo->toString();
2822bool RISCVAsmParser::parseDirectiveOption() {
2833 if (Option ==
"push") {
2837 getTargetStreamer().emitDirectiveOptionPush();
2842 if (Option ==
"pop") {
2847 getTargetStreamer().emitDirectiveOptionPop();
2848 if (popFeatureBits())
2849 return Error(StartLoc,
".option pop with no .option push");
2854 if (Option ==
"arch") {
2862 Type = RISCVOptionArchArgType::Plus;
2864 Type = RISCVOptionArchArgType::Minus;
2865 else if (!
Args.empty())
2867 "unexpected token, expected + or -");
2869 Type = RISCVOptionArchArgType::Full;
2873 "unexpected token, expected identifier");
2879 if (
Type == RISCVOptionArchArgType::Full) {
2881 if (resetToArch(Arch, Loc, Result,
true))
2890 Loc,
"extension version number parsing not currently implemented");
2893 if (!enableExperimentalExtension() &&
2895 return Error(Loc,
"unexpected experimental extensions");
2898 return Error(Loc,
"unknown extension feature");
2902 if (
Type == RISCVOptionArchArgType::Plus) {
2905 setFeatureBits(
Ext->Value,
Ext->Key);
2908 copySTI().setFeatureBits(OldFeatureBits);
2909 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
2914 OutputErrMsg << ErrMsg.getMessage();
2917 return Error(Loc, OutputErrMsg.str());
2920 assert(
Type == RISCVOptionArchArgType::Minus);
2925 if (getSTI().hasFeature(Feature.Value) &&
2926 Feature.Implies.test(
Ext->Value))
2928 " extension; " + Feature.Key +
2929 " extension requires " +
Ext->Key +
2933 clearFeatureBits(
Ext->Value,
Ext->Key);
2940 getTargetStreamer().emitDirectiveOptionArch(Args);
2944 if (Option ==
"rvc") {
2948 getTargetStreamer().emitDirectiveOptionRVC();
2949 setFeatureBits(RISCV::FeatureStdExtC,
"c");
2953 if (Option ==
"norvc") {
2957 getTargetStreamer().emitDirectiveOptionNoRVC();
2958 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
2959 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
2963 if (Option ==
"pic") {
2967 getTargetStreamer().emitDirectiveOptionPIC();
2968 ParserOptions.IsPicEnabled =
true;
2972 if (Option ==
"nopic") {
2976 getTargetStreamer().emitDirectiveOptionNoPIC();
2977 ParserOptions.IsPicEnabled =
false;
2981 if (Option ==
"relax") {
2985 getTargetStreamer().emitDirectiveOptionRelax();
2986 setFeatureBits(RISCV::FeatureRelax,
"relax");
2990 if (Option ==
"norelax") {
2994 getTargetStreamer().emitDirectiveOptionNoRelax();
2995 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3001 "'rvc', 'norvc', 'arch', 'relax' or "
3010bool RISCVAsmParser::parseDirectiveAttribute() {
3017 std::optional<unsigned>
Ret =
3020 return Error(TagLoc,
"attribute name not recognised: " +
Name);
3031 if (
check(!CE, TagLoc,
"expected numeric constant"))
3034 Tag =
CE->getValue();
3041 int64_t IntegerValue = 0;
3042 bool IsIntegerValue =
true;
3047 IsIntegerValue =
false;
3050 if (IsIntegerValue) {
3057 return Error(ValueExprLoc,
"expected numeric constant");
3058 IntegerValue =
CE->getValue();
3071 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3073 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3076 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3080 getTargetStreamer().emitTextAttribute(
Tag, Result);
3088 .
Cases(
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s",
true)
3089 .
Cases(
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj", AllowC)
3097bool RISCVAsmParser::parseDirectiveInsn(
SMLoc L) {
3100 bool AllowC = getSTI().hasFeature(RISCV::FeatureStdExtC) ||
3101 getSTI().hasFeature(RISCV::FeatureStdExtZca);
3111 Value,
"expected instruction format or an integer constant"))
3120 int64_t RealLength = (
Value & 3) == 3 ? 4 : 2;
3122 return Error(ErrorLoc,
"invalid operand for instruction");
3123 if (RealLength == 2 && !AllowC)
3124 return Error(ErrorLoc,
"compressed instructions are not allowed");
3126 return Error(ErrorLoc,
"instruction length mismatch");
3128 if (getParser().parseEOL(
"invalid operand for instruction")) {
3129 getParser().eatToEndOfStatement();
3133 emitToStreamer(getStreamer(),
MCInstBuilder(RealLength == 2 ? RISCV::Insn16
3140 return Error(ErrorLoc,
"invalid instruction format");
3142 std::string FormatName = (
".insn_" +
Format).str();
3159bool RISCVAsmParser::parseDirectiveVariantCC() {
3161 if (getParser().parseIdentifier(
Name))
3162 return TokError(
"expected symbol name");
3165 getTargetStreamer().emitDirectiveVariantCC(
3166 *getContext().getOrCreateSymbol(
Name));
3174 ++RISCVNumInstrsCompressed;
3183 for (
MCInst &Inst : Seq) {
3184 emitToStreamer(Out, Inst);
3191 unsigned SecondOpcode,
SMLoc IDLoc,
3205 const MCExpr *RefToLinkTmpLabel =
3212 .addExpr(RefToLinkTmpLabel));
3215void RISCVAsmParser::emitLoadLocalAddress(
MCInst &Inst,
SMLoc IDLoc,
3226 RISCV::ADDI, IDLoc, Out);
3229void RISCVAsmParser::emitLoadGlobalAddress(
MCInst &Inst,
SMLoc IDLoc,
3239 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3241 SecondOpcode, IDLoc, Out);
3244void RISCVAsmParser::emitLoadAddress(
MCInst &Inst,
SMLoc IDLoc,
3253 if (ParserOptions.IsPicEnabled)
3254 emitLoadGlobalAddress(Inst, IDLoc, Out);
3256 emitLoadLocalAddress(Inst, IDLoc, Out);
3259void RISCVAsmParser::emitLoadTLSIEAddress(
MCInst &Inst,
SMLoc IDLoc,
3269 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3271 SecondOpcode, IDLoc, Out);
3274void RISCVAsmParser::emitLoadTLSGDAddress(
MCInst &Inst,
SMLoc IDLoc,
3285 RISCV::ADDI, IDLoc, Out);
3288void RISCVAsmParser::emitLoadStoreSymbol(
MCInst &Inst,
unsigned Opcode,
3298 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3300 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3304 Opcode, IDLoc, Out);
3307void RISCVAsmParser::emitPseudoExtend(
MCInst &Inst,
bool SignExtend,
3308 int64_t Width,
SMLoc IDLoc,
3320 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3321 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3323 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3336void RISCVAsmParser::emitVMSGE(
MCInst &Inst,
unsigned Opcode,
SMLoc IDLoc,
3347 .addReg(RISCV::NoRegister)
3360 "The destination register should not be V0.");
3379 "The destination register should be V0.");
3381 "The temporary vector register should not be V0.");
3386 .addReg(RISCV::NoRegister)
3400 "The temporary vector register should not be V0.");
3405 .addReg(RISCV::NoRegister)
3425bool RISCVAsmParser::checkPseudoAddTPRel(
MCInst &Inst,
3427 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3430 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3431 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3432 "%tprel_add modifier");
3438bool RISCVAsmParser::checkPseudoTLSDESCCall(
MCInst &Inst,
3440 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
3443 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3444 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
3445 "%tlsdesc_call modifier");
3451std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3452 return RISCVOperand::createReg(RISCV::NoRegister,
llvm::SMLoc(),
3456std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3457 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3461std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3462 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3466bool RISCVAsmParser::validateInstruction(
MCInst &Inst,
3470 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3471 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3474 if (DestReg == TempReg) {
3476 return Error(Loc,
"the temporary vector register cannot be the same as "
3477 "the destination register");
3481 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3482 Opcode == RISCV::TH_LWD) {
3487 if (Rs1 == Rd1 && Rs1 == Rd2) {
3489 return Error(Loc,
"rs1, rd1, and rd2 cannot all be the same");
3493 if (Opcode == RISCV::CM_MVSA01) {
3498 return Error(Loc,
"rs1 and rs2 must be different");
3502 bool IsTHeadMemPair32 = (Opcode == RISCV::TH_LWD ||
3503 Opcode == RISCV::TH_LWUD || Opcode == RISCV::TH_SWD);
3504 bool IsTHeadMemPair64 = (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_SDD);
3509 return Error(Loc,
"operand must be constant 3");
3512 return Error(Loc,
"operand must be constant 4");
3519 if (Opcode == RISCV::VC_V_XVW || Opcode == RISCV::VC_V_IVW ||
3520 Opcode == RISCV::VC_V_FVW || Opcode == RISCV::VC_V_VVW) {
3526 if (VCIXDst == VCIXRs1)
3527 return Error(VCIXDstLoc,
"the destination vector register group cannot"
3528 " overlap the source vector register group");
3532 if (VCIXDst == VCIXRs2)
3533 return Error(VCIXDstLoc,
"the destination vector register group cannot"
3534 " overlap the source vector register group");
3549 if (DestReg == CheckReg)
3550 return Error(Loc,
"the destination vector register group cannot overlap"
3551 " the source vector register group");
3555 if (DestReg == CheckReg)
3556 return Error(Loc,
"the destination vector register group cannot overlap"
3557 " the source vector register group");
3562 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM ||
3563 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM ||
3564 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM ||
3565 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM ||
3566 Opcode == RISCV::VMERGE_VXM)
3567 return Error(Loc,
"the destination vector register group cannot be V0");
3574 assert((CheckReg == RISCV::V0 || CheckReg == RISCV::NoRegister) &&
3575 "Unexpected register for mask operand");
3577 if (DestReg == CheckReg)
3578 return Error(Loc,
"the destination vector register group cannot overlap"
3579 " the mask register");
3584bool RISCVAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
3592 case RISCV::PseudoLLAImm:
3593 case RISCV::PseudoLAImm:
3594 case RISCV::PseudoLI: {
3611 Imm = SignExtend64<32>(Imm);
3612 emitLoadImm(
Reg, Imm, Out);
3615 case RISCV::PseudoLLA:
3616 emitLoadLocalAddress(Inst, IDLoc, Out);
3618 case RISCV::PseudoLGA:
3619 emitLoadGlobalAddress(Inst, IDLoc, Out);
3621 case RISCV::PseudoLA:
3622 emitLoadAddress(Inst, IDLoc, Out);
3624 case RISCV::PseudoLA_TLS_IE:
3625 emitLoadTLSIEAddress(Inst, IDLoc, Out);
3627 case RISCV::PseudoLA_TLS_GD:
3628 emitLoadTLSGDAddress(Inst, IDLoc, Out);
3630 case RISCV::PseudoLB:
3631 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
3633 case RISCV::PseudoLBU:
3634 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
3636 case RISCV::PseudoLH:
3637 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
3639 case RISCV::PseudoLHU:
3640 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
3642 case RISCV::PseudoLW:
3643 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
3645 case RISCV::PseudoLWU:
3646 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
3648 case RISCV::PseudoLD:
3649 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
3651 case RISCV::PseudoFLH:
3652 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
3654 case RISCV::PseudoFLW:
3655 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
3657 case RISCV::PseudoFLD:
3658 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
3660 case RISCV::PseudoSB:
3661 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
3663 case RISCV::PseudoSH:
3664 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
3666 case RISCV::PseudoSW:
3667 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
3669 case RISCV::PseudoSD:
3670 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
3672 case RISCV::PseudoFSH:
3673 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
3675 case RISCV::PseudoFSW:
3676 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
3678 case RISCV::PseudoFSD:
3679 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
3681 case RISCV::PseudoAddTPRel:
3682 if (checkPseudoAddTPRel(Inst,
Operands))
3685 case RISCV::PseudoTLSDESCCall:
3686 if (checkPseudoTLSDESCCall(Inst,
Operands))
3689 case RISCV::PseudoSEXT_B:
3690 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
3692 case RISCV::PseudoSEXT_H:
3693 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
3695 case RISCV::PseudoZEXT_H:
3696 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
3698 case RISCV::PseudoZEXT_W:
3699 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
3701 case RISCV::PseudoVMSGEU_VX:
3702 case RISCV::PseudoVMSGEU_VX_M:
3703 case RISCV::PseudoVMSGEU_VX_M_T:
3704 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
3706 case RISCV::PseudoVMSGE_VX:
3707 case RISCV::PseudoVMSGE_VX_M:
3708 case RISCV::PseudoVMSGE_VX_M_T:
3709 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
3711 case RISCV::PseudoVMSGE_VI:
3712 case RISCV::PseudoVMSLT_VI: {
3716 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
3726 case RISCV::PseudoVMSGEU_VI:
3727 case RISCV::PseudoVMSLTU_VI: {
3734 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3745 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3760 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)
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)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
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.
bool parseIntToken(int64_t &V, const Twine &ErrMsg)
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 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.
ArrayRef< MCOperandInfo > operands() const
unsigned short NumOperands
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 createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createImm(int64_t Val)
unsigned 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.
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.
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
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...
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
ParseInstruction - Parse one assembly instruction.
virtual unsigned checkTargetMatchPredicate(MCInst &Inst)
checkTargetMatchPredicate - Validate the instruction match against any complex target predicates not ...
virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
MatchAndEmitInstruction - Recognize a series of operands of a parsed instruction as an actual MCInst ...
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.
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.