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;
90 "do not have a target streamer");
96 unsigned Kind)
override;
102 bool generateImmOutOfRangeError(
SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
108 bool MatchingInlineAsm)
override;
113 SMLoc &EndLoc)
override;
120 bool parseVTypeToken(
StringRef Identifier, VTypeState &State,
unsigned &Sew,
121 unsigned &Lmul,
bool &Fractional,
bool &TailAgnostic,
123 bool generateVTypeError(
SMLoc ErrorLoc);
157 void emitLoadStoreSymbol(
MCInst &Inst,
unsigned Opcode,
SMLoc IDLoc,
161 void emitPseudoExtend(
MCInst &Inst,
bool SignExtend, int64_t Width,
190#define GET_ASSEMBLER_HEADER
191#include "RISCVGenAsmMatcher.inc"
220 bool parseDirectiveOption();
221 bool parseDirectiveAttribute();
222 bool parseDirectiveInsn(
SMLoc L);
223 bool parseDirectiveVariantCC();
229 bool FromOptionDirective);
232 if (!(
getSTI().hasFeature(Feature))) {
240 if (
getSTI().hasFeature(Feature)) {
247 void pushFeatureBits() {
249 "These two stacks must be kept synchronized");
251 ParserOptionsStack.
push_back(ParserOptions);
254 bool popFeatureBits() {
256 "These two stacks must be kept synchronized");
257 if (FeatureBitStack.
empty())
269 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
270 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
271 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
274 enum RISCVMatchResultTy {
276 Match_RequiresEvenGPRs,
277#define GET_OPERAND_DIAGNOSTIC_TYPES
278#include "RISCVGenAsmMatcher.inc"
279#undef GET_OPERAND_DIAGNOSTIC_TYPES
282 static bool classifySymbolRef(
const MCExpr *Expr,
284 static bool isSymbolDiff(
const MCExpr *Expr);
298 if (ABIName.ends_with(
"f") && !getSTI().hasFeature(RISCV::FeatureStdExtF)) {
299 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
300 "doesn't support the F instruction set extension (ignoring "
302 }
else if (ABIName.ends_with(
"d") &&
303 !getSTI().hasFeature(RISCV::FeatureStdExtD)) {
304 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
305 "doesn't support the D instruction set extension (ignoring "
318 getTargetStreamer().emitTargetAttributes(STI,
false);
387 SMLoc StartLoc, EndLoc;
393 struct SysRegOp SysReg;
394 struct VTypeOp VType;
396 struct FenceOp Fence;
397 struct RlistOp Rlist;
398 struct SpimmOp Spimm;
402 RISCVOperand(KindTy K) :
Kind(
K) {}
407 StartLoc =
o.StartLoc;
410 case KindTy::Register:
413 case KindTy::Immediate:
416 case KindTy::FPImmediate:
422 case KindTy::SystemRegister:
446 bool isToken()
const override {
return Kind == KindTy::Token; }
447 bool isReg()
const override {
return Kind == KindTy::Register; }
448 bool isV0Reg()
const {
449 return Kind == KindTy::Register &&
Reg.RegNum == RISCV::V0;
451 bool isAnyReg()
const {
452 return Kind == KindTy::Register &&
453 (RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.RegNum) ||
454 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg.RegNum) ||
455 RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg.RegNum));
457 bool isAnyRegC()
const {
458 return Kind == KindTy::Register &&
459 (RISCVMCRegisterClasses[RISCV::GPRCRegClassID].contains(
461 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
464 bool isImm()
const override {
return Kind == KindTy::Immediate; }
465 bool isMem()
const override {
return false; }
466 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
467 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
468 bool isRlist()
const {
return Kind == KindTy::Rlist; }
469 bool isSpimm()
const {
return Kind == KindTy::Spimm; }
472 return Kind == KindTy::Register &&
473 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.RegNum);
476 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
478 bool isGPRPair()
const {
479 return Kind == KindTy::Register &&
480 RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(
484 static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &Imm,
486 if (
auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
488 return RE->evaluateAsConstant(Imm);
491 if (
auto CE = dyn_cast<MCConstantExpr>(Expr)) {
493 Imm =
CE->getValue();
502 template <
int N>
bool isBareSimmNLsb0()
const {
507 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
510 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
518 bool isBareSymbol()
const {
522 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
524 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
528 bool isCallSymbol()
const {
532 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
534 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
539 bool isPseudoJumpSymbol()
const {
543 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
545 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
549 bool isTPRelAddSymbol()
const {
553 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
555 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
559 bool isTLSDESCCallSymbol()
const {
563 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
565 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
569 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
571 bool isVTypeImm(
unsigned N)
const {
576 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
582 bool isVTypeI10()
const {
583 if (Kind == KindTy::Immediate)
584 return isVTypeImm(10);
585 return Kind == KindTy::VType;
587 bool isVTypeI11()
const {
588 if (Kind == KindTy::Immediate)
589 return isVTypeImm(11);
590 return Kind == KindTy::VType;
595 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
598 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
599 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
603 bool isLoadFPImm()
const {
606 if (Kind != KindTy::FPImmediate)
609 APFloat(APFloat::IEEEdouble(),
APInt(64, getFPConst())));
612 return Idx >= 0 &&
Idx != 1;
615 bool isImmXLenLI()
const {
620 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
630 (isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm)));
633 return RISCVAsmParser::isSymbolDiff(getImm());
636 bool isImmXLenLI_Restricted()
const {
641 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
644 (isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm)));
647 bool isUImmLog2XLen()
const {
652 if (!evaluateConstantImm(getImm(), Imm, VK) ||
655 return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm);
658 bool isUImmLog2XLenNonZero()
const {
663 if (!evaluateConstantImm(getImm(), Imm, VK) ||
668 return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm);
671 bool isUImmLog2XLenHalf()
const {
676 if (!evaluateConstantImm(getImm(), Imm, VK) ||
679 return (isRV64Imm() && isUInt<5>(Imm)) || isUInt<4>(Imm);
682 template <
unsigned N>
bool IsUImm()
const {
687 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
691 bool isUImm1()
const {
return IsUImm<1>(); }
692 bool isUImm2()
const {
return IsUImm<2>(); }
693 bool isUImm3()
const {
return IsUImm<3>(); }
694 bool isUImm4()
const {
return IsUImm<4>(); }
695 bool isUImm5()
const {
return IsUImm<5>(); }
696 bool isUImm6()
const {
return IsUImm<6>(); }
697 bool isUImm7()
const {
return IsUImm<7>(); }
698 bool isUImm8()
const {
return IsUImm<8>(); }
699 bool isUImm20()
const {
return IsUImm<20>(); }
701 bool isUImm8GE32()
const {
706 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
707 return IsConstantImm && isUInt<8>(Imm) &&
Imm >= 32 &&
711 bool isRnumArg()
const {
716 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
717 return IsConstantImm &&
Imm >= INT64_C(0) &&
Imm <= INT64_C(10) &&
721 bool isRnumArg_0_7()
const {
726 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
727 return IsConstantImm &&
Imm >= INT64_C(0) &&
Imm <= INT64_C(7) &&
731 bool isRnumArg_1_10()
const {
736 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
737 return IsConstantImm &&
Imm >= INT64_C(1) &&
Imm <= INT64_C(10) &&
741 bool isRnumArg_2_14()
const {
746 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
747 return IsConstantImm &&
Imm >= INT64_C(2) &&
Imm <= INT64_C(14) &&
751 bool isSImm5()
const {
756 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
757 return IsConstantImm && isInt<5>(fixImmediateForRV32(Imm, isRV64Imm())) &&
761 bool isSImm6()
const {
766 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
767 return IsConstantImm && isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) &&
771 bool isSImm6NonZero()
const {
776 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
777 return IsConstantImm &&
Imm != 0 &&
778 isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) &&
782 bool isCLUIImm()
const {
787 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
788 return IsConstantImm && (
Imm != 0) &&
789 (isUInt<5>(Imm) || (
Imm >= 0xfffe0 &&
Imm <= 0xfffff)) &&
793 bool isUImm2Lsb0()
const {
798 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
799 return IsConstantImm && isShiftedUInt<1, 1>(Imm) &&
803 bool isUImm7Lsb00()
const {
808 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
809 return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
813 bool isUImm8Lsb00()
const {
818 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
819 return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
823 bool isUImm8Lsb000()
const {
828 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
829 return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
833 bool isSImm9Lsb0()
const {
return isBareSimmNLsb0<9>(); }
835 bool isUImm9Lsb000()
const {
840 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
841 return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
845 bool isUImm10Lsb00NonZero()
const {
850 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
851 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (
Imm != 0) &&
857 static int64_t fixImmediateForRV32(int64_t Imm,
bool IsRV64Imm) {
858 if (IsRV64Imm || !isUInt<32>(Imm))
860 return SignExtend64<32>(Imm);
863 bool isSImm12()
const {
869 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
871 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
873 IsValid = isInt<12>(fixImmediateForRV32(Imm, isRV64Imm()));
882 bool isSImm12Lsb0()
const {
return isBareSimmNLsb0<12>(); }
884 bool isSImm12Lsb00000()
const {
889 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
890 return IsConstantImm && isShiftedInt<7, 5>(Imm) &&
894 bool isSImm13Lsb0()
const {
return isBareSimmNLsb0<13>(); }
896 bool isSImm10Lsb0000NonZero()
const {
901 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
902 return IsConstantImm && (
Imm != 0) && isShiftedInt<6, 4>(Imm) &&
906 bool isUImm20LUI()
const {
912 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
913 if (!IsConstantImm) {
914 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
924 bool isUImm20AUIPC()
const {
930 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
931 if (!IsConstantImm) {
932 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
948 bool isSImm21Lsb0JAL()
const {
return isBareSimmNLsb0<21>(); }
950 bool isImmZero()
const {
955 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
959 bool isSImm5Plus1()
const {
964 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
965 return IsConstantImm &&
966 isInt<5>(fixImmediateForRV32(Imm, isRV64Imm()) - 1) &&
971 SMLoc getStartLoc()
const override {
return StartLoc; }
973 SMLoc getEndLoc()
const override {
return EndLoc; }
975 bool isRV64Imm()
const {
976 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
980 unsigned getReg()
const override {
981 assert(Kind == KindTy::Register &&
"Invalid type access!");
982 return Reg.RegNum.id();
986 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
987 return StringRef(SysReg.Data, SysReg.Length);
990 const MCExpr *getImm()
const {
991 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
996 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1001 assert(Kind == KindTy::Token &&
"Invalid type access!");
1005 unsigned getVType()
const {
1006 assert(Kind == KindTy::VType &&
"Invalid type access!");
1011 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1015 unsigned getFence()
const {
1016 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1029 case KindTy::Immediate:
1032 case KindTy::FPImmediate:
1034 case KindTy::Register:
1038 OS <<
"'" << getToken() <<
"'";
1040 case KindTy::SystemRegister:
1041 OS <<
"<sysreg: " << getSysReg() <<
'>';
1050 roundingModeToString(getFRM());
1068 case KindTy::RegReg:
1075 static std::unique_ptr<RISCVOperand> createToken(
StringRef Str,
SMLoc S) {
1076 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1083 static std::unique_ptr<RISCVOperand>
1084 createReg(
unsigned RegNo,
SMLoc S,
SMLoc E,
bool IsGPRAsFPR =
false) {
1085 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1086 Op->Reg.RegNum = RegNo;
1087 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1093 static std::unique_ptr<RISCVOperand> createImm(
const MCExpr *Val,
SMLoc S,
1095 auto Op = std::make_unique<RISCVOperand>(KindTy::Immediate);
1097 Op->Imm.IsRV64 = IsRV64;
1103 static std::unique_ptr<RISCVOperand> createFPImm(
uint64_t Val,
SMLoc S) {
1104 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1105 Op->FPImm.Val = Val;
1111 static std::unique_ptr<RISCVOperand> createSysReg(
StringRef Str,
SMLoc S,
1112 unsigned Encoding) {
1113 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1114 Op->SysReg.Data = Str.data();
1115 Op->SysReg.Length = Str.size();
1122 static std::unique_ptr<RISCVOperand>
1124 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1131 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val,
SMLoc S) {
1132 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1133 Op->Fence.Val = Val;
1139 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI,
SMLoc S) {
1140 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1141 Op->VType.Val = VTypeI;
1147 static std::unique_ptr<RISCVOperand> createRlist(
unsigned RlistEncode,
1149 auto Op = std::make_unique<RISCVOperand>(KindTy::Rlist);
1150 Op->Rlist.Val = RlistEncode;
1155 static std::unique_ptr<RISCVOperand> createRegReg(
unsigned Reg1No,
1156 unsigned Reg2No,
SMLoc S) {
1157 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1158 Op->RegReg.Reg1 = Reg1No;
1159 Op->RegReg.Reg2 = Reg2No;
1165 static std::unique_ptr<RISCVOperand> createSpimm(
unsigned Spimm,
SMLoc S) {
1166 auto Op = std::make_unique<RISCVOperand>(KindTy::Spimm);
1167 Op->Spimm.Val = Spimm;
1172 static void addExpr(
MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1173 assert(Expr &&
"Expr shouldn't be null!");
1176 bool IsConstant = evaluateConstantImm(Expr, Imm, VK);
1186 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1187 assert(
N == 1 &&
"Invalid number of operands!");
1191 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1192 assert(
N == 1 &&
"Invalid number of operands!");
1193 addExpr(Inst, getImm(), isRV64Imm());
1196 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
1197 assert(
N == 1 &&
"Invalid number of operands!");
1199 addExpr(Inst, getImm(), isRV64Imm());
1204 APFloat(APFloat::IEEEdouble(),
APInt(64, getFPConst())));
1208 void addFenceArgOperands(
MCInst &Inst,
unsigned N)
const {
1209 assert(
N == 1 &&
"Invalid number of operands!");
1213 void addCSRSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
1214 assert(
N == 1 &&
"Invalid number of operands!");
1221 void addVTypeIOperands(
MCInst &Inst,
unsigned N)
const {
1222 assert(
N == 1 &&
"Invalid number of operands!");
1224 if (Kind == KindTy::Immediate) {
1226 [[maybe_unused]]
bool IsConstantImm =
1227 evaluateConstantImm(getImm(), Imm, VK);
1228 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1235 void addRlistOperands(
MCInst &Inst,
unsigned N)
const {
1236 assert(
N == 1 &&
"Invalid number of operands!");
1240 void addRegRegOperands(
MCInst &Inst,
unsigned N)
const {
1241 assert(
N == 1 &&
"Invalid number of operands!");
1246 void addSpimmOperands(
MCInst &Inst,
unsigned N)
const {
1247 assert(
N == 1 &&
"Invalid number of operands!");
1251 void addFRMArgOperands(
MCInst &Inst,
unsigned N)
const {
1252 assert(
N == 1 &&
"Invalid number of operands!");
1258#define GET_REGISTER_MATCHER
1259#define GET_SUBTARGET_FEATURE_NAME
1260#define GET_MATCHER_IMPLEMENTATION
1261#define GET_MNEMONIC_SPELL_CHECKER
1262#include "RISCVGenAsmMatcher.inc"
1265 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1266 return Reg - RISCV::F0_D + RISCV::F0_H;
1270 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1271 return Reg - RISCV::F0_D + RISCV::F0_F;
1276 unsigned RegClassID;
1277 if (Kind == MCK_VRM2)
1278 RegClassID = RISCV::VRM2RegClassID;
1279 else if (Kind == MCK_VRM4)
1280 RegClassID = RISCV::VRM4RegClassID;
1281 else if (Kind == MCK_VRM8)
1282 RegClassID = RISCV::VRM8RegClassID;
1286 &RISCVMCRegisterClasses[RegClassID]);
1291 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1293 return Match_InvalidOperand;
1297 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg);
1299 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg);
1300 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg);
1304 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1305 (IsRegFPR64C &&
Kind == MCK_FPR32C)) {
1307 return Match_Success;
1311 if (IsRegFPR64 && Kind == MCK_FPR16) {
1313 return Match_Success;
1317 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1319 if (
Op.Reg.RegNum == 0)
1320 return Match_InvalidOperand;
1321 return Match_Success;
1323 return Match_InvalidOperand;
1326unsigned RISCVAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
1330 if (MCID.
operands()[
I].RegClass == RISCV::GPRPairRegClassID) {
1335 if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].
contains(
Reg))
1339 if (((
Reg.id() - RISCV::X0) & 1) != 0)
1340 return Match_RequiresEvenGPRs;
1344 return Match_Success;
1347bool RISCVAsmParser::generateImmOutOfRangeError(
1349 const Twine &Msg =
"immediate must be an integer in the range") {
1353bool RISCVAsmParser::generateImmOutOfRangeError(
1355 const Twine &Msg =
"immediate must be an integer in the range") {
1357 return generateImmOutOfRangeError(ErrorLoc,
Lower,
Upper, Msg);
1360bool RISCVAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1364 bool MatchingInlineAsm) {
1374 if (validateInstruction(Inst,
Operands))
1376 return processInstruction(Inst, IDLoc,
Operands, Out);
1377 case Match_MissingFeature: {
1378 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1379 bool FirstFeature =
true;
1380 std::string
Msg =
"instruction requires the following:";
1381 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1382 if (MissingFeatures[i]) {
1383 Msg += FirstFeature ?
" " :
", ";
1385 FirstFeature =
false;
1388 return Error(IDLoc, Msg);
1390 case Match_MnemonicFail: {
1391 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1392 std::string Suggestion = RISCVMnemonicSpellCheck(
1393 ((RISCVOperand &)*
Operands[0]).getToken(), FBS, 0);
1394 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1396 case Match_InvalidOperand: {
1397 SMLoc ErrorLoc = IDLoc;
1400 return Error(ErrorLoc,
"too few operands for instruction");
1403 if (ErrorLoc ==
SMLoc())
1406 return Error(ErrorLoc,
"invalid operand for instruction");
1413 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1414 SMLoc ErrorLoc = IDLoc;
1416 return Error(ErrorLoc,
"too few operands for instruction");
1422 case Match_RequiresEvenGPRs:
1424 "double precision floating point operands must use even "
1425 "numbered X register");
1426 case Match_InvalidImmXLenLI:
1429 return Error(ErrorLoc,
"operand must be a constant 64-bit integer");
1432 std::numeric_limits<int32_t>::min(),
1433 std::numeric_limits<uint32_t>::max());
1434 case Match_InvalidImmXLenLI_Restricted:
1437 return Error(ErrorLoc,
"operand either must be a constant 64-bit integer "
1438 "or a bare symbol name");
1440 return generateImmOutOfRangeError(
1442 std::numeric_limits<uint32_t>::max(),
1443 "operand either must be a bare symbol name or an immediate integer in "
1445 case Match_InvalidImmZero: {
1447 return Error(ErrorLoc,
"immediate must be zero");
1449 case Match_InvalidUImmLog2XLen:
1453 case Match_InvalidUImmLog2XLenNonZero:
1457 case Match_InvalidUImmLog2XLenHalf:
1461 case Match_InvalidUImm1:
1463 case Match_InvalidUImm2:
1465 case Match_InvalidUImm2Lsb0:
1467 "immediate must be one of");
1468 case Match_InvalidUImm3:
1470 case Match_InvalidUImm4:
1472 case Match_InvalidUImm5:
1474 case Match_InvalidUImm6:
1476 case Match_InvalidUImm7:
1478 case Match_InvalidUImm8:
1480 case Match_InvalidUImm8GE32:
1482 case Match_InvalidSImm5:
1485 case Match_InvalidSImm6:
1488 case Match_InvalidSImm6NonZero:
1489 return generateImmOutOfRangeError(
1491 "immediate must be non-zero in the range");
1492 case Match_InvalidCLUIImm:
1493 return generateImmOutOfRangeError(
1495 "immediate must be in [0xfffe0, 0xfffff] or");
1496 case Match_InvalidUImm7Lsb00:
1497 return generateImmOutOfRangeError(
1499 "immediate must be a multiple of 4 bytes in the range");
1500 case Match_InvalidUImm8Lsb00:
1501 return generateImmOutOfRangeError(
1503 "immediate must be a multiple of 4 bytes in the range");
1504 case Match_InvalidUImm8Lsb000:
1505 return generateImmOutOfRangeError(
1507 "immediate must be a multiple of 8 bytes in the range");
1508 case Match_InvalidSImm9Lsb0:
1509 return generateImmOutOfRangeError(
1511 "immediate must be a multiple of 2 bytes in the range");
1512 case Match_InvalidUImm9Lsb000:
1513 return generateImmOutOfRangeError(
1515 "immediate must be a multiple of 8 bytes in the range");
1516 case Match_InvalidUImm10Lsb00NonZero:
1517 return generateImmOutOfRangeError(
1519 "immediate must be a multiple of 4 bytes in the range");
1520 case Match_InvalidSImm10Lsb0000NonZero:
1521 return generateImmOutOfRangeError(
1523 "immediate must be a multiple of 16 bytes and non-zero in the range");
1524 case Match_InvalidSImm12:
1525 return generateImmOutOfRangeError(
1527 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an "
1528 "integer in the range");
1529 case Match_InvalidSImm12Lsb0:
1530 return generateImmOutOfRangeError(
1532 "immediate must be a multiple of 2 bytes in the range");
1533 case Match_InvalidSImm12Lsb00000:
1534 return generateImmOutOfRangeError(
1536 "immediate must be a multiple of 32 bytes in the range");
1537 case Match_InvalidSImm13Lsb0:
1538 return generateImmOutOfRangeError(
1540 "immediate must be a multiple of 2 bytes in the range");
1541 case Match_InvalidUImm20LUI:
1543 "operand must be a symbol with "
1544 "%hi/%tprel_hi modifier or an integer in "
1546 case Match_InvalidUImm20:
1548 case Match_InvalidUImm20AUIPC:
1549 return generateImmOutOfRangeError(
1551 "operand must be a symbol with a "
1552 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
1553 "an integer in the range");
1554 case Match_InvalidSImm21Lsb0JAL:
1555 return generateImmOutOfRangeError(
1557 "immediate must be a multiple of 2 bytes in the range");
1558 case Match_InvalidCSRSystemRegister: {
1560 "operand must be a valid system register "
1561 "name or an integer in the range");
1563 case Match_InvalidLoadFPImm: {
1565 return Error(ErrorLoc,
"operand must be a valid floating-point constant");
1567 case Match_InvalidBareSymbol: {
1569 return Error(ErrorLoc,
"operand must be a bare symbol name");
1571 case Match_InvalidPseudoJumpSymbol: {
1573 return Error(ErrorLoc,
"operand must be a valid jump target");
1575 case Match_InvalidCallSymbol: {
1577 return Error(ErrorLoc,
"operand must be a bare symbol name");
1579 case Match_InvalidTPRelAddSymbol: {
1581 return Error(ErrorLoc,
"operand must be a symbol with %tprel_add modifier");
1583 case Match_InvalidTLSDESCCallSymbol: {
1585 return Error(ErrorLoc,
1586 "operand must be a symbol with %tlsdesc_call modifier");
1588 case Match_InvalidRTZArg: {
1590 return Error(ErrorLoc,
"operand must be 'rtz' floating-point rounding mode");
1592 case Match_InvalidVTypeI: {
1594 return generateVTypeError(ErrorLoc);
1596 case Match_InvalidVMaskRegister: {
1598 return Error(ErrorLoc,
"operand must be v0.t");
1600 case Match_InvalidSImm5Plus1: {
1603 "immediate must be in the range");
1605 case Match_InvalidRlist: {
1609 "operand must be {ra [, s0[-sN]]} or {x1 [, x8[-x9][, x18[-xN]]]}");
1611 case Match_InvalidSpimm: {
1615 "stack adjustment is invalid for this instruction and register list; "
1616 "refer to Zc spec for a detailed range of stack adjustment");
1618 case Match_InvalidRnumArg: {
1621 case Match_InvalidRegReg: {
1623 return Error(ErrorLoc,
"operands must be register and register");
1641 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1642 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1645 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1646 Reg = RISCV::NoRegister;
1652 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1653 return Error(StartLoc,
"invalid register name");
1659 const AsmToken &Tok = getParser().getTok();
1674 SMLoc FirstS = getLoc();
1675 bool HadParens =
false;
1682 size_t ReadCount = getLexer().peekTokens(Buf);
1685 LParen = getParser().getTok();
1690 switch (getLexer().getKind()) {
1693 getLexer().UnLex(LParen);
1701 getLexer().UnLex(LParen);
1705 Operands.push_back(RISCVOperand::createToken(
"(", FirstS));
1709 Operands.push_back(RISCVOperand::createReg(RegNo, S,
E));
1714 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
1725 switch (getLexer().getKind()) {
1735 if (getParser().parseExpression(Res,
E))
1738 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1740 int64_t
Imm =
CE->getValue();
1741 if (isUInt<7>(Imm)) {
1742 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1751 if (getParser().parseIdentifier(Identifier))
1754 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1756 assert(isUInt<7>(Opcode->Value) && (Opcode->Value & 0x3) == 3 &&
1757 "Unexpected opcode");
1760 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1770 return generateImmOutOfRangeError(
1772 "opcode must be a valid opcode name or an immediate in the range");
1780 switch (getLexer().getKind()) {
1790 if (getParser().parseExpression(Res,
E))
1793 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1795 int64_t
Imm =
CE->getValue();
1796 if (Imm >= 0 && Imm <= 2) {
1797 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1806 if (getParser().parseIdentifier(Identifier))
1810 if (Identifier ==
"C0")
1812 else if (Identifier ==
"C1")
1814 else if (Identifier ==
"C2")
1821 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1830 return generateImmOutOfRangeError(
1832 "opcode must be a valid opcode name or an immediate in the range");
1839 switch (getLexer().getKind()) {
1849 if (getParser().parseExpression(Res))
1852 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1854 int64_t
Imm =
CE->getValue();
1855 if (isUInt<12>(Imm)) {
1856 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm);
1860 RISCVOperand::createSysReg(SysReg ? SysReg->Name :
"", S, Imm));
1865 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1869 if (getParser().parseIdentifier(Identifier))
1872 auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1874 SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier);
1876 if ((SysReg = RISCVSysReg::lookupSysRegByDeprecatedName(Identifier)))
1877 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
1878 SysReg->Name +
"'");
1882 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits()))
1883 return Error(S,
"system register use requires an option to be enabled");
1885 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
1889 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
1890 "operand must be a valid system register "
1891 "name or an integer in the range");
1895 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1908 if (
Identifier.compare_insensitive(
"inf") == 0) {
1911 getTok().getEndLoc(), isRV64()));
1912 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
1915 getTok().getEndLoc(), isRV64()));
1916 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
1919 getTok().getEndLoc(), isRV64()));
1921 return TokError(
"invalid floating point literal");
1934 return TokError(
"invalid floating point immediate");
1937 APFloat RealVal(APFloat::IEEEdouble());
1939 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
1941 return TokError(
"invalid floating point representation");
1944 RealVal.changeSign();
1946 Operands.push_back(RISCVOperand::createFPImm(
1947 RealVal.bitcastToAPInt().getZExtValue(), S));
1959 switch (getLexer().getKind()) {
1971 if (getParser().parseExpression(Res,
E))
1975 return parseOperandWithModifier(
Operands);
1978 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1990 return Error(getLoc(),
"expected valid identifier for operand modifier");
1994 return Error(getLoc(),
"unrecognized operand modifier");
2001 if (getParser().parseParenExpression(SubExpr,
E))
2005 Operands.push_back(RISCVOperand::createImm(ModExpr, S,
E, isRV64()));
2017 AsmToken Tok = getLexer().getTok();
2019 if (getParser().parseIdentifier(Identifier))
2025 return Error(getLoc(),
"'@plt' operand not valid for instruction");
2027 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
2029 if (
Sym->isVariable()) {
2030 const MCExpr *
V =
Sym->getVariableValue(
false);
2031 if (!isa<MCSymbolRefExpr>(V)) {
2032 getLexer().UnLex(Tok);
2040 switch (getLexer().getKind()) {
2042 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2055 if (getParser().parseExpression(Expr,
E))
2058 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2074 if (getParser().parseIdentifier(Identifier))
2082 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
2085 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2094 if (getParser().parseExpression(Res,
E))
2097 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef ||
2098 cast<MCSymbolRefExpr>(Res)->getKind() ==
2099 MCSymbolRefExpr::VariantKind::VK_PLT)
2100 return Error(S,
"operand must be a valid jump target");
2103 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2124bool RISCVAsmParser::parseVTypeToken(
StringRef Identifier, VTypeState &State,
2125 unsigned &Sew,
unsigned &Lmul,
2126 bool &Fractional,
bool &TailAgnostic,
2127 bool &MaskAgnostic) {
2129 case VTypeState_SEW:
2136 State = VTypeState_LMUL;
2138 case VTypeState_LMUL: {
2146 State = VTypeState_TailPolicy;
2149 case VTypeState_TailPolicy:
2150 if (Identifier ==
"ta")
2151 TailAgnostic =
true;
2152 else if (Identifier ==
"tu")
2153 TailAgnostic =
false;
2156 State = VTypeState_MaskPolicy;
2158 case VTypeState_MaskPolicy:
2159 if (Identifier ==
"ma")
2160 MaskAgnostic =
true;
2161 else if (Identifier ==
"mu")
2162 MaskAgnostic =
false;
2165 State = VTypeState_Done;
2167 case VTypeState_Done:
2180 bool Fractional =
false;
2181 bool TailAgnostic =
false;
2182 bool MaskAgnostic =
false;
2184 VTypeState State = VTypeState_SEW;
2191 if (parseVTypeToken(Identifier, State, Sew, Lmul, Fractional, TailAgnostic,
2203 if (parseVTypeToken(Identifier, State, Sew, Lmul, Fractional, TailAgnostic,
2215 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2219 return generateVTypeError(S);
2222bool RISCVAsmParser::generateVTypeError(
SMLoc ErrorLoc) {
2226 "e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2234 if (!
Name.consume_back(
".t"))
2235 return Error(getLoc(),
"expected '.t' suffix");
2240 if (RegNo != RISCV::V0)
2245 Operands.push_back(RISCVOperand::createReg(RegNo, S,
E));
2261 Operands.push_back(RISCVOperand::createReg(
2262 RegNo, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2266template <
bool IsRV64>
2268 return parseGPRPair(
Operands, IsRV64);
2278 if (!IsRV64Inst && isRV64())
2290 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(RegNo))
2293 if ((RegNo - RISCV::X0) & 1)
2294 return TokError(
"register must be even");
2302 RegNo, RISCV::sub_gpr_even,
2303 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2304 Operands.push_back(RISCVOperand::createReg(Pair, S,
E));
2311 "operand must be a valid floating point rounding mode mnemonic");
2313 StringRef Str = getLexer().getTok().getIdentifier();
2318 "operand must be a valid floating point rounding mode mnemonic");
2320 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2326 const AsmToken &Tok = getLexer().getTok();
2332 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2346 for (
char c : Str) {
2375 Operands.push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2381 return TokError(
"operand must be formed of letters selected in-order from "
2388 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
2390 if (!parseRegister(
Operands).isSuccess())
2391 return Error(getLoc(),
"expected register");
2395 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2419 std::unique_ptr<RISCVOperand> OptionalImmOp;
2426 SMLoc ImmStart = getLoc();
2427 if (getParser().parseIntToken(ImmVal,
2428 "expected '(' or optional integer offset"))
2433 SMLoc ImmEnd = getLoc();
2436 ImmStart, ImmEnd, isRV64());
2440 OptionalImmOp ?
"expected '(' after optional integer offset"
2441 :
"expected '(' or optional integer offset"))
2444 if (!parseRegister(
Operands).isSuccess())
2445 return Error(getLoc(),
"expected register");
2451 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2453 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2454 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2467 return Error(getLoc(),
"invalid register");
2474 return Error(getLoc(),
"expected register");
2476 StringRef Reg2Name = getLexer().getTok().getIdentifier();
2479 return Error(getLoc(),
"invalid register");
2485 Operands.push_back(RISCVOperand::createRegReg(
Reg, Reg2, getLoc()));
2498 bool IsEABI = isRVE();
2501 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2506 if (RegStart != RISCV::X1)
2507 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2513 return Error(getLoc(),
"invalid register");
2517 return Error(getLoc(),
"invalid register");
2518 if (RegStart != RISCV::X8)
2519 return Error(getLoc(),
2520 "continuous register list must start from 's0' or 'x8'");
2526 StringRef EndName = getLexer().getTok().getIdentifier();
2530 return Error(getLoc(),
"invalid register");
2531 if (IsEABI && RegEnd != RISCV::X9)
2532 return Error(getLoc(),
"contiguous register list of EABI can only be "
2533 "'s0-s1' or 'x8-x9' pair");
2540 if (RegEnd != RISCV::X9)
2543 "first contiguous registers pair of register list must be 'x8-x9'");
2547 return Error(getLoc(),
"invalid register");
2548 StringRef EndName = getLexer().getTok().getIdentifier();
2550 return Error(getLoc(),
2551 "second contiguous registers pair of register list "
2552 "must start from 'x18'");
2558 return Error(getLoc(),
"invalid register");
2559 EndName = getLexer().getTok().getIdentifier();
2561 return Error(getLoc(),
"invalid register");
2568 if (RegEnd == RISCV::X26)
2569 return Error(getLoc(),
"invalid register list, {ra, s0-s10} or {x1, x8-x9, "
2570 "x18-x26} is not supported");
2575 if (RegEnd == RISCV::NoRegister)
2580 return Error(S,
"invalid register list");
2581 Operands.push_back(RISCVOperand::createRlist(Encode, S));
2592 unsigned RlistVal =
static_cast<RISCVOperand *
>(
Operands[1].get())->Rlist.Val;
2594 bool IsEABI = isRVE();
2597 Operands.push_back(RISCVOperand::createSpimm(Spimm << 4, S));
2609 MatchOperandParserImpl(
Operands, Mnemonic,
true);
2616 if (parseRegister(
Operands,
true).isSuccess())
2623 return !parseMemOpBaseReg(
Operands).isSuccess();
2628 Error(getLoc(),
"unknown operand");
2641 if (getSTI().hasFeature(RISCV::FeatureRelax)) {
2642 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
2643 if (Assembler !=
nullptr) {
2651 Operands.push_back(RISCVOperand::createToken(
Name, NameLoc));
2670 if (getParser().parseEOL(
"unexpected token")) {
2671 getParser().eatToEndOfStatement();
2677bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
2681 if (
const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
2682 Kind = RE->getKind();
2683 Expr = RE->getSubExpr();
2693bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
2706 if (IDVal ==
".option")
2707 return parseDirectiveOption();
2708 if (IDVal ==
".attribute")
2709 return parseDirectiveAttribute();
2710 if (IDVal ==
".insn")
2711 return parseDirectiveInsn(DirectiveID.
getLoc());
2712 if (IDVal ==
".variant_cc")
2713 return parseDirectiveVariantCC();
2718bool RISCVAsmParser::resetToArch(
StringRef Arch,
SMLoc Loc, std::string &Result,
2719 bool FromOptionDirective) {
2722 clearFeatureBits(Feature.Value, Feature.Key);
2731 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
2732 << ErrMsg.getMessage();
2735 return Error(Loc, OutputErrMsg.str());
2737 auto &ISAInfo = *ParseResult;
2740 if (ISAInfo->hasExtension(Feature.Key))
2741 setFeatureBits(Feature.Value, Feature.Key);
2743 if (FromOptionDirective) {
2744 if (ISAInfo->getXLen() == 32 && isRV64())
2745 return Error(Loc,
"bad arch string switching from rv64 to rv32");
2746 else if (ISAInfo->getXLen() == 64 && !isRV64())
2747 return Error(Loc,
"bad arch string switching from rv32 to rv64");
2750 if (ISAInfo->getXLen() == 32)
2751 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
2752 else if (ISAInfo->getXLen() == 64)
2753 setFeatureBits(RISCV::Feature64Bit,
"64bit");
2755 return Error(Loc,
"bad arch string " + Arch);
2757 Result = ISAInfo->toString();
2761bool RISCVAsmParser::parseDirectiveOption() {
2772 if (Option ==
"push") {
2776 getTargetStreamer().emitDirectiveOptionPush();
2781 if (Option ==
"pop") {
2786 getTargetStreamer().emitDirectiveOptionPop();
2787 if (popFeatureBits())
2788 return Error(StartLoc,
".option pop with no .option push");
2793 if (Option ==
"arch") {
2801 Type = RISCVOptionArchArgType::Plus;
2803 Type = RISCVOptionArchArgType::Minus;
2804 else if (!
Args.empty())
2806 "unexpected token, expected + or -");
2808 Type = RISCVOptionArchArgType::Full;
2812 "unexpected token, expected identifier");
2818 if (
Type == RISCVOptionArchArgType::Full) {
2820 if (resetToArch(Arch, Loc, Result,
true))
2833 "Extension version number parsing not currently implemented");
2834 return Error(Loc,
"unknown extension feature");
2839 if (
Type == RISCVOptionArchArgType::Plus) {
2842 setFeatureBits(
Ext->Value,
Ext->Key);
2845 copySTI().setFeatureBits(OldFeatureBits);
2846 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
2851 OutputErrMsg << ErrMsg.getMessage();
2854 return Error(Loc, OutputErrMsg.str());
2857 assert(
Type == RISCVOptionArchArgType::Minus);
2862 if (getSTI().hasFeature(Feature.Value) &&
2863 Feature.Implies.test(
Ext->Value))
2865 Twine(
"Can't disable ") +
Ext->Key +
" extension, " +
2866 Feature.Key +
" extension requires " +
Ext->Key +
2867 " extension be enabled");
2870 clearFeatureBits(
Ext->Value,
Ext->Key);
2877 getTargetStreamer().emitDirectiveOptionArch(Args);
2881 if (Option ==
"rvc") {
2885 getTargetStreamer().emitDirectiveOptionRVC();
2886 setFeatureBits(RISCV::FeatureStdExtC,
"c");
2890 if (Option ==
"norvc") {
2894 getTargetStreamer().emitDirectiveOptionNoRVC();
2895 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
2896 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
2900 if (Option ==
"pic") {
2904 getTargetStreamer().emitDirectiveOptionPIC();
2905 ParserOptions.IsPicEnabled =
true;
2909 if (Option ==
"nopic") {
2913 getTargetStreamer().emitDirectiveOptionNoPIC();
2914 ParserOptions.IsPicEnabled =
false;
2918 if (Option ==
"relax") {
2922 getTargetStreamer().emitDirectiveOptionRelax();
2923 setFeatureBits(RISCV::FeatureRelax,
"relax");
2927 if (Option ==
"norelax") {
2931 getTargetStreamer().emitDirectiveOptionNoRelax();
2932 clearFeatureBits(RISCV::FeatureRelax,
"relax");
2938 "'rvc', 'norvc', 'arch', 'relax' or "
2947bool RISCVAsmParser::parseDirectiveAttribute() {
2954 std::optional<unsigned>
Ret =
2957 return Error(TagLoc,
"attribute name not recognised: " +
Name);
2968 if (
check(!CE, TagLoc,
"expected numeric constant"))
2971 Tag =
CE->getValue();
2978 int64_t IntegerValue = 0;
2979 bool IsIntegerValue =
true;
2984 IsIntegerValue =
false;
2987 if (IsIntegerValue) {
2994 return Error(ValueExprLoc,
"expected numeric constant");
2995 IntegerValue =
CE->getValue();
3008 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3010 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3013 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3017 getTargetStreamer().emitTextAttribute(
Tag, Result);
3025 .
Cases(
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s",
true)
3026 .
Cases(
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj", AllowC)
3032bool RISCVAsmParser::parseDirectiveInsn(
SMLoc L) {
3039 return Error(ErrorLoc,
"expected instruction format");
3041 bool AllowC = getSTI().hasFeature(RISCV::FeatureStdExtC) ||
3042 getSTI().hasFeature(RISCV::FeatureStdExtZca);
3044 return Error(ErrorLoc,
"invalid instruction format");
3046 std::string FormatName = (
".insn_" +
Format).str();
3063bool RISCVAsmParser::parseDirectiveVariantCC() {
3065 if (getParser().parseIdentifier(
Name))
3066 return TokError(
"expected symbol name");
3069 getTargetStreamer().emitDirectiveVariantCC(
3070 *getContext().getOrCreateSymbol(
Name));
3078 ++RISCVNumInstrsCompressed;
3088 switch (Inst.getOpndKind()) {
3118 unsigned SecondOpcode,
SMLoc IDLoc,
3132 const MCExpr *RefToLinkTmpLabel =
3139 .addExpr(RefToLinkTmpLabel));
3142void RISCVAsmParser::emitLoadLocalAddress(
MCInst &Inst,
SMLoc IDLoc,
3153 RISCV::ADDI, IDLoc, Out);
3156void RISCVAsmParser::emitLoadGlobalAddress(
MCInst &Inst,
SMLoc IDLoc,
3166 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3168 SecondOpcode, IDLoc, Out);
3171void RISCVAsmParser::emitLoadAddress(
MCInst &Inst,
SMLoc IDLoc,
3180 if (ParserOptions.IsPicEnabled)
3181 emitLoadGlobalAddress(Inst, IDLoc, Out);
3183 emitLoadLocalAddress(Inst, IDLoc, Out);
3186void RISCVAsmParser::emitLoadTLSIEAddress(
MCInst &Inst,
SMLoc IDLoc,
3196 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3198 SecondOpcode, IDLoc, Out);
3201void RISCVAsmParser::emitLoadTLSGDAddress(
MCInst &Inst,
SMLoc IDLoc,
3212 RISCV::ADDI, IDLoc, Out);
3215void RISCVAsmParser::emitLoadStoreSymbol(
MCInst &Inst,
unsigned Opcode,
3225 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3227 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3231 Opcode, IDLoc, Out);
3234void RISCVAsmParser::emitPseudoExtend(
MCInst &Inst,
bool SignExtend,
3235 int64_t Width,
SMLoc IDLoc,
3247 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3248 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3250 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3263void RISCVAsmParser::emitVMSGE(
MCInst &Inst,
unsigned Opcode,
SMLoc IDLoc,
3274 .addReg(RISCV::NoRegister)
3287 "The destination register should not be V0.");
3306 "The destination register should be V0.");
3308 "The temporary vector register should not be V0.");
3313 .addReg(RISCV::NoRegister)
3327 "The temporary vector register should not be V0.");
3332 .addReg(RISCV::NoRegister)
3352bool RISCVAsmParser::checkPseudoAddTPRel(
MCInst &Inst,
3354 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3357 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3358 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3359 "%tprel_add modifier");
3365bool RISCVAsmParser::checkPseudoTLSDESCCall(
MCInst &Inst,
3367 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
3370 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3371 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
3372 "%tlsdesc_call modifier");
3378std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3379 return RISCVOperand::createReg(RISCV::NoRegister,
llvm::SMLoc(),
3383std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3384 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3388std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3389 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3393bool RISCVAsmParser::validateInstruction(
MCInst &Inst,
3397 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3398 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3401 if (DestReg == TempReg) {
3403 return Error(Loc,
"The temporary vector register cannot be the same as "
3404 "the destination register.");
3408 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3409 Opcode == RISCV::TH_LWD) {
3414 if (Rs1 == Rd1 && Rs1 == Rd2) {
3416 return Error(Loc,
"The source register and destination registers "
3417 "cannot be equal.");
3421 if (Opcode == RISCV::CM_MVSA01) {
3426 return Error(Loc,
"'rs1' and 'rs2' must be different.");
3430 bool IsTHeadMemPair32 = (Opcode == RISCV::TH_LWD ||
3431 Opcode == RISCV::TH_LWUD || Opcode == RISCV::TH_SWD);
3432 bool IsTHeadMemPair64 = (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_SDD);
3437 return Error(Loc,
"Operand must be constant 3.");
3440 return Error(Loc,
"Operand must be constant 4.");
3447 if (Opcode == RISCV::VC_V_XVW || Opcode == RISCV::VC_V_IVW ||
3448 Opcode == RISCV::VC_V_FVW || Opcode == RISCV::VC_V_VVW) {
3454 if (VCIXDst == VCIXRs1)
3455 return Error(VCIXDstLoc,
"The destination vector register group cannot"
3456 " overlap the source vector register group.");
3460 if (VCIXDst == VCIXRs2)
3461 return Error(VCIXDstLoc,
"The destination vector register group cannot"
3462 " overlap the source vector register group.");
3477 if (DestReg == CheckReg)
3478 return Error(Loc,
"The destination vector register group cannot overlap"
3479 " the source vector register group.");
3483 if (DestReg == CheckReg)
3484 return Error(Loc,
"The destination vector register group cannot overlap"
3485 " the source vector register group.");
3490 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM ||
3491 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM ||
3492 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM ||
3493 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM ||
3494 Opcode == RISCV::VMERGE_VXM)
3495 return Error(Loc,
"The destination vector register group cannot be V0.");
3502 assert((CheckReg == RISCV::V0 || CheckReg == RISCV::NoRegister) &&
3503 "Unexpected register for mask operand");
3505 if (DestReg == CheckReg)
3506 return Error(Loc,
"The destination vector register group cannot overlap"
3507 " the mask register.");
3512bool RISCVAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
3520 case RISCV::PseudoLLAImm:
3521 case RISCV::PseudoLAImm:
3522 case RISCV::PseudoLI: {
3539 Imm = SignExtend64<32>(Imm);
3540 emitLoadImm(
Reg, Imm, Out);
3543 case RISCV::PseudoLLA:
3544 emitLoadLocalAddress(Inst, IDLoc, Out);
3546 case RISCV::PseudoLGA:
3547 emitLoadGlobalAddress(Inst, IDLoc, Out);
3549 case RISCV::PseudoLA:
3550 emitLoadAddress(Inst, IDLoc, Out);
3552 case RISCV::PseudoLA_TLS_IE:
3553 emitLoadTLSIEAddress(Inst, IDLoc, Out);
3555 case RISCV::PseudoLA_TLS_GD:
3556 emitLoadTLSGDAddress(Inst, IDLoc, Out);
3558 case RISCV::PseudoLB:
3559 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
3561 case RISCV::PseudoLBU:
3562 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
3564 case RISCV::PseudoLH:
3565 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
3567 case RISCV::PseudoLHU:
3568 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
3570 case RISCV::PseudoLW:
3571 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
3573 case RISCV::PseudoLWU:
3574 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
3576 case RISCV::PseudoLD:
3577 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
3579 case RISCV::PseudoFLH:
3580 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
3582 case RISCV::PseudoFLW:
3583 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
3585 case RISCV::PseudoFLD:
3586 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
3588 case RISCV::PseudoSB:
3589 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
3591 case RISCV::PseudoSH:
3592 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
3594 case RISCV::PseudoSW:
3595 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
3597 case RISCV::PseudoSD:
3598 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
3600 case RISCV::PseudoFSH:
3601 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
3603 case RISCV::PseudoFSW:
3604 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
3606 case RISCV::PseudoFSD:
3607 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
3609 case RISCV::PseudoAddTPRel:
3610 if (checkPseudoAddTPRel(Inst,
Operands))
3613 case RISCV::PseudoTLSDESCCall:
3614 if (checkPseudoTLSDESCCall(Inst,
Operands))
3617 case RISCV::PseudoSEXT_B:
3618 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
3620 case RISCV::PseudoSEXT_H:
3621 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
3623 case RISCV::PseudoZEXT_H:
3624 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
3626 case RISCV::PseudoZEXT_W:
3627 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
3629 case RISCV::PseudoVMSGEU_VX:
3630 case RISCV::PseudoVMSGEU_VX_M:
3631 case RISCV::PseudoVMSGEU_VX_M_T:
3632 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
3634 case RISCV::PseudoVMSGE_VX:
3635 case RISCV::PseudoVMSGE_VX_M:
3636 case RISCV::PseudoVMSGE_VX_M_T:
3637 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
3639 case RISCV::PseudoVMSGE_VI:
3640 case RISCV::PseudoVMSLT_VI: {
3644 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
3654 case RISCV::PseudoVMSGEU_VI:
3655 case RISCV::PseudoVMSLTU_VI: {
3662 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3673 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3688 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)
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.
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 MCAsmLayout *Layout, 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)...
MCInstBuilder & addReg(unsigned Reg)
Add a new register operand.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
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
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 bool isSupportedExtension(StringRef Ext)
static llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseArchString(StringRef Arch, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck=true, bool IgnoreUnknown=false)
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.
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.
const CustomOperand< const MCSubtargetInfo & > Msg[]
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.
InstSeq generateInstSeq(int64_t Val, const MCSubtargetInfo &STI)
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, bool IsEABI)
void printSpimm(int64_t Spimm, raw_ostream &OS)
@ 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.