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"
217 bool ExpectNegative =
false);
219 return parseZcmpStackAdj(
Operands,
true);
224 bool parseDirectiveOption();
225 bool parseDirectiveAttribute();
226 bool parseDirectiveInsn(
SMLoc L);
227 bool parseDirectiveVariantCC();
233 bool FromOptionDirective);
236 if (!(
getSTI().hasFeature(Feature))) {
244 if (
getSTI().hasFeature(Feature)) {
251 void pushFeatureBits() {
253 "These two stacks must be kept synchronized");
255 ParserOptionsStack.
push_back(ParserOptions);
258 bool popFeatureBits() {
260 "These two stacks must be kept synchronized");
261 if (FeatureBitStack.
empty())
273 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
274 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
275 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
278 enum RISCVMatchResultTy {
280 Match_RequiresEvenGPRs,
281#define GET_OPERAND_DIAGNOSTIC_TYPES
282#include "RISCVGenAsmMatcher.inc"
283#undef GET_OPERAND_DIAGNOSTIC_TYPES
286 static bool classifySymbolRef(
const MCExpr *Expr,
288 static bool isSymbolDiff(
const MCExpr *Expr);
302 if (ABIName.ends_with(
"f") && !getSTI().hasFeature(RISCV::FeatureStdExtF)) {
303 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
304 "doesn't support the F instruction set extension (ignoring "
306 }
else if (ABIName.ends_with(
"d") &&
307 !getSTI().hasFeature(RISCV::FeatureStdExtD)) {
308 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
309 "doesn't support the D instruction set extension (ignoring "
322 getTargetStreamer().emitTargetAttributes(STI,
false);
391 SMLoc StartLoc, EndLoc;
397 struct SysRegOp SysReg;
398 struct VTypeOp VType;
400 struct FenceOp Fence;
401 struct RlistOp Rlist;
402 struct SpimmOp Spimm;
406 RISCVOperand(KindTy K) :
Kind(
K) {}
411 StartLoc =
o.StartLoc;
414 case KindTy::Register:
417 case KindTy::Immediate:
420 case KindTy::FPImmediate:
426 case KindTy::SystemRegister:
450 bool isToken()
const override {
return Kind == KindTy::Token; }
451 bool isReg()
const override {
return Kind == KindTy::Register; }
452 bool isV0Reg()
const {
453 return Kind == KindTy::Register &&
Reg.RegNum == RISCV::V0;
455 bool isAnyReg()
const {
456 return Kind == KindTy::Register &&
457 (RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.RegNum) ||
458 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg.RegNum) ||
459 RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg.RegNum));
461 bool isAnyRegC()
const {
462 return Kind == KindTy::Register &&
463 (RISCVMCRegisterClasses[RISCV::GPRCRegClassID].contains(
465 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
468 bool isImm()
const override {
return Kind == KindTy::Immediate; }
469 bool isMem()
const override {
return false; }
470 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
471 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
472 bool isRlist()
const {
return Kind == KindTy::Rlist; }
473 bool isSpimm()
const {
return Kind == KindTy::Spimm; }
476 return Kind == KindTy::Register &&
477 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.RegNum);
480 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
482 bool isGPRPair()
const {
483 return Kind == KindTy::Register &&
484 RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(
488 static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &Imm,
490 if (
auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
492 return RE->evaluateAsConstant(Imm);
495 if (
auto CE = dyn_cast<MCConstantExpr>(Expr)) {
497 Imm =
CE->getValue();
506 template <
int N>
bool isBareSimmNLsb0()
const {
511 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
514 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
522 bool isBareSymbol()
const {
526 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
528 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
532 bool isCallSymbol()
const {
536 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
538 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
543 bool isPseudoJumpSymbol()
const {
547 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
549 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
553 bool isTPRelAddSymbol()
const {
557 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
559 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
563 bool isTLSDESCCallSymbol()
const {
567 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
569 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
573 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
575 bool isVTypeImm(
unsigned N)
const {
580 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
586 bool isVTypeI10()
const {
587 if (Kind == KindTy::Immediate)
588 return isVTypeImm(10);
589 return Kind == KindTy::VType;
591 bool isVTypeI11()
const {
592 if (Kind == KindTy::Immediate)
593 return isVTypeImm(11);
594 return Kind == KindTy::VType;
599 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
602 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
603 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
607 bool isLoadFPImm()
const {
610 if (Kind != KindTy::FPImmediate)
613 APFloat(APFloat::IEEEdouble(),
APInt(64, getFPConst())));
616 return Idx >= 0 &&
Idx != 1;
619 bool isImmXLenLI()
const {
624 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
634 (isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm)));
637 return RISCVAsmParser::isSymbolDiff(getImm());
640 bool isImmXLenLI_Restricted()
const {
645 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
648 (isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm)));
651 bool isUImmLog2XLen()
const {
656 if (!evaluateConstantImm(getImm(), Imm, VK) ||
659 return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm);
662 bool isUImmLog2XLenNonZero()
const {
667 if (!evaluateConstantImm(getImm(), Imm, VK) ||
672 return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm);
675 bool isUImmLog2XLenHalf()
const {
680 if (!evaluateConstantImm(getImm(), Imm, VK) ||
683 return (isRV64Imm() && isUInt<5>(Imm)) || isUInt<4>(Imm);
686 template <
unsigned N>
bool IsUImm()
const {
691 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
695 bool isUImm1()
const {
return IsUImm<1>(); }
696 bool isUImm2()
const {
return IsUImm<2>(); }
697 bool isUImm3()
const {
return IsUImm<3>(); }
698 bool isUImm4()
const {
return IsUImm<4>(); }
699 bool isUImm5()
const {
return IsUImm<5>(); }
700 bool isUImm6()
const {
return IsUImm<6>(); }
701 bool isUImm7()
const {
return IsUImm<7>(); }
702 bool isUImm8()
const {
return IsUImm<8>(); }
703 bool isUImm20()
const {
return IsUImm<20>(); }
705 bool isUImm8GE32()
const {
710 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
711 return IsConstantImm && isUInt<8>(Imm) &&
Imm >= 32 &&
715 bool isRnumArg()
const {
720 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
721 return IsConstantImm &&
Imm >= INT64_C(0) &&
Imm <= INT64_C(10) &&
725 bool isRnumArg_0_7()
const {
730 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
731 return IsConstantImm &&
Imm >= INT64_C(0) &&
Imm <= INT64_C(7) &&
735 bool isRnumArg_1_10()
const {
740 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
741 return IsConstantImm &&
Imm >= INT64_C(1) &&
Imm <= INT64_C(10) &&
745 bool isRnumArg_2_14()
const {
750 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
751 return IsConstantImm &&
Imm >= INT64_C(2) &&
Imm <= INT64_C(14) &&
755 bool isSImm5()
const {
760 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
761 return IsConstantImm && isInt<5>(fixImmediateForRV32(Imm, isRV64Imm())) &&
765 bool isSImm6()
const {
770 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
771 return IsConstantImm && isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) &&
775 bool isSImm6NonZero()
const {
780 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
781 return IsConstantImm &&
Imm != 0 &&
782 isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) &&
786 bool isCLUIImm()
const {
791 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
792 return IsConstantImm && (
Imm != 0) &&
793 (isUInt<5>(Imm) || (
Imm >= 0xfffe0 &&
Imm <= 0xfffff)) &&
797 bool isUImm2Lsb0()
const {
802 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
803 return IsConstantImm && isShiftedUInt<1, 1>(Imm) &&
807 bool isUImm7Lsb00()
const {
812 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
813 return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
817 bool isUImm8Lsb00()
const {
822 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
823 return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
827 bool isUImm8Lsb000()
const {
832 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
833 return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
837 bool isSImm9Lsb0()
const {
return isBareSimmNLsb0<9>(); }
839 bool isUImm9Lsb000()
const {
844 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
845 return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
849 bool isUImm10Lsb00NonZero()
const {
854 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
855 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (
Imm != 0) &&
861 static int64_t fixImmediateForRV32(int64_t Imm,
bool IsRV64Imm) {
862 if (IsRV64Imm || !isUInt<32>(Imm))
864 return SignExtend64<32>(Imm);
867 bool isSImm12()
const {
873 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
875 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
877 IsValid = isInt<12>(fixImmediateForRV32(Imm, isRV64Imm()));
886 bool isSImm12Lsb0()
const {
return isBareSimmNLsb0<12>(); }
888 bool isSImm12Lsb00000()
const {
893 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
894 return IsConstantImm && isShiftedInt<7, 5>(Imm) &&
898 bool isSImm13Lsb0()
const {
return isBareSimmNLsb0<13>(); }
900 bool isSImm10Lsb0000NonZero()
const {
905 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
906 return IsConstantImm && (
Imm != 0) && isShiftedInt<6, 4>(Imm) &&
910 bool isUImm20LUI()
const {
916 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
917 if (!IsConstantImm) {
918 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
928 bool isUImm20AUIPC()
const {
934 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
935 if (!IsConstantImm) {
936 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
952 bool isSImm21Lsb0JAL()
const {
return isBareSimmNLsb0<21>(); }
954 bool isImmZero()
const {
959 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
963 bool isSImm5Plus1()
const {
968 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
969 return IsConstantImm &&
970 isInt<5>(fixImmediateForRV32(Imm, isRV64Imm()) - 1) &&
975 SMLoc getStartLoc()
const override {
return StartLoc; }
977 SMLoc getEndLoc()
const override {
return EndLoc; }
979 bool isRV64Imm()
const {
980 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
985 assert(Kind == KindTy::Register &&
"Invalid type access!");
990 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
991 return StringRef(SysReg.Data, SysReg.Length);
994 const MCExpr *getImm()
const {
995 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
1000 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1005 assert(Kind == KindTy::Token &&
"Invalid type access!");
1009 unsigned getVType()
const {
1010 assert(Kind == KindTy::VType &&
"Invalid type access!");
1015 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1019 unsigned getFence()
const {
1020 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1033 case KindTy::Immediate:
1036 case KindTy::FPImmediate:
1038 case KindTy::Register:
1042 OS <<
"'" << getToken() <<
"'";
1044 case KindTy::SystemRegister:
1045 OS <<
"<sysreg: " << getSysReg() <<
'>';
1054 roundingModeToString(getFRM());
1072 case KindTy::RegReg:
1079 static std::unique_ptr<RISCVOperand> createToken(
StringRef Str,
SMLoc S) {
1080 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1087 static std::unique_ptr<RISCVOperand>
1088 createReg(
unsigned RegNo,
SMLoc S,
SMLoc E,
bool IsGPRAsFPR =
false) {
1089 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1090 Op->Reg.RegNum = RegNo;
1091 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1097 static std::unique_ptr<RISCVOperand> createImm(
const MCExpr *Val,
SMLoc S,
1099 auto Op = std::make_unique<RISCVOperand>(KindTy::Immediate);
1101 Op->Imm.IsRV64 = IsRV64;
1107 static std::unique_ptr<RISCVOperand> createFPImm(
uint64_t Val,
SMLoc S) {
1108 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1109 Op->FPImm.Val = Val;
1115 static std::unique_ptr<RISCVOperand> createSysReg(
StringRef Str,
SMLoc S,
1116 unsigned Encoding) {
1117 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1118 Op->SysReg.Data = Str.data();
1119 Op->SysReg.Length = Str.size();
1126 static std::unique_ptr<RISCVOperand>
1128 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1135 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val,
SMLoc S) {
1136 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1137 Op->Fence.Val = Val;
1143 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI,
SMLoc S) {
1144 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1145 Op->VType.Val = VTypeI;
1151 static std::unique_ptr<RISCVOperand> createRlist(
unsigned RlistEncode,
1153 auto Op = std::make_unique<RISCVOperand>(KindTy::Rlist);
1154 Op->Rlist.Val = RlistEncode;
1159 static std::unique_ptr<RISCVOperand> createRegReg(
unsigned Reg1No,
1160 unsigned Reg2No,
SMLoc S) {
1161 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1162 Op->RegReg.Reg1 = Reg1No;
1163 Op->RegReg.Reg2 = Reg2No;
1169 static std::unique_ptr<RISCVOperand> createSpimm(
unsigned Spimm,
SMLoc S) {
1170 auto Op = std::make_unique<RISCVOperand>(KindTy::Spimm);
1171 Op->Spimm.Val = Spimm;
1176 static void addExpr(
MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1177 assert(Expr &&
"Expr shouldn't be null!");
1180 bool IsConstant = evaluateConstantImm(Expr, Imm, VK);
1190 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1191 assert(
N == 1 &&
"Invalid number of operands!");
1195 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1196 assert(
N == 1 &&
"Invalid number of operands!");
1197 addExpr(Inst, getImm(), isRV64Imm());
1200 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
1201 assert(
N == 1 &&
"Invalid number of operands!");
1203 addExpr(Inst, getImm(), isRV64Imm());
1208 APFloat(APFloat::IEEEdouble(),
APInt(64, getFPConst())));
1212 void addFenceArgOperands(
MCInst &Inst,
unsigned N)
const {
1213 assert(
N == 1 &&
"Invalid number of operands!");
1217 void addCSRSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
1218 assert(
N == 1 &&
"Invalid number of operands!");
1225 void addVTypeIOperands(
MCInst &Inst,
unsigned N)
const {
1226 assert(
N == 1 &&
"Invalid number of operands!");
1228 if (Kind == KindTy::Immediate) {
1230 [[maybe_unused]]
bool IsConstantImm =
1231 evaluateConstantImm(getImm(), Imm, VK);
1232 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1239 void addRlistOperands(
MCInst &Inst,
unsigned N)
const {
1240 assert(
N == 1 &&
"Invalid number of operands!");
1244 void addRegRegOperands(
MCInst &Inst,
unsigned N)
const {
1245 assert(
N == 1 &&
"Invalid number of operands!");
1250 void addSpimmOperands(
MCInst &Inst,
unsigned N)
const {
1251 assert(
N == 1 &&
"Invalid number of operands!");
1255 void addFRMArgOperands(
MCInst &Inst,
unsigned N)
const {
1256 assert(
N == 1 &&
"Invalid number of operands!");
1262#define GET_REGISTER_MATCHER
1263#define GET_SUBTARGET_FEATURE_NAME
1264#define GET_MATCHER_IMPLEMENTATION
1265#define GET_MNEMONIC_SPELL_CHECKER
1266#include "RISCVGenAsmMatcher.inc"
1269 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1270 return Reg - RISCV::F0_D + RISCV::F0_H;
1274 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1275 return Reg - RISCV::F0_D + RISCV::F0_F;
1280 unsigned RegClassID;
1281 if (Kind == MCK_VRM2)
1282 RegClassID = RISCV::VRM2RegClassID;
1283 else if (Kind == MCK_VRM4)
1284 RegClassID = RISCV::VRM4RegClassID;
1285 else if (Kind == MCK_VRM8)
1286 RegClassID = RISCV::VRM8RegClassID;
1290 &RISCVMCRegisterClasses[RegClassID]);
1295 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1297 return Match_InvalidOperand;
1301 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg);
1303 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg);
1304 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg);
1308 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1309 (IsRegFPR64C &&
Kind == MCK_FPR32C)) {
1311 return Match_Success;
1315 if (IsRegFPR64 && Kind == MCK_FPR16) {
1317 return Match_Success;
1321 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1323 if (
Op.Reg.RegNum == 0)
1324 return Match_InvalidOperand;
1325 return Match_Success;
1327 return Match_InvalidOperand;
1330unsigned RISCVAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
1334 if (MCID.
operands()[
I].RegClass == RISCV::GPRPairRegClassID) {
1339 if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].
contains(
Reg))
1343 if (((
Reg.id() - RISCV::X0) & 1) != 0)
1344 return Match_RequiresEvenGPRs;
1348 return Match_Success;
1351bool RISCVAsmParser::generateImmOutOfRangeError(
1353 const Twine &Msg =
"immediate must be an integer in the range") {
1357bool RISCVAsmParser::generateImmOutOfRangeError(
1359 const Twine &Msg =
"immediate must be an integer in the range") {
1361 return generateImmOutOfRangeError(ErrorLoc,
Lower,
Upper, Msg);
1364bool RISCVAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1368 bool MatchingInlineAsm) {
1378 if (validateInstruction(Inst,
Operands))
1380 return processInstruction(Inst, IDLoc,
Operands, Out);
1381 case Match_MissingFeature: {
1382 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1383 bool FirstFeature =
true;
1384 std::string
Msg =
"instruction requires the following:";
1385 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1386 if (MissingFeatures[i]) {
1387 Msg += FirstFeature ?
" " :
", ";
1389 FirstFeature =
false;
1392 return Error(IDLoc, Msg);
1394 case Match_MnemonicFail: {
1395 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1396 std::string Suggestion = RISCVMnemonicSpellCheck(
1397 ((RISCVOperand &)*
Operands[0]).getToken(), FBS, 0);
1398 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1400 case Match_InvalidOperand: {
1401 SMLoc ErrorLoc = IDLoc;
1404 return Error(ErrorLoc,
"too few operands for instruction");
1407 if (ErrorLoc ==
SMLoc())
1410 return Error(ErrorLoc,
"invalid operand for instruction");
1417 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1418 SMLoc ErrorLoc = IDLoc;
1420 return Error(ErrorLoc,
"too few operands for instruction");
1426 case Match_RequiresEvenGPRs:
1428 "double precision floating point operands must use even "
1429 "numbered X register");
1430 case Match_InvalidImmXLenLI:
1433 return Error(ErrorLoc,
"operand must be a constant 64-bit integer");
1436 std::numeric_limits<int32_t>::min(),
1437 std::numeric_limits<uint32_t>::max());
1438 case Match_InvalidImmXLenLI_Restricted:
1441 return Error(ErrorLoc,
"operand either must be a constant 64-bit integer "
1442 "or a bare symbol name");
1444 return generateImmOutOfRangeError(
1446 std::numeric_limits<uint32_t>::max(),
1447 "operand either must be a bare symbol name or an immediate integer in "
1449 case Match_InvalidImmZero: {
1451 return Error(ErrorLoc,
"immediate must be zero");
1453 case Match_InvalidUImmLog2XLen:
1457 case Match_InvalidUImmLog2XLenNonZero:
1461 case Match_InvalidUImmLog2XLenHalf:
1465 case Match_InvalidUImm1:
1467 case Match_InvalidUImm2:
1469 case Match_InvalidUImm2Lsb0:
1471 "immediate must be one of");
1472 case Match_InvalidUImm3:
1474 case Match_InvalidUImm4:
1476 case Match_InvalidUImm5:
1478 case Match_InvalidUImm6:
1480 case Match_InvalidUImm7:
1482 case Match_InvalidUImm8:
1484 case Match_InvalidUImm8GE32:
1486 case Match_InvalidSImm5:
1489 case Match_InvalidSImm6:
1492 case Match_InvalidSImm6NonZero:
1493 return generateImmOutOfRangeError(
1495 "immediate must be non-zero in the range");
1496 case Match_InvalidCLUIImm:
1497 return generateImmOutOfRangeError(
1499 "immediate must be in [0xfffe0, 0xfffff] or");
1500 case Match_InvalidUImm7Lsb00:
1501 return generateImmOutOfRangeError(
1503 "immediate must be a multiple of 4 bytes in the range");
1504 case Match_InvalidUImm8Lsb00:
1505 return generateImmOutOfRangeError(
1507 "immediate must be a multiple of 4 bytes in the range");
1508 case Match_InvalidUImm8Lsb000:
1509 return generateImmOutOfRangeError(
1511 "immediate must be a multiple of 8 bytes in the range");
1512 case Match_InvalidSImm9Lsb0:
1513 return generateImmOutOfRangeError(
1515 "immediate must be a multiple of 2 bytes in the range");
1516 case Match_InvalidUImm9Lsb000:
1517 return generateImmOutOfRangeError(
1519 "immediate must be a multiple of 8 bytes in the range");
1520 case Match_InvalidUImm10Lsb00NonZero:
1521 return generateImmOutOfRangeError(
1523 "immediate must be a multiple of 4 bytes in the range");
1524 case Match_InvalidSImm10Lsb0000NonZero:
1525 return generateImmOutOfRangeError(
1527 "immediate must be a multiple of 16 bytes and non-zero in the range");
1528 case Match_InvalidSImm12:
1529 return generateImmOutOfRangeError(
1531 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an "
1532 "integer in the range");
1533 case Match_InvalidSImm12Lsb0:
1534 return generateImmOutOfRangeError(
1536 "immediate must be a multiple of 2 bytes in the range");
1537 case Match_InvalidSImm12Lsb00000:
1538 return generateImmOutOfRangeError(
1540 "immediate must be a multiple of 32 bytes in the range");
1541 case Match_InvalidSImm13Lsb0:
1542 return generateImmOutOfRangeError(
1544 "immediate must be a multiple of 2 bytes in the range");
1545 case Match_InvalidUImm20LUI:
1547 "operand must be a symbol with "
1548 "%hi/%tprel_hi modifier or an integer in "
1550 case Match_InvalidUImm20:
1552 case Match_InvalidUImm20AUIPC:
1553 return generateImmOutOfRangeError(
1555 "operand must be a symbol with a "
1556 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
1557 "an integer in the range");
1558 case Match_InvalidSImm21Lsb0JAL:
1559 return generateImmOutOfRangeError(
1561 "immediate must be a multiple of 2 bytes in the range");
1562 case Match_InvalidCSRSystemRegister: {
1564 "operand must be a valid system register "
1565 "name or an integer in the range");
1567 case Match_InvalidLoadFPImm: {
1569 return Error(ErrorLoc,
"operand must be a valid floating-point constant");
1571 case Match_InvalidBareSymbol: {
1573 return Error(ErrorLoc,
"operand must be a bare symbol name");
1575 case Match_InvalidPseudoJumpSymbol: {
1577 return Error(ErrorLoc,
"operand must be a valid jump target");
1579 case Match_InvalidCallSymbol: {
1581 return Error(ErrorLoc,
"operand must be a bare symbol name");
1583 case Match_InvalidTPRelAddSymbol: {
1585 return Error(ErrorLoc,
"operand must be a symbol with %tprel_add modifier");
1587 case Match_InvalidTLSDESCCallSymbol: {
1589 return Error(ErrorLoc,
1590 "operand must be a symbol with %tlsdesc_call modifier");
1592 case Match_InvalidRTZArg: {
1594 return Error(ErrorLoc,
"operand must be 'rtz' floating-point rounding mode");
1596 case Match_InvalidVTypeI: {
1598 return generateVTypeError(ErrorLoc);
1600 case Match_InvalidVMaskRegister: {
1602 return Error(ErrorLoc,
"operand must be v0.t");
1604 case Match_InvalidSImm5Plus1: {
1607 "immediate must be in the range");
1609 case Match_InvalidRlist: {
1613 "operand must be {ra [, s0[-sN]]} or {x1 [, x8[-x9][, x18[-xN]]]}");
1615 case Match_InvalidStackAdj: {
1619 "stack adjustment is invalid for this instruction and register list; "
1620 "refer to Zc spec for a detailed range of stack adjustment");
1622 case Match_InvalidRnumArg: {
1625 case Match_InvalidRegReg: {
1627 return Error(ErrorLoc,
"operands must be register and register");
1645 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1646 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1649 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1650 Reg = RISCV::NoRegister;
1656 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1657 return Error(StartLoc,
"invalid register name");
1663 const AsmToken &Tok = getParser().getTok();
1678 SMLoc FirstS = getLoc();
1679 bool HadParens =
false;
1686 size_t ReadCount = getLexer().peekTokens(Buf);
1689 LParen = getParser().getTok();
1694 switch (getLexer().getKind()) {
1697 getLexer().UnLex(LParen);
1705 getLexer().UnLex(LParen);
1709 Operands.push_back(RISCVOperand::createToken(
"(", FirstS));
1713 Operands.push_back(RISCVOperand::createReg(RegNo, S,
E));
1718 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
1729 switch (getLexer().getKind()) {
1739 if (getParser().parseExpression(Res,
E))
1742 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1744 int64_t
Imm =
CE->getValue();
1745 if (isUInt<7>(Imm)) {
1746 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1755 if (getParser().parseIdentifier(Identifier))
1758 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1760 assert(isUInt<7>(Opcode->Value) && (Opcode->Value & 0x3) == 3 &&
1761 "Unexpected opcode");
1764 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1774 return generateImmOutOfRangeError(
1776 "opcode must be a valid opcode name or an immediate in the range");
1784 switch (getLexer().getKind()) {
1794 if (getParser().parseExpression(Res,
E))
1797 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1799 int64_t
Imm =
CE->getValue();
1800 if (Imm >= 0 && Imm <= 2) {
1801 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1810 if (getParser().parseIdentifier(Identifier))
1814 if (Identifier ==
"C0")
1816 else if (Identifier ==
"C1")
1818 else if (Identifier ==
"C2")
1825 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1834 return generateImmOutOfRangeError(
1836 "opcode must be a valid opcode name or an immediate in the range");
1843 switch (getLexer().getKind()) {
1853 if (getParser().parseExpression(Res))
1856 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1858 int64_t
Imm =
CE->getValue();
1859 if (isUInt<12>(Imm)) {
1860 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm);
1864 RISCVOperand::createSysReg(SysReg ? SysReg->Name :
"", S, Imm));
1869 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1873 if (getParser().parseIdentifier(Identifier))
1876 auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1878 SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier);
1880 if ((SysReg = RISCVSysReg::lookupSysRegByDeprecatedName(Identifier)))
1881 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
1882 SysReg->Name +
"'");
1886 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits()))
1887 return Error(S,
"system register use requires an option to be enabled");
1889 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
1893 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
1894 "operand must be a valid system register "
1895 "name or an integer in the range");
1899 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1912 if (
Identifier.compare_insensitive(
"inf") == 0) {
1915 getTok().getEndLoc(), isRV64()));
1916 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
1919 getTok().getEndLoc(), isRV64()));
1920 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
1923 getTok().getEndLoc(), isRV64()));
1925 return TokError(
"invalid floating point literal");
1938 return TokError(
"invalid floating point immediate");
1941 APFloat RealVal(APFloat::IEEEdouble());
1943 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
1945 return TokError(
"invalid floating point representation");
1948 RealVal.changeSign();
1950 Operands.push_back(RISCVOperand::createFPImm(
1951 RealVal.bitcastToAPInt().getZExtValue(), S));
1963 switch (getLexer().getKind()) {
1975 if (getParser().parseExpression(Res,
E))
1979 return parseOperandWithModifier(
Operands);
1982 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1994 return Error(getLoc(),
"expected valid identifier for operand modifier");
1998 return Error(getLoc(),
"unrecognized operand modifier");
2005 if (getParser().parseParenExpression(SubExpr,
E))
2009 Operands.push_back(RISCVOperand::createImm(ModExpr, S,
E, isRV64()));
2021 AsmToken Tok = getLexer().getTok();
2023 if (getParser().parseIdentifier(Identifier))
2029 return Error(getLoc(),
"'@plt' operand not valid for instruction");
2031 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
2033 if (
Sym->isVariable()) {
2034 const MCExpr *
V =
Sym->getVariableValue(
false);
2035 if (!isa<MCSymbolRefExpr>(V)) {
2036 getLexer().UnLex(Tok);
2044 switch (getLexer().getKind()) {
2046 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2059 if (getParser().parseExpression(Expr,
E))
2062 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2078 if (getParser().parseIdentifier(Identifier))
2086 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
2089 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2098 if (getParser().parseExpression(Res,
E))
2101 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef ||
2102 cast<MCSymbolRefExpr>(Res)->getKind() ==
2103 MCSymbolRefExpr::VariantKind::VK_PLT)
2104 return Error(S,
"operand must be a valid jump target");
2107 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2128bool RISCVAsmParser::parseVTypeToken(
StringRef Identifier, VTypeState &State,
2129 unsigned &Sew,
unsigned &Lmul,
2130 bool &Fractional,
bool &TailAgnostic,
2131 bool &MaskAgnostic) {
2133 case VTypeState_SEW:
2140 State = VTypeState_LMUL;
2142 case VTypeState_LMUL: {
2150 State = VTypeState_TailPolicy;
2153 case VTypeState_TailPolicy:
2154 if (Identifier ==
"ta")
2155 TailAgnostic =
true;
2156 else if (Identifier ==
"tu")
2157 TailAgnostic =
false;
2160 State = VTypeState_MaskPolicy;
2162 case VTypeState_MaskPolicy:
2163 if (Identifier ==
"ma")
2164 MaskAgnostic =
true;
2165 else if (Identifier ==
"mu")
2166 MaskAgnostic =
false;
2169 State = VTypeState_Done;
2171 case VTypeState_Done:
2184 bool Fractional =
false;
2185 bool TailAgnostic =
false;
2186 bool MaskAgnostic =
false;
2188 VTypeState State = VTypeState_SEW;
2195 if (parseVTypeToken(Identifier, State, Sew, Lmul, Fractional, TailAgnostic,
2207 if (parseVTypeToken(Identifier, State, Sew, Lmul, Fractional, TailAgnostic,
2219 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2223 return generateVTypeError(S);
2226bool RISCVAsmParser::generateVTypeError(
SMLoc ErrorLoc) {
2230 "e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2238 if (!
Name.consume_back(
".t"))
2239 return Error(getLoc(),
"expected '.t' suffix");
2244 if (RegNo != RISCV::V0)
2249 Operands.push_back(RISCVOperand::createReg(RegNo, S,
E));
2265 Operands.push_back(RISCVOperand::createReg(
2266 RegNo, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2270template <
bool IsRV64>
2272 return parseGPRPair(
Operands, IsRV64);
2282 if (!IsRV64Inst && isRV64())
2294 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(RegNo))
2297 if ((RegNo - RISCV::X0) & 1)
2298 return TokError(
"register must be even");
2306 RegNo, RISCV::sub_gpr_even,
2307 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2308 Operands.push_back(RISCVOperand::createReg(Pair, S,
E));
2315 "operand must be a valid floating point rounding mode mnemonic");
2317 StringRef Str = getLexer().getTok().getIdentifier();
2322 "operand must be a valid floating point rounding mode mnemonic");
2324 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2330 const AsmToken &Tok = getLexer().getTok();
2336 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2350 for (
char c : Str) {
2379 Operands.push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2385 return TokError(
"operand must be formed of letters selected in-order from "
2392 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
2394 if (!parseRegister(
Operands).isSuccess())
2395 return Error(getLoc(),
"expected register");
2399 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2423 std::unique_ptr<RISCVOperand> OptionalImmOp;
2430 SMLoc ImmStart = getLoc();
2431 if (getParser().parseIntToken(ImmVal,
2432 "expected '(' or optional integer offset"))
2437 SMLoc ImmEnd = getLoc();
2440 ImmStart, ImmEnd, isRV64());
2444 OptionalImmOp ?
"expected '(' after optional integer offset"
2445 :
"expected '(' or optional integer offset"))
2448 if (!parseRegister(
Operands).isSuccess())
2449 return Error(getLoc(),
"expected register");
2455 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2457 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2458 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2471 return Error(getLoc(),
"invalid register");
2478 return Error(getLoc(),
"expected register");
2480 StringRef Reg2Name = getLexer().getTok().getIdentifier();
2483 return Error(getLoc(),
"invalid register");
2489 Operands.push_back(RISCVOperand::createRegReg(
Reg, Reg2, getLoc()));
2502 bool IsEABI = isRVE();
2505 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2510 if (RegStart != RISCV::X1)
2511 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2517 return Error(getLoc(),
"invalid register");
2521 return Error(getLoc(),
"invalid register");
2522 if (RegStart != RISCV::X8)
2523 return Error(getLoc(),
2524 "continuous register list must start from 's0' or 'x8'");
2530 StringRef EndName = getLexer().getTok().getIdentifier();
2534 return Error(getLoc(),
"invalid register");
2535 if (IsEABI && RegEnd != RISCV::X9)
2536 return Error(getLoc(),
"contiguous register list of EABI can only be "
2537 "'s0-s1' or 'x8-x9' pair");
2544 if (RegEnd != RISCV::X9)
2547 "first contiguous registers pair of register list must be 'x8-x9'");
2551 return Error(getLoc(),
"invalid register");
2552 StringRef EndName = getLexer().getTok().getIdentifier();
2554 return Error(getLoc(),
2555 "second contiguous registers pair of register list "
2556 "must start from 'x18'");
2562 return Error(getLoc(),
"invalid register");
2563 EndName = getLexer().getTok().getIdentifier();
2565 return Error(getLoc(),
"invalid register");
2572 if (RegEnd == RISCV::X26)
2573 return Error(getLoc(),
"invalid register list, {ra, s0-s10} or {x1, x8-x9, "
2574 "x18-x26} is not supported");
2579 if (RegEnd == RISCV::NoRegister)
2584 return Error(S,
"invalid register list");
2585 Operands.push_back(RISCVOperand::createRlist(Encode, S));
2591 bool ExpectNegative) {
2597 unsigned RlistVal =
static_cast<RISCVOperand *
>(
Operands[1].get())->Rlist.Val;
2599 bool IsEABI = isRVE();
2600 if (Negative != ExpectNegative ||
2603 Operands.push_back(RISCVOperand::createSpimm(Spimm << 4, S));
2615 MatchOperandParserImpl(
Operands, Mnemonic,
true);
2622 if (parseRegister(
Operands,
true).isSuccess())
2629 return !parseMemOpBaseReg(
Operands).isSuccess();
2634 Error(getLoc(),
"unknown operand");
2647 if (getSTI().hasFeature(RISCV::FeatureRelax)) {
2648 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
2649 if (Assembler !=
nullptr) {
2657 Operands.push_back(RISCVOperand::createToken(
Name, NameLoc));
2676 if (getParser().parseEOL(
"unexpected token")) {
2677 getParser().eatToEndOfStatement();
2683bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
2687 if (
const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
2688 Kind = RE->getKind();
2689 Expr = RE->getSubExpr();
2699bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
2712 if (IDVal ==
".option")
2713 return parseDirectiveOption();
2714 if (IDVal ==
".attribute")
2715 return parseDirectiveAttribute();
2716 if (IDVal ==
".insn")
2717 return parseDirectiveInsn(DirectiveID.
getLoc());
2718 if (IDVal ==
".variant_cc")
2719 return parseDirectiveVariantCC();
2724bool RISCVAsmParser::resetToArch(
StringRef Arch,
SMLoc Loc, std::string &Result,
2725 bool FromOptionDirective) {
2728 clearFeatureBits(Feature.Value, Feature.Key);
2737 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
2738 << ErrMsg.getMessage();
2741 return Error(Loc, OutputErrMsg.str());
2743 auto &ISAInfo = *ParseResult;
2746 if (ISAInfo->hasExtension(Feature.Key))
2747 setFeatureBits(Feature.Value, Feature.Key);
2749 if (FromOptionDirective) {
2750 if (ISAInfo->getXLen() == 32 && isRV64())
2751 return Error(Loc,
"bad arch string switching from rv64 to rv32");
2752 else if (ISAInfo->getXLen() == 64 && !isRV64())
2753 return Error(Loc,
"bad arch string switching from rv32 to rv64");
2756 if (ISAInfo->getXLen() == 32)
2757 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
2758 else if (ISAInfo->getXLen() == 64)
2759 setFeatureBits(RISCV::Feature64Bit,
"64bit");
2761 return Error(Loc,
"bad arch string " + Arch);
2763 Result = ISAInfo->toString();
2767bool RISCVAsmParser::parseDirectiveOption() {
2778 if (Option ==
"push") {
2782 getTargetStreamer().emitDirectiveOptionPush();
2787 if (Option ==
"pop") {
2792 getTargetStreamer().emitDirectiveOptionPop();
2793 if (popFeatureBits())
2794 return Error(StartLoc,
".option pop with no .option push");
2799 if (Option ==
"arch") {
2807 Type = RISCVOptionArchArgType::Plus;
2809 Type = RISCVOptionArchArgType::Minus;
2810 else if (!
Args.empty())
2812 "unexpected token, expected + or -");
2814 Type = RISCVOptionArchArgType::Full;
2818 "unexpected token, expected identifier");
2824 if (
Type == RISCVOptionArchArgType::Full) {
2826 if (resetToArch(Arch, Loc, Result,
true))
2839 "Extension version number parsing not currently implemented");
2840 return Error(Loc,
"unknown extension feature");
2845 if (
Type == RISCVOptionArchArgType::Plus) {
2848 setFeatureBits(
Ext->Value,
Ext->Key);
2851 copySTI().setFeatureBits(OldFeatureBits);
2852 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
2857 OutputErrMsg << ErrMsg.getMessage();
2860 return Error(Loc, OutputErrMsg.str());
2863 assert(
Type == RISCVOptionArchArgType::Minus);
2868 if (getSTI().hasFeature(Feature.Value) &&
2869 Feature.Implies.test(
Ext->Value))
2871 Twine(
"Can't disable ") +
Ext->Key +
" extension, " +
2872 Feature.Key +
" extension requires " +
Ext->Key +
2873 " extension be enabled");
2876 clearFeatureBits(
Ext->Value,
Ext->Key);
2883 getTargetStreamer().emitDirectiveOptionArch(Args);
2887 if (Option ==
"rvc") {
2891 getTargetStreamer().emitDirectiveOptionRVC();
2892 setFeatureBits(RISCV::FeatureStdExtC,
"c");
2896 if (Option ==
"norvc") {
2900 getTargetStreamer().emitDirectiveOptionNoRVC();
2901 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
2902 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
2906 if (Option ==
"pic") {
2910 getTargetStreamer().emitDirectiveOptionPIC();
2911 ParserOptions.IsPicEnabled =
true;
2915 if (Option ==
"nopic") {
2919 getTargetStreamer().emitDirectiveOptionNoPIC();
2920 ParserOptions.IsPicEnabled =
false;
2924 if (Option ==
"relax") {
2928 getTargetStreamer().emitDirectiveOptionRelax();
2929 setFeatureBits(RISCV::FeatureRelax,
"relax");
2933 if (Option ==
"norelax") {
2937 getTargetStreamer().emitDirectiveOptionNoRelax();
2938 clearFeatureBits(RISCV::FeatureRelax,
"relax");
2944 "'rvc', 'norvc', 'arch', 'relax' or "
2953bool RISCVAsmParser::parseDirectiveAttribute() {
2960 std::optional<unsigned>
Ret =
2963 return Error(TagLoc,
"attribute name not recognised: " +
Name);
2974 if (
check(!CE, TagLoc,
"expected numeric constant"))
2977 Tag =
CE->getValue();
2984 int64_t IntegerValue = 0;
2985 bool IsIntegerValue =
true;
2990 IsIntegerValue =
false;
2993 if (IsIntegerValue) {
3000 return Error(ValueExprLoc,
"expected numeric constant");
3001 IntegerValue =
CE->getValue();
3014 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3016 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3019 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3023 getTargetStreamer().emitTextAttribute(
Tag, Result);
3031 .
Cases(
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s",
true)
3032 .
Cases(
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj", AllowC)
3038bool RISCVAsmParser::parseDirectiveInsn(
SMLoc L) {
3045 return Error(ErrorLoc,
"expected instruction format");
3047 bool AllowC = getSTI().hasFeature(RISCV::FeatureStdExtC) ||
3048 getSTI().hasFeature(RISCV::FeatureStdExtZca);
3050 return Error(ErrorLoc,
"invalid instruction format");
3052 std::string FormatName = (
".insn_" +
Format).str();
3069bool RISCVAsmParser::parseDirectiveVariantCC() {
3071 if (getParser().parseIdentifier(
Name))
3072 return TokError(
"expected symbol name");
3075 getTargetStreamer().emitDirectiveVariantCC(
3076 *getContext().getOrCreateSymbol(
Name));
3084 ++RISCVNumInstrsCompressed;
3093 for (
MCInst &Inst : Seq) {
3094 emitToStreamer(Out, Inst);
3101 unsigned SecondOpcode,
SMLoc IDLoc,
3115 const MCExpr *RefToLinkTmpLabel =
3122 .addExpr(RefToLinkTmpLabel));
3125void RISCVAsmParser::emitLoadLocalAddress(
MCInst &Inst,
SMLoc IDLoc,
3136 RISCV::ADDI, IDLoc, Out);
3139void RISCVAsmParser::emitLoadGlobalAddress(
MCInst &Inst,
SMLoc IDLoc,
3149 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3151 SecondOpcode, IDLoc, Out);
3154void RISCVAsmParser::emitLoadAddress(
MCInst &Inst,
SMLoc IDLoc,
3163 if (ParserOptions.IsPicEnabled)
3164 emitLoadGlobalAddress(Inst, IDLoc, Out);
3166 emitLoadLocalAddress(Inst, IDLoc, Out);
3169void RISCVAsmParser::emitLoadTLSIEAddress(
MCInst &Inst,
SMLoc IDLoc,
3179 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3181 SecondOpcode, IDLoc, Out);
3184void RISCVAsmParser::emitLoadTLSGDAddress(
MCInst &Inst,
SMLoc IDLoc,
3195 RISCV::ADDI, IDLoc, Out);
3198void RISCVAsmParser::emitLoadStoreSymbol(
MCInst &Inst,
unsigned Opcode,
3208 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3210 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3214 Opcode, IDLoc, Out);
3217void RISCVAsmParser::emitPseudoExtend(
MCInst &Inst,
bool SignExtend,
3218 int64_t Width,
SMLoc IDLoc,
3230 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3231 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3233 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3246void RISCVAsmParser::emitVMSGE(
MCInst &Inst,
unsigned Opcode,
SMLoc IDLoc,
3257 .addReg(RISCV::NoRegister)
3270 "The destination register should not be V0.");
3289 "The destination register should be V0.");
3291 "The temporary vector register should not be V0.");
3296 .addReg(RISCV::NoRegister)
3310 "The temporary vector register should not be V0.");
3315 .addReg(RISCV::NoRegister)
3335bool RISCVAsmParser::checkPseudoAddTPRel(
MCInst &Inst,
3337 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3340 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3341 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3342 "%tprel_add modifier");
3348bool RISCVAsmParser::checkPseudoTLSDESCCall(
MCInst &Inst,
3350 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
3353 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3354 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
3355 "%tlsdesc_call modifier");
3361std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3362 return RISCVOperand::createReg(RISCV::NoRegister,
llvm::SMLoc(),
3366std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3367 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3371std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3372 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3376bool RISCVAsmParser::validateInstruction(
MCInst &Inst,
3380 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3381 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3384 if (DestReg == TempReg) {
3386 return Error(Loc,
"The temporary vector register cannot be the same as "
3387 "the destination register.");
3391 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3392 Opcode == RISCV::TH_LWD) {
3397 if (Rs1 == Rd1 && Rs1 == Rd2) {
3399 return Error(Loc,
"The source register and destination registers "
3400 "cannot be equal.");
3404 if (Opcode == RISCV::CM_MVSA01) {
3409 return Error(Loc,
"'rs1' and 'rs2' must be different.");
3413 bool IsTHeadMemPair32 = (Opcode == RISCV::TH_LWD ||
3414 Opcode == RISCV::TH_LWUD || Opcode == RISCV::TH_SWD);
3415 bool IsTHeadMemPair64 = (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_SDD);
3420 return Error(Loc,
"Operand must be constant 3.");
3423 return Error(Loc,
"Operand must be constant 4.");
3430 if (Opcode == RISCV::VC_V_XVW || Opcode == RISCV::VC_V_IVW ||
3431 Opcode == RISCV::VC_V_FVW || Opcode == RISCV::VC_V_VVW) {
3437 if (VCIXDst == VCIXRs1)
3438 return Error(VCIXDstLoc,
"The destination vector register group cannot"
3439 " overlap the source vector register group.");
3443 if (VCIXDst == VCIXRs2)
3444 return Error(VCIXDstLoc,
"The destination vector register group cannot"
3445 " overlap the source vector register group.");
3460 if (DestReg == CheckReg)
3461 return Error(Loc,
"The destination vector register group cannot overlap"
3462 " the source vector register group.");
3466 if (DestReg == CheckReg)
3467 return Error(Loc,
"The destination vector register group cannot overlap"
3468 " the source vector register group.");
3473 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM ||
3474 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM ||
3475 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM ||
3476 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM ||
3477 Opcode == RISCV::VMERGE_VXM)
3478 return Error(Loc,
"The destination vector register group cannot be V0.");
3485 assert((CheckReg == RISCV::V0 || CheckReg == RISCV::NoRegister) &&
3486 "Unexpected register for mask operand");
3488 if (DestReg == CheckReg)
3489 return Error(Loc,
"The destination vector register group cannot overlap"
3490 " the mask register.");
3495bool RISCVAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
3503 case RISCV::PseudoLLAImm:
3504 case RISCV::PseudoLAImm:
3505 case RISCV::PseudoLI: {
3522 Imm = SignExtend64<32>(Imm);
3523 emitLoadImm(
Reg, Imm, Out);
3526 case RISCV::PseudoLLA:
3527 emitLoadLocalAddress(Inst, IDLoc, Out);
3529 case RISCV::PseudoLGA:
3530 emitLoadGlobalAddress(Inst, IDLoc, Out);
3532 case RISCV::PseudoLA:
3533 emitLoadAddress(Inst, IDLoc, Out);
3535 case RISCV::PseudoLA_TLS_IE:
3536 emitLoadTLSIEAddress(Inst, IDLoc, Out);
3538 case RISCV::PseudoLA_TLS_GD:
3539 emitLoadTLSGDAddress(Inst, IDLoc, Out);
3541 case RISCV::PseudoLB:
3542 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
3544 case RISCV::PseudoLBU:
3545 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
3547 case RISCV::PseudoLH:
3548 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
3550 case RISCV::PseudoLHU:
3551 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
3553 case RISCV::PseudoLW:
3554 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
3556 case RISCV::PseudoLWU:
3557 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
3559 case RISCV::PseudoLD:
3560 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
3562 case RISCV::PseudoFLH:
3563 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
3565 case RISCV::PseudoFLW:
3566 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
3568 case RISCV::PseudoFLD:
3569 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
3571 case RISCV::PseudoSB:
3572 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
3574 case RISCV::PseudoSH:
3575 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
3577 case RISCV::PseudoSW:
3578 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
3580 case RISCV::PseudoSD:
3581 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
3583 case RISCV::PseudoFSH:
3584 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
3586 case RISCV::PseudoFSW:
3587 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
3589 case RISCV::PseudoFSD:
3590 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
3592 case RISCV::PseudoAddTPRel:
3593 if (checkPseudoAddTPRel(Inst,
Operands))
3596 case RISCV::PseudoTLSDESCCall:
3597 if (checkPseudoTLSDESCCall(Inst,
Operands))
3600 case RISCV::PseudoSEXT_B:
3601 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
3603 case RISCV::PseudoSEXT_H:
3604 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
3606 case RISCV::PseudoZEXT_H:
3607 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
3609 case RISCV::PseudoZEXT_W:
3610 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
3612 case RISCV::PseudoVMSGEU_VX:
3613 case RISCV::PseudoVMSGEU_VX_M:
3614 case RISCV::PseudoVMSGEU_VX_M_T:
3615 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
3617 case RISCV::PseudoVMSGE_VX:
3618 case RISCV::PseudoVMSGE_VX_M:
3619 case RISCV::PseudoVMSGE_VX_M_T:
3620 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
3622 case RISCV::PseudoVMSGE_VI:
3623 case RISCV::PseudoVMSLT_VI: {
3627 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
3637 case RISCV::PseudoVMSGEU_VI:
3638 case RISCV::PseudoVMSLTU_VI: {
3645 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3656 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3671 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)...
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.
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, bool IsEABI)
@ 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.