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_InvalidUImm1:
1488 case Match_InvalidUImm2:
1490 case Match_InvalidUImm2Lsb0:
1492 "immediate must be one of");
1493 case Match_InvalidUImm3:
1495 case Match_InvalidUImm4:
1497 case Match_InvalidUImm5:
1499 case Match_InvalidUImm6:
1501 case Match_InvalidUImm7:
1503 case Match_InvalidUImm8:
1505 case Match_InvalidUImm8GE32:
1507 case Match_InvalidSImm5:
1510 case Match_InvalidSImm6:
1513 case Match_InvalidSImm6NonZero:
1514 return generateImmOutOfRangeError(
1516 "immediate must be non-zero in the range");
1517 case Match_InvalidCLUIImm:
1518 return generateImmOutOfRangeError(
1520 "immediate must be in [0xfffe0, 0xfffff] or");
1521 case Match_InvalidUImm5Lsb0:
1522 return generateImmOutOfRangeError(
1524 "immediate must be a multiple of 2 bytes in the range");
1525 case Match_InvalidUImm6Lsb0:
1526 return generateImmOutOfRangeError(
1528 "immediate must be a multiple of 2 bytes in the range");
1529 case Match_InvalidUImm7Lsb00:
1530 return generateImmOutOfRangeError(
1532 "immediate must be a multiple of 4 bytes in the range");
1533 case Match_InvalidUImm8Lsb00:
1534 return generateImmOutOfRangeError(
1536 "immediate must be a multiple of 4 bytes in the range");
1537 case Match_InvalidUImm8Lsb000:
1538 return generateImmOutOfRangeError(
1540 "immediate must be a multiple of 8 bytes in the range");
1541 case Match_InvalidSImm9Lsb0:
1542 return generateImmOutOfRangeError(
1544 "immediate must be a multiple of 2 bytes in the range");
1545 case Match_InvalidUImm9Lsb000:
1546 return generateImmOutOfRangeError(
1548 "immediate must be a multiple of 8 bytes in the range");
1549 case Match_InvalidUImm10Lsb00NonZero:
1550 return generateImmOutOfRangeError(
1552 "immediate must be a multiple of 4 bytes in the range");
1553 case Match_InvalidSImm10Lsb0000NonZero:
1554 return generateImmOutOfRangeError(
1556 "immediate must be a multiple of 16 bytes and non-zero in the range");
1557 case Match_InvalidSImm12:
1558 return generateImmOutOfRangeError(
1560 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an "
1561 "integer in the range");
1562 case Match_InvalidSImm12Lsb0:
1563 return generateImmOutOfRangeError(
1565 "immediate must be a multiple of 2 bytes in the range");
1566 case Match_InvalidSImm12Lsb00000:
1567 return generateImmOutOfRangeError(
1569 "immediate must be a multiple of 32 bytes in the range");
1570 case Match_InvalidSImm13Lsb0:
1571 return generateImmOutOfRangeError(
1573 "immediate must be a multiple of 2 bytes in the range");
1574 case Match_InvalidUImm20LUI:
1576 "operand must be a symbol with "
1577 "%hi/%tprel_hi modifier or an integer in "
1579 case Match_InvalidUImm20:
1581 case Match_InvalidUImm20AUIPC:
1582 return generateImmOutOfRangeError(
1584 "operand must be a symbol with a "
1585 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
1586 "an integer in the range");
1587 case Match_InvalidSImm21Lsb0JAL:
1588 return generateImmOutOfRangeError(
1590 "immediate must be a multiple of 2 bytes in the range");
1591 case Match_InvalidCSRSystemRegister: {
1593 "operand must be a valid system register "
1594 "name or an integer in the range");
1596 case Match_InvalidLoadFPImm: {
1598 return Error(ErrorLoc,
"operand must be a valid floating-point constant");
1600 case Match_InvalidBareSymbol: {
1602 return Error(ErrorLoc,
"operand must be a bare symbol name");
1604 case Match_InvalidPseudoJumpSymbol: {
1606 return Error(ErrorLoc,
"operand must be a valid jump target");
1608 case Match_InvalidCallSymbol: {
1610 return Error(ErrorLoc,
"operand must be a bare symbol name");
1612 case Match_InvalidTPRelAddSymbol: {
1614 return Error(ErrorLoc,
"operand must be a symbol with %tprel_add modifier");
1616 case Match_InvalidTLSDESCCallSymbol: {
1618 return Error(ErrorLoc,
1619 "operand must be a symbol with %tlsdesc_call modifier");
1621 case Match_InvalidRTZArg: {
1623 return Error(ErrorLoc,
"operand must be 'rtz' floating-point rounding mode");
1625 case Match_InvalidVTypeI: {
1627 return generateVTypeError(ErrorLoc);
1629 case Match_InvalidVMaskRegister: {
1631 return Error(ErrorLoc,
"operand must be v0.t");
1633 case Match_InvalidSImm5Plus1: {
1636 "immediate must be in the range");
1638 case Match_InvalidRlist: {
1642 "operand must be {ra [, s0[-sN]]} or {x1 [, x8[-x9][, x18[-xN]]]}");
1644 case Match_InvalidStackAdj: {
1648 "stack adjustment is invalid for this instruction and register list; "
1649 "refer to Zc spec for a detailed range of stack adjustment");
1651 case Match_InvalidRnumArg: {
1654 case Match_InvalidRegReg: {
1656 return Error(ErrorLoc,
"operands must be register and register");
1674 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1675 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1678 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1679 Reg = RISCV::NoRegister;
1685 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1686 return Error(StartLoc,
"invalid register name");
1692 const AsmToken &Tok = getParser().getTok();
1707 SMLoc FirstS = getLoc();
1708 bool HadParens =
false;
1715 size_t ReadCount = getLexer().peekTokens(Buf);
1718 LParen = getParser().getTok();
1723 switch (getLexer().getKind()) {
1726 getLexer().UnLex(LParen);
1734 getLexer().UnLex(LParen);
1738 Operands.push_back(RISCVOperand::createToken(
"(", FirstS));
1742 Operands.push_back(RISCVOperand::createReg(RegNo, S,
E));
1747 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
1758 switch (getLexer().getKind()) {
1768 if (getParser().parseExpression(Res,
E))
1771 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1773 int64_t
Imm =
CE->getValue();
1774 if (isUInt<7>(Imm)) {
1775 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1784 if (getParser().parseIdentifier(Identifier))
1787 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1789 assert(isUInt<7>(Opcode->Value) && (Opcode->Value & 0x3) == 3 &&
1790 "Unexpected opcode");
1793 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1803 return generateImmOutOfRangeError(
1805 "opcode must be a valid opcode name or an immediate in the range");
1813 switch (getLexer().getKind()) {
1823 if (getParser().parseExpression(Res,
E))
1826 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1828 int64_t
Imm =
CE->getValue();
1829 if (Imm >= 0 && Imm <= 2) {
1830 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1839 if (getParser().parseIdentifier(Identifier))
1843 if (Identifier ==
"C0")
1845 else if (Identifier ==
"C1")
1847 else if (Identifier ==
"C2")
1854 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1863 return generateImmOutOfRangeError(
1865 "opcode must be a valid opcode name or an immediate in the range");
1872 switch (getLexer().getKind()) {
1882 if (getParser().parseExpression(Res))
1885 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1887 int64_t
Imm =
CE->getValue();
1888 if (isUInt<12>(Imm)) {
1889 auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
1894 Operands.push_back(RISCVOperand::createSysReg(
Reg.Name, S, Imm));
1900 Operands.push_back(RISCVOperand::createSysReg(
"", S, Imm));
1905 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1909 if (getParser().parseIdentifier(Identifier))
1912 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1914 SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier);
1916 if ((SysReg = RISCVSysReg::lookupSysRegByDeprecatedName(Identifier)))
1917 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
1918 SysReg->Name +
"'");
1922 const auto &FeatureBits = getSTI().getFeatureBits();
1923 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
1925 return SysReg->FeaturesRequired[Feature.Value];
1927 auto ErrorMsg = std::string(
"system register '") + SysReg->Name +
"' ";
1928 if (SysReg->isRV32Only && FeatureBits[RISCV::Feature64Bit]) {
1929 ErrorMsg +=
"is RV32 only";
1931 ErrorMsg +=
" and ";
1935 "requires '" + std::string(Feature->Key) +
"' to be enabled";
1938 return Error(S, ErrorMsg);
1941 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
1945 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
1946 "operand must be a valid system register "
1947 "name or an integer in the range");
1951 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1964 if (
Identifier.compare_insensitive(
"inf") == 0) {
1967 getTok().getEndLoc(), isRV64()));
1968 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
1971 getTok().getEndLoc(), isRV64()));
1972 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
1975 getTok().getEndLoc(), isRV64()));
1977 return TokError(
"invalid floating point literal");
1990 return TokError(
"invalid floating point immediate");
1993 APFloat RealVal(APFloat::IEEEdouble());
1995 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
1997 return TokError(
"invalid floating point representation");
2000 RealVal.changeSign();
2002 Operands.push_back(RISCVOperand::createFPImm(
2003 RealVal.bitcastToAPInt().getZExtValue(), S));
2015 switch (getLexer().getKind()) {
2027 if (getParser().parseExpression(Res,
E))
2031 return parseOperandWithModifier(
Operands);
2034 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2046 return Error(getLoc(),
"expected valid identifier for operand modifier");
2050 return Error(getLoc(),
"unrecognized operand modifier");
2057 if (getParser().parseParenExpression(SubExpr,
E))
2061 Operands.push_back(RISCVOperand::createImm(ModExpr, S,
E, isRV64()));
2073 AsmToken Tok = getLexer().getTok();
2075 if (getParser().parseIdentifier(Identifier))
2081 return Error(getLoc(),
"'@plt' operand not valid for instruction");
2083 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
2085 if (
Sym->isVariable()) {
2086 const MCExpr *
V =
Sym->getVariableValue(
false);
2087 if (!isa<MCSymbolRefExpr>(V)) {
2088 getLexer().UnLex(Tok);
2096 switch (getLexer().getKind()) {
2098 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2111 if (getParser().parseExpression(Expr,
E))
2114 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2130 if (getParser().parseIdentifier(Identifier))
2138 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
2141 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2150 if (getParser().parseExpression(Res,
E))
2153 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef ||
2154 cast<MCSymbolRefExpr>(Res)->getKind() ==
2155 MCSymbolRefExpr::VariantKind::VK_PLT)
2156 return Error(S,
"operand must be a valid jump target");
2159 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2180bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2181 unsigned &Sew,
unsigned &Lmul,
2182 bool &Fractional,
bool &TailAgnostic,
2183 bool &MaskAgnostic) {
2190 case VTypeState_SEW:
2197 State = VTypeState_LMUL;
2199 case VTypeState_LMUL: {
2209 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2210 unsigned MinLMUL = ELEN / 8;
2213 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2214 Twine(MinLMUL) +
" is reserved");
2217 State = VTypeState_TailPolicy;
2220 case VTypeState_TailPolicy:
2221 if (Identifier ==
"ta")
2222 TailAgnostic =
true;
2223 else if (Identifier ==
"tu")
2224 TailAgnostic =
false;
2227 State = VTypeState_MaskPolicy;
2229 case VTypeState_MaskPolicy:
2230 if (Identifier ==
"ma")
2231 MaskAgnostic =
true;
2232 else if (Identifier ==
"mu")
2233 MaskAgnostic =
false;
2236 State = VTypeState_Done;
2238 case VTypeState_Done:
2251 bool Fractional =
false;
2252 bool TailAgnostic =
false;
2253 bool MaskAgnostic =
false;
2255 VTypeState State = VTypeState_SEW;
2258 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2265 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2275 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2276 unsigned MaxSEW = ELEN / Lmul;
2278 if (MaxSEW >= 8 && Sew > MaxSEW)
2280 "use of vtype encodings with SEW > " +
Twine(MaxSEW) +
2281 " and LMUL == mf" +
Twine(Lmul) +
2282 " may not be compatible with all RVV implementations");
2287 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2291 return generateVTypeError(S);
2294bool RISCVAsmParser::generateVTypeError(
SMLoc ErrorLoc) {
2298 "e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2306 if (!
Name.consume_back(
".t"))
2307 return Error(getLoc(),
"expected '.t' suffix");
2312 if (RegNo != RISCV::V0)
2317 Operands.push_back(RISCVOperand::createReg(RegNo, S,
E));
2333 Operands.push_back(RISCVOperand::createReg(
2334 RegNo, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2338template <
bool IsRV64>
2340 return parseGPRPair(
Operands, IsRV64);
2350 if (!IsRV64Inst && isRV64())
2362 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(RegNo))
2365 if ((RegNo - RISCV::X0) & 1)
2366 return TokError(
"register must be even");
2374 RegNo, RISCV::sub_gpr_even,
2375 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2376 Operands.push_back(RISCVOperand::createReg(Pair, S,
E));
2383 "operand must be a valid floating point rounding mode mnemonic");
2385 StringRef Str = getLexer().getTok().getIdentifier();
2390 "operand must be a valid floating point rounding mode mnemonic");
2392 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2398 const AsmToken &Tok = getLexer().getTok();
2404 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2418 for (
char c : Str) {
2447 Operands.push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2453 return TokError(
"operand must be formed of letters selected in-order from "
2460 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
2462 if (!parseRegister(
Operands).isSuccess())
2463 return Error(getLoc(),
"expected register");
2467 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2491 std::unique_ptr<RISCVOperand> OptionalImmOp;
2498 SMLoc ImmStart = getLoc();
2499 if (getParser().parseIntToken(ImmVal,
2500 "expected '(' or optional integer offset"))
2505 SMLoc ImmEnd = getLoc();
2508 ImmStart, ImmEnd, isRV64());
2512 OptionalImmOp ?
"expected '(' after optional integer offset"
2513 :
"expected '(' or optional integer offset"))
2516 if (!parseRegister(
Operands).isSuccess())
2517 return Error(getLoc(),
"expected register");
2523 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2525 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2526 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2539 return Error(getLoc(),
"invalid register");
2546 return Error(getLoc(),
"expected register");
2548 StringRef Reg2Name = getLexer().getTok().getIdentifier();
2551 return Error(getLoc(),
"invalid register");
2557 Operands.push_back(RISCVOperand::createRegReg(
Reg, Reg2, getLoc()));
2570 bool IsEABI = isRVE();
2573 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2578 if (RegStart != RISCV::X1)
2579 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2585 return Error(getLoc(),
"invalid register");
2589 return Error(getLoc(),
"invalid register");
2590 if (RegStart != RISCV::X8)
2591 return Error(getLoc(),
2592 "continuous register list must start from 's0' or 'x8'");
2598 StringRef EndName = getLexer().getTok().getIdentifier();
2602 return Error(getLoc(),
"invalid register");
2603 if (IsEABI && RegEnd != RISCV::X9)
2604 return Error(getLoc(),
"contiguous register list of EABI can only be "
2605 "'s0-s1' or 'x8-x9' pair");
2612 if (RegEnd != RISCV::X9)
2615 "first contiguous registers pair of register list must be 'x8-x9'");
2619 return Error(getLoc(),
"invalid register");
2620 StringRef EndName = getLexer().getTok().getIdentifier();
2622 return Error(getLoc(),
2623 "second contiguous registers pair of register list "
2624 "must start from 'x18'");
2630 return Error(getLoc(),
"invalid register");
2631 EndName = getLexer().getTok().getIdentifier();
2633 return Error(getLoc(),
"invalid register");
2640 if (RegEnd == RISCV::X26)
2641 return Error(getLoc(),
"invalid register list, {ra, s0-s10} or {x1, x8-x9, "
2642 "x18-x26} is not supported");
2647 if (RegEnd == RISCV::NoRegister)
2652 return Error(S,
"invalid register list");
2653 Operands.push_back(RISCVOperand::createRlist(Encode, S));
2659 bool ExpectNegative) {
2665 unsigned RlistVal =
static_cast<RISCVOperand *
>(
Operands[1].get())->Rlist.Val;
2667 if (Negative != ExpectNegative ||
2670 Operands.push_back(RISCVOperand::createSpimm(Spimm << 4, S));
2682 MatchOperandParserImpl(
Operands, Mnemonic,
true);
2689 if (parseRegister(
Operands,
true).isSuccess())
2696 return !parseMemOpBaseReg(
Operands).isSuccess();
2701 Error(getLoc(),
"unknown operand");
2714 if (getSTI().hasFeature(RISCV::FeatureRelax)) {
2715 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
2716 if (Assembler !=
nullptr) {
2724 Operands.push_back(RISCVOperand::createToken(
Name, NameLoc));
2743 if (getParser().parseEOL(
"unexpected token")) {
2744 getParser().eatToEndOfStatement();
2750bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
2754 if (
const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
2755 Kind = RE->getKind();
2756 Expr = RE->getSubExpr();
2766bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
2779 if (IDVal ==
".option")
2780 return parseDirectiveOption();
2781 if (IDVal ==
".attribute")
2782 return parseDirectiveAttribute();
2783 if (IDVal ==
".insn")
2784 return parseDirectiveInsn(DirectiveID.
getLoc());
2785 if (IDVal ==
".variant_cc")
2786 return parseDirectiveVariantCC();
2791bool RISCVAsmParser::resetToArch(
StringRef Arch,
SMLoc Loc, std::string &Result,
2792 bool FromOptionDirective) {
2795 clearFeatureBits(Feature.Value, Feature.Key);
2804 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
2805 << ErrMsg.getMessage();
2808 return Error(Loc, OutputErrMsg.str());
2813 if (ISAInfo->hasExtension(Feature.Key))
2814 setFeatureBits(Feature.Value, Feature.Key);
2816 if (FromOptionDirective) {
2817 if (ISAInfo->getXLen() == 32 && isRV64())
2818 return Error(Loc,
"bad arch string switching from rv64 to rv32");
2819 else if (ISAInfo->getXLen() == 64 && !isRV64())
2820 return Error(Loc,
"bad arch string switching from rv32 to rv64");
2823 if (ISAInfo->getXLen() == 32)
2824 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
2825 else if (ISAInfo->getXLen() == 64)
2826 setFeatureBits(RISCV::Feature64Bit,
"64bit");
2828 return Error(Loc,
"bad arch string " + Arch);
2830 Result = ISAInfo->toString();
2834bool RISCVAsmParser::parseDirectiveOption() {
2845 if (Option ==
"push") {
2849 getTargetStreamer().emitDirectiveOptionPush();
2854 if (Option ==
"pop") {
2859 getTargetStreamer().emitDirectiveOptionPop();
2860 if (popFeatureBits())
2861 return Error(StartLoc,
".option pop with no .option push");
2866 if (Option ==
"arch") {
2874 Type = RISCVOptionArchArgType::Plus;
2876 Type = RISCVOptionArchArgType::Minus;
2877 else if (!
Args.empty())
2879 "unexpected token, expected + or -");
2881 Type = RISCVOptionArchArgType::Full;
2885 "unexpected token, expected identifier");
2891 if (
Type == RISCVOptionArchArgType::Full) {
2893 if (resetToArch(Arch, Loc, Result,
true))
2902 Loc,
"extension version number parsing not currently implemented");
2905 if (!enableExperimentalExtension() &&
2907 return Error(Loc,
"unexpected experimental extensions");
2910 return Error(Loc,
"unknown extension feature");
2914 if (
Type == RISCVOptionArchArgType::Plus) {
2917 setFeatureBits(
Ext->Value,
Ext->Key);
2920 copySTI().setFeatureBits(OldFeatureBits);
2921 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
2926 OutputErrMsg << ErrMsg.getMessage();
2929 return Error(Loc, OutputErrMsg.str());
2932 assert(
Type == RISCVOptionArchArgType::Minus);
2937 if (getSTI().hasFeature(Feature.Value) &&
2938 Feature.Implies.test(
Ext->Value))
2940 " extension; " + Feature.Key +
2941 " extension requires " +
Ext->Key +
2945 clearFeatureBits(
Ext->Value,
Ext->Key);
2952 getTargetStreamer().emitDirectiveOptionArch(Args);
2956 if (Option ==
"rvc") {
2960 getTargetStreamer().emitDirectiveOptionRVC();
2961 setFeatureBits(RISCV::FeatureStdExtC,
"c");
2965 if (Option ==
"norvc") {
2969 getTargetStreamer().emitDirectiveOptionNoRVC();
2970 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
2971 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
2975 if (Option ==
"pic") {
2979 getTargetStreamer().emitDirectiveOptionPIC();
2980 ParserOptions.IsPicEnabled =
true;
2984 if (Option ==
"nopic") {
2988 getTargetStreamer().emitDirectiveOptionNoPIC();
2989 ParserOptions.IsPicEnabled =
false;
2993 if (Option ==
"relax") {
2997 getTargetStreamer().emitDirectiveOptionRelax();
2998 setFeatureBits(RISCV::FeatureRelax,
"relax");
3002 if (Option ==
"norelax") {
3006 getTargetStreamer().emitDirectiveOptionNoRelax();
3007 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3013 "'rvc', 'norvc', 'arch', 'relax' or "
3022bool RISCVAsmParser::parseDirectiveAttribute() {
3029 std::optional<unsigned>
Ret =
3032 return Error(TagLoc,
"attribute name not recognised: " +
Name);
3043 if (check(!CE, TagLoc,
"expected numeric constant"))
3046 Tag =
CE->getValue();
3053 int64_t IntegerValue = 0;
3054 bool IsIntegerValue =
true;
3059 IsIntegerValue =
false;
3062 if (IsIntegerValue) {
3069 return Error(ValueExprLoc,
"expected numeric constant");
3070 IntegerValue =
CE->getValue();
3083 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3085 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3088 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3092 getTargetStreamer().emitTextAttribute(
Tag, Result);
3100 .
Cases(
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s",
true)
3101 .
Cases(
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj", AllowC)
3109bool RISCVAsmParser::parseDirectiveInsn(
SMLoc L) {
3112 bool AllowC = getSTI().hasFeature(RISCV::FeatureStdExtC) ||
3113 getSTI().hasFeature(RISCV::FeatureStdExtZca);
3123 Value,
"expected instruction format or an integer constant"))
3132 int64_t RealLength = (
Value & 3) == 3 ? 4 : 2;
3134 return Error(ErrorLoc,
"invalid operand for instruction");
3135 if (RealLength == 2 && !AllowC)
3136 return Error(ErrorLoc,
"compressed instructions are not allowed");
3138 return Error(ErrorLoc,
"instruction length mismatch");
3140 if (getParser().parseEOL(
"invalid operand for instruction")) {
3141 getParser().eatToEndOfStatement();
3145 emitToStreamer(getStreamer(),
MCInstBuilder(RealLength == 2 ? RISCV::Insn16
3152 return Error(ErrorLoc,
"invalid instruction format");
3154 std::string FormatName = (
".insn_" +
Format).str();
3171bool RISCVAsmParser::parseDirectiveVariantCC() {
3173 if (getParser().parseIdentifier(
Name))
3174 return TokError(
"expected symbol name");
3177 getTargetStreamer().emitDirectiveVariantCC(
3178 *getContext().getOrCreateSymbol(
Name));
3186 ++RISCVNumInstrsCompressed;
3195 for (
MCInst &Inst : Seq) {
3196 emitToStreamer(Out, Inst);
3203 unsigned SecondOpcode,
SMLoc IDLoc,
3217 const MCExpr *RefToLinkTmpLabel =
3224 .addExpr(RefToLinkTmpLabel));
3227void RISCVAsmParser::emitLoadLocalAddress(
MCInst &Inst,
SMLoc IDLoc,
3238 RISCV::ADDI, IDLoc, Out);
3241void RISCVAsmParser::emitLoadGlobalAddress(
MCInst &Inst,
SMLoc IDLoc,
3251 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3253 SecondOpcode, IDLoc, Out);
3256void RISCVAsmParser::emitLoadAddress(
MCInst &Inst,
SMLoc IDLoc,
3265 if (ParserOptions.IsPicEnabled)
3266 emitLoadGlobalAddress(Inst, IDLoc, Out);
3268 emitLoadLocalAddress(Inst, IDLoc, Out);
3271void RISCVAsmParser::emitLoadTLSIEAddress(
MCInst &Inst,
SMLoc IDLoc,
3281 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3283 SecondOpcode, IDLoc, Out);
3286void RISCVAsmParser::emitLoadTLSGDAddress(
MCInst &Inst,
SMLoc IDLoc,
3297 RISCV::ADDI, IDLoc, Out);
3300void RISCVAsmParser::emitLoadStoreSymbol(
MCInst &Inst,
unsigned Opcode,
3310 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3312 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3316 Opcode, IDLoc, Out);
3319void RISCVAsmParser::emitPseudoExtend(
MCInst &Inst,
bool SignExtend,
3320 int64_t Width,
SMLoc IDLoc,
3332 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3333 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3335 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3348void RISCVAsmParser::emitVMSGE(
MCInst &Inst,
unsigned Opcode,
SMLoc IDLoc,
3359 .addReg(RISCV::NoRegister)
3372 "The destination register should not be V0.");
3391 "The destination register should be V0.");
3393 "The temporary vector register should not be V0.");
3398 .addReg(RISCV::NoRegister)
3412 "The temporary vector register should not be V0.");
3417 .addReg(RISCV::NoRegister)
3437bool RISCVAsmParser::checkPseudoAddTPRel(
MCInst &Inst,
3439 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3442 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3443 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3444 "%tprel_add modifier");
3450bool RISCVAsmParser::checkPseudoTLSDESCCall(
MCInst &Inst,
3452 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
3455 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3456 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
3457 "%tlsdesc_call modifier");
3463std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3464 return RISCVOperand::createReg(RISCV::NoRegister,
llvm::SMLoc(),
3468std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3469 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3473std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3474 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3478bool RISCVAsmParser::validateInstruction(
MCInst &Inst,
3482 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3483 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3486 if (DestReg == TempReg) {
3488 return Error(Loc,
"the temporary vector register cannot be the same as "
3489 "the destination register");
3493 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3494 Opcode == RISCV::TH_LWD) {
3499 if (Rs1 == Rd1 && Rs1 == Rd2) {
3501 return Error(Loc,
"rs1, rd1, and rd2 cannot all be the same");
3505 if (Opcode == RISCV::CM_MVSA01) {
3510 return Error(Loc,
"rs1 and rs2 must be different");
3514 bool IsTHeadMemPair32 = (Opcode == RISCV::TH_LWD ||
3515 Opcode == RISCV::TH_LWUD || Opcode == RISCV::TH_SWD);
3516 bool IsTHeadMemPair64 = (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_SDD);
3521 return Error(Loc,
"operand must be constant 3");
3524 return Error(Loc,
"operand must be constant 4");
3531 if (Opcode == RISCV::VC_V_XVW || Opcode == RISCV::VC_V_IVW ||
3532 Opcode == RISCV::VC_V_FVW || Opcode == RISCV::VC_V_VVW) {
3538 if (VCIXDst == VCIXRs1)
3539 return Error(VCIXDstLoc,
"the destination vector register group cannot"
3540 " overlap the source vector register group");
3544 if (VCIXDst == VCIXRs2)
3545 return Error(VCIXDstLoc,
"the destination vector register group cannot"
3546 " overlap the source vector register group");
3561 if (DestReg == CheckReg)
3562 return Error(Loc,
"the destination vector register group cannot overlap"
3563 " the source vector register group");
3567 if (DestReg == CheckReg)
3568 return Error(Loc,
"the destination vector register group cannot overlap"
3569 " the source vector register group");
3574 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM ||
3575 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM ||
3576 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM ||
3577 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM ||
3578 Opcode == RISCV::VMERGE_VXM)
3579 return Error(Loc,
"the destination vector register group cannot be V0");
3586 assert((CheckReg == RISCV::V0 || CheckReg == RISCV::NoRegister) &&
3587 "Unexpected register for mask operand");
3589 if (DestReg == CheckReg)
3590 return Error(Loc,
"the destination vector register group cannot overlap"
3591 " the mask register");
3596bool RISCVAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
3604 case RISCV::PseudoLLAImm:
3605 case RISCV::PseudoLAImm:
3606 case RISCV::PseudoLI: {
3623 Imm = SignExtend64<32>(Imm);
3624 emitLoadImm(
Reg, Imm, Out);
3627 case RISCV::PseudoLLA:
3628 emitLoadLocalAddress(Inst, IDLoc, Out);
3630 case RISCV::PseudoLGA:
3631 emitLoadGlobalAddress(Inst, IDLoc, Out);
3633 case RISCV::PseudoLA:
3634 emitLoadAddress(Inst, IDLoc, Out);
3636 case RISCV::PseudoLA_TLS_IE:
3637 emitLoadTLSIEAddress(Inst, IDLoc, Out);
3639 case RISCV::PseudoLA_TLS_GD:
3640 emitLoadTLSGDAddress(Inst, IDLoc, Out);
3642 case RISCV::PseudoLB:
3643 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
3645 case RISCV::PseudoLBU:
3646 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
3648 case RISCV::PseudoLH:
3649 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
3651 case RISCV::PseudoLHU:
3652 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
3654 case RISCV::PseudoLW:
3655 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
3657 case RISCV::PseudoLWU:
3658 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
3660 case RISCV::PseudoLD:
3661 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
3663 case RISCV::PseudoFLH:
3664 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
3666 case RISCV::PseudoFLW:
3667 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
3669 case RISCV::PseudoFLD:
3670 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
3672 case RISCV::PseudoSB:
3673 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
3675 case RISCV::PseudoSH:
3676 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
3678 case RISCV::PseudoSW:
3679 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
3681 case RISCV::PseudoSD:
3682 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
3684 case RISCV::PseudoFSH:
3685 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
3687 case RISCV::PseudoFSW:
3688 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
3690 case RISCV::PseudoFSD:
3691 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
3693 case RISCV::PseudoAddTPRel:
3694 if (checkPseudoAddTPRel(Inst,
Operands))
3697 case RISCV::PseudoTLSDESCCall:
3698 if (checkPseudoTLSDESCCall(Inst,
Operands))
3701 case RISCV::PseudoSEXT_B:
3702 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
3704 case RISCV::PseudoSEXT_H:
3705 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
3707 case RISCV::PseudoZEXT_H:
3708 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
3710 case RISCV::PseudoZEXT_W:
3711 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
3713 case RISCV::PseudoVMSGEU_VX:
3714 case RISCV::PseudoVMSGEU_VX_M:
3715 case RISCV::PseudoVMSGEU_VX_M_T:
3716 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
3718 case RISCV::PseudoVMSGE_VX:
3719 case RISCV::PseudoVMSGE_VX_M:
3720 case RISCV::PseudoVMSGE_VX_M_T:
3721 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
3723 case RISCV::PseudoVMSGE_VI:
3724 case RISCV::PseudoVMSLT_VI: {
3728 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
3738 case RISCV::PseudoVMSGEU_VI:
3739 case RISCV::PseudoVMSLTU_VI: {
3746 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3757 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3772 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.
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.