47#define DEBUG_TYPE "riscv-asm-parser"
50 "Number of RISC-V Compressed instructions emitted");
62struct ParserOptionsSet {
74 VTypeState_TailPolicy,
75 VTypeState_MaskPolicy,
82 ParserOptionsSet ParserOptions;
87 bool enableExperimentalExtension()
const {
93 "do not have a target streamer");
99 unsigned Kind)
override;
105 bool generateImmOutOfRangeError(
SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
111 bool MatchingInlineAsm)
override;
116 SMLoc &EndLoc)
override;
123 bool parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
unsigned &Sew,
124 unsigned &Lmul,
bool &Fractional,
bool &TailAgnostic,
126 bool generateVTypeError(
SMLoc ErrorLoc);
160 void emitLoadStoreSymbol(
MCInst &Inst,
unsigned Opcode,
SMLoc IDLoc,
164 void emitPseudoExtend(
MCInst &Inst,
bool SignExtend, int64_t Width,
193#define GET_ASSEMBLER_HEADER
194#include "RISCVGenAsmMatcher.inc"
220 bool ExpectNegative =
false);
222 return parseZcmpStackAdj(
Operands,
true);
227 bool parseDirectiveOption();
228 bool parseDirectiveAttribute();
229 bool parseDirectiveInsn(
SMLoc L);
230 bool parseDirectiveVariantCC();
236 bool FromOptionDirective);
239 if (!(
getSTI().hasFeature(Feature))) {
247 if (
getSTI().hasFeature(Feature)) {
254 void pushFeatureBits() {
256 "These two stacks must be kept synchronized");
258 ParserOptionsStack.
push_back(ParserOptions);
261 bool popFeatureBits() {
263 "These two stacks must be kept synchronized");
264 if (FeatureBitStack.
empty())
276 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
277 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
278 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
281 enum RISCVMatchResultTy {
283 Match_RequiresEvenGPRs,
284#define GET_OPERAND_DIAGNOSTIC_TYPES
285#include "RISCVGenAsmMatcher.inc"
286#undef GET_OPERAND_DIAGNOSTIC_TYPES
289 static bool classifySymbolRef(
const MCExpr *Expr,
291 static bool isSymbolDiff(
const MCExpr *Expr);
305 if (ABIName.ends_with(
"f") && !getSTI().hasFeature(RISCV::FeatureStdExtF)) {
306 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
307 "doesn't support the F instruction set extension (ignoring "
309 }
else if (ABIName.ends_with(
"d") &&
310 !getSTI().hasFeature(RISCV::FeatureStdExtD)) {
311 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
312 "doesn't support the D instruction set extension (ignoring "
325 getTargetStreamer().emitTargetAttributes(STI,
false);
394 SMLoc StartLoc, EndLoc;
400 struct SysRegOp SysReg;
401 struct VTypeOp VType;
403 struct FenceOp Fence;
404 struct RlistOp Rlist;
405 struct SpimmOp Spimm;
409 RISCVOperand(KindTy K) :
Kind(
K) {}
414 StartLoc =
o.StartLoc;
417 case KindTy::Register:
420 case KindTy::Immediate:
423 case KindTy::FPImmediate:
429 case KindTy::SystemRegister:
453 bool isToken()
const override {
return Kind == KindTy::Token; }
454 bool isReg()
const override {
return Kind == KindTy::Register; }
455 bool isV0Reg()
const {
456 return Kind == KindTy::Register &&
Reg.RegNum == RISCV::V0;
458 bool isAnyReg()
const {
459 return Kind == KindTy::Register &&
460 (RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.RegNum) ||
461 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg.RegNum) ||
462 RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg.RegNum));
464 bool isAnyRegC()
const {
465 return Kind == KindTy::Register &&
466 (RISCVMCRegisterClasses[RISCV::GPRCRegClassID].contains(
468 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
471 bool isImm()
const override {
return Kind == KindTy::Immediate; }
472 bool isMem()
const override {
return false; }
473 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
474 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
475 bool isRlist()
const {
return Kind == KindTy::Rlist; }
476 bool isSpimm()
const {
return Kind == KindTy::Spimm; }
479 return Kind == KindTy::Register &&
480 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.RegNum);
483 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
485 bool isGPRPair()
const {
486 return Kind == KindTy::Register &&
487 RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(
491 static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &Imm,
493 if (
auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
495 return RE->evaluateAsConstant(Imm);
498 if (
auto CE = dyn_cast<MCConstantExpr>(Expr)) {
500 Imm =
CE->getValue();
509 template <
int N>
bool isBareSimmNLsb0()
const {
514 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
517 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
525 bool isBareSymbol()
const {
529 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
531 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
535 bool isCallSymbol()
const {
539 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
541 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
546 bool isPseudoJumpSymbol()
const {
550 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
552 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
556 bool isTPRelAddSymbol()
const {
560 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
562 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
566 bool isTLSDESCCallSymbol()
const {
570 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
572 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
576 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
578 bool isVTypeImm(
unsigned N)
const {
583 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
589 bool isVTypeI10()
const {
590 if (Kind == KindTy::Immediate)
591 return isVTypeImm(10);
592 return Kind == KindTy::VType;
594 bool isVTypeI11()
const {
595 if (Kind == KindTy::Immediate)
596 return isVTypeImm(11);
597 return Kind == KindTy::VType;
602 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
605 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
606 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
610 bool isLoadFPImm()
const {
613 if (Kind != KindTy::FPImmediate)
616 APFloat(APFloat::IEEEdouble(),
APInt(64, getFPConst())));
619 return Idx >= 0 &&
Idx != 1;
622 bool isImmXLenLI()
const {
627 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
637 (isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm)));
640 return RISCVAsmParser::isSymbolDiff(getImm());
643 bool isImmXLenLI_Restricted()
const {
648 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
651 (isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm)));
654 bool isUImmLog2XLen()
const {
659 if (!evaluateConstantImm(getImm(), Imm, VK) ||
662 return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm);
665 bool isUImmLog2XLenNonZero()
const {
670 if (!evaluateConstantImm(getImm(), Imm, VK) ||
675 return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm);
678 bool isUImmLog2XLenHalf()
const {
683 if (!evaluateConstantImm(getImm(), Imm, VK) ||
686 return (isRV64Imm() && isUInt<5>(Imm)) || isUInt<4>(Imm);
689 template <
unsigned N>
bool IsUImm()
const {
694 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
698 bool isUImm1()
const {
return IsUImm<1>(); }
699 bool isUImm2()
const {
return IsUImm<2>(); }
700 bool isUImm3()
const {
return IsUImm<3>(); }
701 bool isUImm4()
const {
return IsUImm<4>(); }
702 bool isUImm5()
const {
return IsUImm<5>(); }
703 bool isUImm6()
const {
return IsUImm<6>(); }
704 bool isUImm7()
const {
return IsUImm<7>(); }
705 bool isUImm8()
const {
return IsUImm<8>(); }
706 bool isUImm20()
const {
return IsUImm<20>(); }
708 bool isUImm8GE32()
const {
713 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
714 return IsConstantImm && isUInt<8>(Imm) &&
Imm >= 32 &&
718 bool isRnumArg()
const {
723 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
724 return IsConstantImm &&
Imm >= INT64_C(0) &&
Imm <= INT64_C(10) &&
728 bool isRnumArg_0_7()
const {
733 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
734 return IsConstantImm &&
Imm >= INT64_C(0) &&
Imm <= INT64_C(7) &&
738 bool isRnumArg_1_10()
const {
743 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
744 return IsConstantImm &&
Imm >= INT64_C(1) &&
Imm <= INT64_C(10) &&
748 bool isRnumArg_2_14()
const {
753 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
754 return IsConstantImm &&
Imm >= INT64_C(2) &&
Imm <= INT64_C(14) &&
758 bool isSImm5()
const {
763 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
764 return IsConstantImm && isInt<5>(fixImmediateForRV32(Imm, isRV64Imm())) &&
768 bool isSImm6()
const {
773 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
774 return IsConstantImm && isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) &&
778 bool isSImm6NonZero()
const {
783 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
784 return IsConstantImm &&
Imm != 0 &&
785 isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) &&
789 bool isCLUIImm()
const {
794 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
795 return IsConstantImm && (
Imm != 0) &&
796 (isUInt<5>(Imm) || (
Imm >= 0xfffe0 &&
Imm <= 0xfffff)) &&
800 bool isUImm2Lsb0()
const {
805 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
806 return IsConstantImm && isShiftedUInt<1, 1>(Imm) &&
810 bool isUImm7Lsb00()
const {
815 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
816 return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
820 bool isUImm8Lsb00()
const {
825 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
826 return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
830 bool isUImm8Lsb000()
const {
835 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
836 return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
840 bool isSImm9Lsb0()
const {
return isBareSimmNLsb0<9>(); }
842 bool isUImm9Lsb000()
const {
847 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
848 return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
852 bool isUImm10Lsb00NonZero()
const {
857 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
858 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (
Imm != 0) &&
864 static int64_t fixImmediateForRV32(int64_t Imm,
bool IsRV64Imm) {
865 if (IsRV64Imm || !isUInt<32>(Imm))
867 return SignExtend64<32>(Imm);
870 bool isSImm12()
const {
876 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
878 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
880 IsValid = isInt<12>(fixImmediateForRV32(Imm, isRV64Imm()));
889 bool isSImm12Lsb0()
const {
return isBareSimmNLsb0<12>(); }
891 bool isSImm12Lsb00000()
const {
896 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
897 return IsConstantImm && isShiftedInt<7, 5>(Imm) &&
901 bool isSImm13Lsb0()
const {
return isBareSimmNLsb0<13>(); }
903 bool isSImm10Lsb0000NonZero()
const {
908 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
909 return IsConstantImm && (
Imm != 0) && isShiftedInt<6, 4>(Imm) &&
913 bool isUImm20LUI()
const {
919 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
920 if (!IsConstantImm) {
921 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
931 bool isUImm20AUIPC()
const {
937 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
938 if (!IsConstantImm) {
939 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
955 bool isSImm21Lsb0JAL()
const {
return isBareSimmNLsb0<21>(); }
957 bool isImmZero()
const {
962 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
966 bool isSImm5Plus1()
const {
971 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
972 return IsConstantImm &&
973 isInt<5>(fixImmediateForRV32(Imm, isRV64Imm()) - 1) &&
978 SMLoc getStartLoc()
const override {
return StartLoc; }
980 SMLoc getEndLoc()
const override {
return EndLoc; }
982 bool isRV64Imm()
const {
983 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
988 assert(Kind == KindTy::Register &&
"Invalid type access!");
993 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
994 return StringRef(SysReg.Data, SysReg.Length);
997 const MCExpr *getImm()
const {
998 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
1003 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1008 assert(Kind == KindTy::Token &&
"Invalid type access!");
1012 unsigned getVType()
const {
1013 assert(Kind == KindTy::VType &&
"Invalid type access!");
1018 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1022 unsigned getFence()
const {
1023 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1036 case KindTy::Immediate:
1039 case KindTy::FPImmediate:
1041 case KindTy::Register:
1045 OS <<
"'" << getToken() <<
"'";
1047 case KindTy::SystemRegister:
1048 OS <<
"<sysreg: " << getSysReg() <<
'>';
1057 roundingModeToString(getFRM());
1075 case KindTy::RegReg:
1082 static std::unique_ptr<RISCVOperand> createToken(
StringRef Str,
SMLoc S) {
1083 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1090 static std::unique_ptr<RISCVOperand>
1091 createReg(
unsigned RegNo,
SMLoc S,
SMLoc E,
bool IsGPRAsFPR =
false) {
1092 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1093 Op->Reg.RegNum = RegNo;
1094 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1100 static std::unique_ptr<RISCVOperand> createImm(
const MCExpr *Val,
SMLoc S,
1102 auto Op = std::make_unique<RISCVOperand>(KindTy::Immediate);
1104 Op->Imm.IsRV64 = IsRV64;
1110 static std::unique_ptr<RISCVOperand> createFPImm(
uint64_t Val,
SMLoc S) {
1111 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1112 Op->FPImm.Val = Val;
1118 static std::unique_ptr<RISCVOperand> createSysReg(
StringRef Str,
SMLoc S,
1119 unsigned Encoding) {
1120 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1121 Op->SysReg.Data = Str.data();
1122 Op->SysReg.Length = Str.size();
1129 static std::unique_ptr<RISCVOperand>
1131 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1138 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val,
SMLoc S) {
1139 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1140 Op->Fence.Val = Val;
1146 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI,
SMLoc S) {
1147 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1148 Op->VType.Val = VTypeI;
1154 static std::unique_ptr<RISCVOperand> createRlist(
unsigned RlistEncode,
1156 auto Op = std::make_unique<RISCVOperand>(KindTy::Rlist);
1157 Op->Rlist.Val = RlistEncode;
1162 static std::unique_ptr<RISCVOperand> createRegReg(
unsigned Reg1No,
1163 unsigned Reg2No,
SMLoc S) {
1164 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1165 Op->RegReg.Reg1 = Reg1No;
1166 Op->RegReg.Reg2 = Reg2No;
1172 static std::unique_ptr<RISCVOperand> createSpimm(
unsigned Spimm,
SMLoc S) {
1173 auto Op = std::make_unique<RISCVOperand>(KindTy::Spimm);
1174 Op->Spimm.Val = Spimm;
1179 static void addExpr(
MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1180 assert(Expr &&
"Expr shouldn't be null!");
1183 bool IsConstant = evaluateConstantImm(Expr, Imm, VK);
1193 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1194 assert(
N == 1 &&
"Invalid number of operands!");
1198 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1199 assert(
N == 1 &&
"Invalid number of operands!");
1200 addExpr(Inst, getImm(), isRV64Imm());
1203 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
1204 assert(
N == 1 &&
"Invalid number of operands!");
1206 addExpr(Inst, getImm(), isRV64Imm());
1211 APFloat(APFloat::IEEEdouble(),
APInt(64, getFPConst())));
1215 void addFenceArgOperands(
MCInst &Inst,
unsigned N)
const {
1216 assert(
N == 1 &&
"Invalid number of operands!");
1220 void addCSRSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
1221 assert(
N == 1 &&
"Invalid number of operands!");
1228 void addVTypeIOperands(
MCInst &Inst,
unsigned N)
const {
1229 assert(
N == 1 &&
"Invalid number of operands!");
1231 if (Kind == KindTy::Immediate) {
1233 [[maybe_unused]]
bool IsConstantImm =
1234 evaluateConstantImm(getImm(), Imm, VK);
1235 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1242 void addRlistOperands(
MCInst &Inst,
unsigned N)
const {
1243 assert(
N == 1 &&
"Invalid number of operands!");
1247 void addRegRegOperands(
MCInst &Inst,
unsigned N)
const {
1248 assert(
N == 1 &&
"Invalid number of operands!");
1253 void addSpimmOperands(
MCInst &Inst,
unsigned N)
const {
1254 assert(
N == 1 &&
"Invalid number of operands!");
1258 void addFRMArgOperands(
MCInst &Inst,
unsigned N)
const {
1259 assert(
N == 1 &&
"Invalid number of operands!");
1265#define GET_REGISTER_MATCHER
1266#define GET_SUBTARGET_FEATURE_NAME
1267#define GET_MATCHER_IMPLEMENTATION
1268#define GET_MNEMONIC_SPELL_CHECKER
1269#include "RISCVGenAsmMatcher.inc"
1272 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1273 return Reg - RISCV::F0_D + RISCV::F0_H;
1277 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1278 return Reg - RISCV::F0_D + RISCV::F0_F;
1283 unsigned RegClassID;
1284 if (Kind == MCK_VRM2)
1285 RegClassID = RISCV::VRM2RegClassID;
1286 else if (Kind == MCK_VRM4)
1287 RegClassID = RISCV::VRM4RegClassID;
1288 else if (Kind == MCK_VRM8)
1289 RegClassID = RISCV::VRM8RegClassID;
1293 &RISCVMCRegisterClasses[RegClassID]);
1298 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1300 return Match_InvalidOperand;
1304 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg);
1306 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg);
1307 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg);
1311 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1312 (IsRegFPR64C &&
Kind == MCK_FPR32C)) {
1314 return Match_Success;
1318 if (IsRegFPR64 && Kind == MCK_FPR16) {
1320 return Match_Success;
1324 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1326 if (
Op.Reg.RegNum == 0)
1327 return Match_InvalidOperand;
1328 return Match_Success;
1330 return Match_InvalidOperand;
1333unsigned RISCVAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
1337 if (MCID.
operands()[
I].RegClass == RISCV::GPRPairRegClassID) {
1342 if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].
contains(
Reg))
1346 if (((
Reg.id() - RISCV::X0) & 1) != 0)
1347 return Match_RequiresEvenGPRs;
1351 return Match_Success;
1354bool RISCVAsmParser::generateImmOutOfRangeError(
1356 const Twine &Msg =
"immediate must be an integer in the range") {
1360bool RISCVAsmParser::generateImmOutOfRangeError(
1362 const Twine &Msg =
"immediate must be an integer in the range") {
1364 return generateImmOutOfRangeError(ErrorLoc,
Lower,
Upper, Msg);
1367bool RISCVAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1371 bool MatchingInlineAsm) {
1381 if (validateInstruction(Inst,
Operands))
1383 return processInstruction(Inst, IDLoc,
Operands, Out);
1384 case Match_MissingFeature: {
1385 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1386 bool FirstFeature =
true;
1387 std::string Msg =
"instruction requires the following:";
1388 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1389 if (MissingFeatures[i]) {
1390 Msg += FirstFeature ?
" " :
", ";
1392 FirstFeature =
false;
1395 return Error(IDLoc, Msg);
1397 case Match_MnemonicFail: {
1398 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1399 std::string Suggestion = RISCVMnemonicSpellCheck(
1400 ((RISCVOperand &)*
Operands[0]).getToken(), FBS, 0);
1401 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1403 case Match_InvalidOperand: {
1404 SMLoc ErrorLoc = IDLoc;
1407 return Error(ErrorLoc,
"too few operands for instruction");
1410 if (ErrorLoc ==
SMLoc())
1413 return Error(ErrorLoc,
"invalid operand for instruction");
1420 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1421 SMLoc ErrorLoc = IDLoc;
1423 return Error(ErrorLoc,
"too few operands for instruction");
1429 case Match_RequiresEvenGPRs:
1431 "double precision floating point operands must use even "
1432 "numbered X register");
1433 case Match_InvalidImmXLenLI:
1436 return Error(ErrorLoc,
"operand must be a constant 64-bit integer");
1439 std::numeric_limits<int32_t>::min(),
1440 std::numeric_limits<uint32_t>::max());
1441 case Match_InvalidImmXLenLI_Restricted:
1444 return Error(ErrorLoc,
"operand either must be a constant 64-bit integer "
1445 "or a bare symbol name");
1447 return generateImmOutOfRangeError(
1449 std::numeric_limits<uint32_t>::max(),
1450 "operand either must be a bare symbol name or an immediate integer in "
1452 case Match_InvalidImmZero: {
1454 return Error(ErrorLoc,
"immediate must be zero");
1456 case Match_InvalidUImmLog2XLen:
1460 case Match_InvalidUImmLog2XLenNonZero:
1464 case Match_InvalidUImmLog2XLenHalf:
1468 case Match_InvalidUImm1:
1470 case Match_InvalidUImm2:
1472 case Match_InvalidUImm2Lsb0:
1474 "immediate must be one of");
1475 case Match_InvalidUImm3:
1477 case Match_InvalidUImm4:
1479 case Match_InvalidUImm5:
1481 case Match_InvalidUImm6:
1483 case Match_InvalidUImm7:
1485 case Match_InvalidUImm8:
1487 case Match_InvalidUImm8GE32:
1489 case Match_InvalidSImm5:
1492 case Match_InvalidSImm6:
1495 case Match_InvalidSImm6NonZero:
1496 return generateImmOutOfRangeError(
1498 "immediate must be non-zero in the range");
1499 case Match_InvalidCLUIImm:
1500 return generateImmOutOfRangeError(
1502 "immediate must be in [0xfffe0, 0xfffff] or");
1503 case Match_InvalidUImm7Lsb00:
1504 return generateImmOutOfRangeError(
1506 "immediate must be a multiple of 4 bytes in the range");
1507 case Match_InvalidUImm8Lsb00:
1508 return generateImmOutOfRangeError(
1510 "immediate must be a multiple of 4 bytes in the range");
1511 case Match_InvalidUImm8Lsb000:
1512 return generateImmOutOfRangeError(
1514 "immediate must be a multiple of 8 bytes in the range");
1515 case Match_InvalidSImm9Lsb0:
1516 return generateImmOutOfRangeError(
1518 "immediate must be a multiple of 2 bytes in the range");
1519 case Match_InvalidUImm9Lsb000:
1520 return generateImmOutOfRangeError(
1522 "immediate must be a multiple of 8 bytes in the range");
1523 case Match_InvalidUImm10Lsb00NonZero:
1524 return generateImmOutOfRangeError(
1526 "immediate must be a multiple of 4 bytes in the range");
1527 case Match_InvalidSImm10Lsb0000NonZero:
1528 return generateImmOutOfRangeError(
1530 "immediate must be a multiple of 16 bytes and non-zero in the range");
1531 case Match_InvalidSImm12:
1532 return generateImmOutOfRangeError(
1534 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an "
1535 "integer in the range");
1536 case Match_InvalidSImm12Lsb0:
1537 return generateImmOutOfRangeError(
1539 "immediate must be a multiple of 2 bytes in the range");
1540 case Match_InvalidSImm12Lsb00000:
1541 return generateImmOutOfRangeError(
1543 "immediate must be a multiple of 32 bytes in the range");
1544 case Match_InvalidSImm13Lsb0:
1545 return generateImmOutOfRangeError(
1547 "immediate must be a multiple of 2 bytes in the range");
1548 case Match_InvalidUImm20LUI:
1550 "operand must be a symbol with "
1551 "%hi/%tprel_hi modifier or an integer in "
1553 case Match_InvalidUImm20:
1555 case Match_InvalidUImm20AUIPC:
1556 return generateImmOutOfRangeError(
1558 "operand must be a symbol with a "
1559 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
1560 "an integer in the range");
1561 case Match_InvalidSImm21Lsb0JAL:
1562 return generateImmOutOfRangeError(
1564 "immediate must be a multiple of 2 bytes in the range");
1565 case Match_InvalidCSRSystemRegister: {
1567 "operand must be a valid system register "
1568 "name or an integer in the range");
1570 case Match_InvalidLoadFPImm: {
1572 return Error(ErrorLoc,
"operand must be a valid floating-point constant");
1574 case Match_InvalidBareSymbol: {
1576 return Error(ErrorLoc,
"operand must be a bare symbol name");
1578 case Match_InvalidPseudoJumpSymbol: {
1580 return Error(ErrorLoc,
"operand must be a valid jump target");
1582 case Match_InvalidCallSymbol: {
1584 return Error(ErrorLoc,
"operand must be a bare symbol name");
1586 case Match_InvalidTPRelAddSymbol: {
1588 return Error(ErrorLoc,
"operand must be a symbol with %tprel_add modifier");
1590 case Match_InvalidTLSDESCCallSymbol: {
1592 return Error(ErrorLoc,
1593 "operand must be a symbol with %tlsdesc_call modifier");
1595 case Match_InvalidRTZArg: {
1597 return Error(ErrorLoc,
"operand must be 'rtz' floating-point rounding mode");
1599 case Match_InvalidVTypeI: {
1601 return generateVTypeError(ErrorLoc);
1603 case Match_InvalidVMaskRegister: {
1605 return Error(ErrorLoc,
"operand must be v0.t");
1607 case Match_InvalidSImm5Plus1: {
1610 "immediate must be in the range");
1612 case Match_InvalidRlist: {
1616 "operand must be {ra [, s0[-sN]]} or {x1 [, x8[-x9][, x18[-xN]]]}");
1618 case Match_InvalidStackAdj: {
1622 "stack adjustment is invalid for this instruction and register list; "
1623 "refer to Zc spec for a detailed range of stack adjustment");
1625 case Match_InvalidRnumArg: {
1628 case Match_InvalidRegReg: {
1630 return Error(ErrorLoc,
"operands must be register and register");
1648 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1649 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1652 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1653 Reg = RISCV::NoRegister;
1659 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1660 return Error(StartLoc,
"invalid register name");
1666 const AsmToken &Tok = getParser().getTok();
1681 SMLoc FirstS = getLoc();
1682 bool HadParens =
false;
1689 size_t ReadCount = getLexer().peekTokens(Buf);
1692 LParen = getParser().getTok();
1697 switch (getLexer().getKind()) {
1700 getLexer().UnLex(LParen);
1708 getLexer().UnLex(LParen);
1712 Operands.push_back(RISCVOperand::createToken(
"(", FirstS));
1716 Operands.push_back(RISCVOperand::createReg(RegNo, S,
E));
1721 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
1732 switch (getLexer().getKind()) {
1742 if (getParser().parseExpression(Res,
E))
1745 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1747 int64_t
Imm =
CE->getValue();
1748 if (isUInt<7>(Imm)) {
1749 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1758 if (getParser().parseIdentifier(Identifier))
1761 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1763 assert(isUInt<7>(Opcode->Value) && (Opcode->Value & 0x3) == 3 &&
1764 "Unexpected opcode");
1767 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1777 return generateImmOutOfRangeError(
1779 "opcode must be a valid opcode name or an immediate in the range");
1787 switch (getLexer().getKind()) {
1797 if (getParser().parseExpression(Res,
E))
1800 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1802 int64_t
Imm =
CE->getValue();
1803 if (Imm >= 0 && Imm <= 2) {
1804 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1813 if (getParser().parseIdentifier(Identifier))
1817 if (Identifier ==
"C0")
1819 else if (Identifier ==
"C1")
1821 else if (Identifier ==
"C2")
1828 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1837 return generateImmOutOfRangeError(
1839 "opcode must be a valid opcode name or an immediate in the range");
1846 switch (getLexer().getKind()) {
1856 if (getParser().parseExpression(Res))
1859 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1861 int64_t
Imm =
CE->getValue();
1862 if (isUInt<12>(Imm)) {
1863 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm);
1867 RISCVOperand::createSysReg(SysReg ? SysReg->Name :
"", S, Imm));
1872 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1876 if (getParser().parseIdentifier(Identifier))
1879 auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1881 SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier);
1883 if ((SysReg = RISCVSysReg::lookupSysRegByDeprecatedName(Identifier)))
1884 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
1885 SysReg->Name +
"'");
1889 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits()))
1890 return Error(S,
"system register use requires an option to be enabled");
1892 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
1896 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
1897 "operand must be a valid system register "
1898 "name or an integer in the range");
1902 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1915 if (
Identifier.compare_insensitive(
"inf") == 0) {
1918 getTok().getEndLoc(), isRV64()));
1919 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
1922 getTok().getEndLoc(), isRV64()));
1923 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
1926 getTok().getEndLoc(), isRV64()));
1928 return TokError(
"invalid floating point literal");
1941 return TokError(
"invalid floating point immediate");
1944 APFloat RealVal(APFloat::IEEEdouble());
1946 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
1948 return TokError(
"invalid floating point representation");
1951 RealVal.changeSign();
1953 Operands.push_back(RISCVOperand::createFPImm(
1954 RealVal.bitcastToAPInt().getZExtValue(), S));
1966 switch (getLexer().getKind()) {
1978 if (getParser().parseExpression(Res,
E))
1982 return parseOperandWithModifier(
Operands);
1985 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1997 return Error(getLoc(),
"expected valid identifier for operand modifier");
2001 return Error(getLoc(),
"unrecognized operand modifier");
2008 if (getParser().parseParenExpression(SubExpr,
E))
2012 Operands.push_back(RISCVOperand::createImm(ModExpr, S,
E, isRV64()));
2024 AsmToken Tok = getLexer().getTok();
2026 if (getParser().parseIdentifier(Identifier))
2032 return Error(getLoc(),
"'@plt' operand not valid for instruction");
2034 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
2036 if (
Sym->isVariable()) {
2037 const MCExpr *
V =
Sym->getVariableValue(
false);
2038 if (!isa<MCSymbolRefExpr>(V)) {
2039 getLexer().UnLex(Tok);
2047 switch (getLexer().getKind()) {
2049 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2062 if (getParser().parseExpression(Expr,
E))
2065 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2081 if (getParser().parseIdentifier(Identifier))
2089 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
2092 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2101 if (getParser().parseExpression(Res,
E))
2104 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef ||
2105 cast<MCSymbolRefExpr>(Res)->getKind() ==
2106 MCSymbolRefExpr::VariantKind::VK_PLT)
2107 return Error(S,
"operand must be a valid jump target");
2110 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2131bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2132 unsigned &Sew,
unsigned &Lmul,
2133 bool &Fractional,
bool &TailAgnostic,
2134 bool &MaskAgnostic) {
2141 case VTypeState_SEW:
2148 State = VTypeState_LMUL;
2150 case VTypeState_LMUL: {
2158 State = VTypeState_TailPolicy;
2161 case VTypeState_TailPolicy:
2162 if (Identifier ==
"ta")
2163 TailAgnostic =
true;
2164 else if (Identifier ==
"tu")
2165 TailAgnostic =
false;
2168 State = VTypeState_MaskPolicy;
2170 case VTypeState_MaskPolicy:
2171 if (Identifier ==
"ma")
2172 MaskAgnostic =
true;
2173 else if (Identifier ==
"mu")
2174 MaskAgnostic =
false;
2177 State = VTypeState_Done;
2179 case VTypeState_Done:
2192 bool Fractional =
false;
2193 bool TailAgnostic =
false;
2194 bool MaskAgnostic =
false;
2196 VTypeState State = VTypeState_SEW;
2198 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2205 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2217 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2221 return generateVTypeError(S);
2224bool RISCVAsmParser::generateVTypeError(
SMLoc ErrorLoc) {
2228 "e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2236 if (!
Name.consume_back(
".t"))
2237 return Error(getLoc(),
"expected '.t' suffix");
2242 if (RegNo != RISCV::V0)
2247 Operands.push_back(RISCVOperand::createReg(RegNo, S,
E));
2263 Operands.push_back(RISCVOperand::createReg(
2264 RegNo, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2268template <
bool IsRV64>
2270 return parseGPRPair(
Operands, IsRV64);
2280 if (!IsRV64Inst && isRV64())
2292 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(RegNo))
2295 if ((RegNo - RISCV::X0) & 1)
2296 return TokError(
"register must be even");
2304 RegNo, RISCV::sub_gpr_even,
2305 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2306 Operands.push_back(RISCVOperand::createReg(Pair, S,
E));
2313 "operand must be a valid floating point rounding mode mnemonic");
2315 StringRef Str = getLexer().getTok().getIdentifier();
2320 "operand must be a valid floating point rounding mode mnemonic");
2322 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2328 const AsmToken &Tok = getLexer().getTok();
2334 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2348 for (
char c : Str) {
2377 Operands.push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2383 return TokError(
"operand must be formed of letters selected in-order from "
2390 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
2392 if (!parseRegister(
Operands).isSuccess())
2393 return Error(getLoc(),
"expected register");
2397 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2421 std::unique_ptr<RISCVOperand> OptionalImmOp;
2428 SMLoc ImmStart = getLoc();
2429 if (getParser().parseIntToken(ImmVal,
2430 "expected '(' or optional integer offset"))
2435 SMLoc ImmEnd = getLoc();
2438 ImmStart, ImmEnd, isRV64());
2442 OptionalImmOp ?
"expected '(' after optional integer offset"
2443 :
"expected '(' or optional integer offset"))
2446 if (!parseRegister(
Operands).isSuccess())
2447 return Error(getLoc(),
"expected register");
2453 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2455 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2456 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2469 return Error(getLoc(),
"invalid register");
2476 return Error(getLoc(),
"expected register");
2478 StringRef Reg2Name = getLexer().getTok().getIdentifier();
2481 return Error(getLoc(),
"invalid register");
2487 Operands.push_back(RISCVOperand::createRegReg(
Reg, Reg2, getLoc()));
2500 bool IsEABI = isRVE();
2503 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2508 if (RegStart != RISCV::X1)
2509 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2515 return Error(getLoc(),
"invalid register");
2519 return Error(getLoc(),
"invalid register");
2520 if (RegStart != RISCV::X8)
2521 return Error(getLoc(),
2522 "continuous register list must start from 's0' or 'x8'");
2528 StringRef EndName = getLexer().getTok().getIdentifier();
2532 return Error(getLoc(),
"invalid register");
2533 if (IsEABI && RegEnd != RISCV::X9)
2534 return Error(getLoc(),
"contiguous register list of EABI can only be "
2535 "'s0-s1' or 'x8-x9' pair");
2542 if (RegEnd != RISCV::X9)
2545 "first contiguous registers pair of register list must be 'x8-x9'");
2549 return Error(getLoc(),
"invalid register");
2550 StringRef EndName = getLexer().getTok().getIdentifier();
2552 return Error(getLoc(),
2553 "second contiguous registers pair of register list "
2554 "must start from 'x18'");
2560 return Error(getLoc(),
"invalid register");
2561 EndName = getLexer().getTok().getIdentifier();
2563 return Error(getLoc(),
"invalid register");
2570 if (RegEnd == RISCV::X26)
2571 return Error(getLoc(),
"invalid register list, {ra, s0-s10} or {x1, x8-x9, "
2572 "x18-x26} is not supported");
2577 if (RegEnd == RISCV::NoRegister)
2582 return Error(S,
"invalid register list");
2583 Operands.push_back(RISCVOperand::createRlist(Encode, S));
2589 bool ExpectNegative) {
2595 unsigned RlistVal =
static_cast<RISCVOperand *
>(
Operands[1].get())->Rlist.Val;
2597 if (Negative != ExpectNegative ||
2600 Operands.push_back(RISCVOperand::createSpimm(Spimm << 4, S));
2612 MatchOperandParserImpl(
Operands, Mnemonic,
true);
2619 if (parseRegister(
Operands,
true).isSuccess())
2626 return !parseMemOpBaseReg(
Operands).isSuccess();
2631 Error(getLoc(),
"unknown operand");
2644 if (getSTI().hasFeature(RISCV::FeatureRelax)) {
2645 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
2646 if (Assembler !=
nullptr) {
2654 Operands.push_back(RISCVOperand::createToken(
Name, NameLoc));
2673 if (getParser().parseEOL(
"unexpected token")) {
2674 getParser().eatToEndOfStatement();
2680bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
2684 if (
const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
2685 Kind = RE->getKind();
2686 Expr = RE->getSubExpr();
2696bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
2709 if (IDVal ==
".option")
2710 return parseDirectiveOption();
2711 if (IDVal ==
".attribute")
2712 return parseDirectiveAttribute();
2713 if (IDVal ==
".insn")
2714 return parseDirectiveInsn(DirectiveID.
getLoc());
2715 if (IDVal ==
".variant_cc")
2716 return parseDirectiveVariantCC();
2721bool RISCVAsmParser::resetToArch(
StringRef Arch,
SMLoc Loc, std::string &Result,
2722 bool FromOptionDirective) {
2725 clearFeatureBits(Feature.Value, Feature.Key);
2734 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
2735 << ErrMsg.getMessage();
2738 return Error(Loc, OutputErrMsg.str());
2740 auto &ISAInfo = *ParseResult;
2743 if (ISAInfo->hasExtension(Feature.Key))
2744 setFeatureBits(Feature.Value, Feature.Key);
2746 if (FromOptionDirective) {
2747 if (ISAInfo->getXLen() == 32 && isRV64())
2748 return Error(Loc,
"bad arch string switching from rv64 to rv32");
2749 else if (ISAInfo->getXLen() == 64 && !isRV64())
2750 return Error(Loc,
"bad arch string switching from rv32 to rv64");
2753 if (ISAInfo->getXLen() == 32)
2754 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
2755 else if (ISAInfo->getXLen() == 64)
2756 setFeatureBits(RISCV::Feature64Bit,
"64bit");
2758 return Error(Loc,
"bad arch string " + Arch);
2760 Result = ISAInfo->toString();
2764bool RISCVAsmParser::parseDirectiveOption() {
2775 if (Option ==
"push") {
2779 getTargetStreamer().emitDirectiveOptionPush();
2784 if (Option ==
"pop") {
2789 getTargetStreamer().emitDirectiveOptionPop();
2790 if (popFeatureBits())
2791 return Error(StartLoc,
".option pop with no .option push");
2796 if (Option ==
"arch") {
2804 Type = RISCVOptionArchArgType::Plus;
2806 Type = RISCVOptionArchArgType::Minus;
2807 else if (!
Args.empty())
2809 "unexpected token, expected + or -");
2811 Type = RISCVOptionArchArgType::Full;
2815 "unexpected token, expected identifier");
2821 if (
Type == RISCVOptionArchArgType::Full) {
2823 if (resetToArch(Arch, Loc, Result,
true))
2832 Loc,
"Extension version number parsing not currently implemented");
2835 if (!enableExperimentalExtension() &&
2837 return Error(Loc,
"Unexpected experimental extensions.");
2840 return Error(Loc,
"unknown extension feature");
2844 if (
Type == RISCVOptionArchArgType::Plus) {
2847 setFeatureBits(
Ext->Value,
Ext->Key);
2850 copySTI().setFeatureBits(OldFeatureBits);
2851 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
2856 OutputErrMsg << ErrMsg.getMessage();
2859 return Error(Loc, OutputErrMsg.str());
2862 assert(
Type == RISCVOptionArchArgType::Minus);
2867 if (getSTI().hasFeature(Feature.Value) &&
2868 Feature.Implies.test(
Ext->Value))
2870 Twine(
"Can't disable ") +
Ext->Key +
" extension, " +
2871 Feature.Key +
" extension requires " +
Ext->Key +
2872 " extension be enabled");
2875 clearFeatureBits(
Ext->Value,
Ext->Key);
2882 getTargetStreamer().emitDirectiveOptionArch(Args);
2886 if (Option ==
"rvc") {
2890 getTargetStreamer().emitDirectiveOptionRVC();
2891 setFeatureBits(RISCV::FeatureStdExtC,
"c");
2895 if (Option ==
"norvc") {
2899 getTargetStreamer().emitDirectiveOptionNoRVC();
2900 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
2901 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
2905 if (Option ==
"pic") {
2909 getTargetStreamer().emitDirectiveOptionPIC();
2910 ParserOptions.IsPicEnabled =
true;
2914 if (Option ==
"nopic") {
2918 getTargetStreamer().emitDirectiveOptionNoPIC();
2919 ParserOptions.IsPicEnabled =
false;
2923 if (Option ==
"relax") {
2927 getTargetStreamer().emitDirectiveOptionRelax();
2928 setFeatureBits(RISCV::FeatureRelax,
"relax");
2932 if (Option ==
"norelax") {
2936 getTargetStreamer().emitDirectiveOptionNoRelax();
2937 clearFeatureBits(RISCV::FeatureRelax,
"relax");
2943 "'rvc', 'norvc', 'arch', 'relax' or "
2952bool RISCVAsmParser::parseDirectiveAttribute() {
2959 std::optional<unsigned>
Ret =
2962 return Error(TagLoc,
"attribute name not recognised: " +
Name);
2973 if (
check(!CE, TagLoc,
"expected numeric constant"))
2976 Tag =
CE->getValue();
2983 int64_t IntegerValue = 0;
2984 bool IsIntegerValue =
true;
2989 IsIntegerValue =
false;
2992 if (IsIntegerValue) {
2999 return Error(ValueExprLoc,
"expected numeric constant");
3000 IntegerValue =
CE->getValue();
3013 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3015 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3018 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3022 getTargetStreamer().emitTextAttribute(
Tag, Result);
3030 .
Cases(
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s",
true)
3031 .
Cases(
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj", AllowC)
3037bool RISCVAsmParser::parseDirectiveInsn(
SMLoc L) {
3044 return Error(ErrorLoc,
"expected instruction format");
3046 bool AllowC = getSTI().hasFeature(RISCV::FeatureStdExtC) ||
3047 getSTI().hasFeature(RISCV::FeatureStdExtZca);
3049 return Error(ErrorLoc,
"invalid instruction format");
3051 std::string FormatName = (
".insn_" +
Format).str();
3068bool RISCVAsmParser::parseDirectiveVariantCC() {
3070 if (getParser().parseIdentifier(
Name))
3071 return TokError(
"expected symbol name");
3074 getTargetStreamer().emitDirectiveVariantCC(
3075 *getContext().getOrCreateSymbol(
Name));
3083 ++RISCVNumInstrsCompressed;
3092 for (
MCInst &Inst : Seq) {
3093 emitToStreamer(Out, Inst);
3100 unsigned SecondOpcode,
SMLoc IDLoc,
3114 const MCExpr *RefToLinkTmpLabel =
3121 .addExpr(RefToLinkTmpLabel));
3124void RISCVAsmParser::emitLoadLocalAddress(
MCInst &Inst,
SMLoc IDLoc,
3135 RISCV::ADDI, IDLoc, Out);
3138void RISCVAsmParser::emitLoadGlobalAddress(
MCInst &Inst,
SMLoc IDLoc,
3148 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3150 SecondOpcode, IDLoc, Out);
3153void RISCVAsmParser::emitLoadAddress(
MCInst &Inst,
SMLoc IDLoc,
3162 if (ParserOptions.IsPicEnabled)
3163 emitLoadGlobalAddress(Inst, IDLoc, Out);
3165 emitLoadLocalAddress(Inst, IDLoc, Out);
3168void RISCVAsmParser::emitLoadTLSIEAddress(
MCInst &Inst,
SMLoc IDLoc,
3178 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3180 SecondOpcode, IDLoc, Out);
3183void RISCVAsmParser::emitLoadTLSGDAddress(
MCInst &Inst,
SMLoc IDLoc,
3194 RISCV::ADDI, IDLoc, Out);
3197void RISCVAsmParser::emitLoadStoreSymbol(
MCInst &Inst,
unsigned Opcode,
3207 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3209 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3213 Opcode, IDLoc, Out);
3216void RISCVAsmParser::emitPseudoExtend(
MCInst &Inst,
bool SignExtend,
3217 int64_t Width,
SMLoc IDLoc,
3229 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3230 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3232 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3245void RISCVAsmParser::emitVMSGE(
MCInst &Inst,
unsigned Opcode,
SMLoc IDLoc,
3256 .addReg(RISCV::NoRegister)
3269 "The destination register should not be V0.");
3288 "The destination register should be V0.");
3290 "The temporary vector register should not be V0.");
3295 .addReg(RISCV::NoRegister)
3309 "The temporary vector register should not be V0.");
3314 .addReg(RISCV::NoRegister)
3334bool RISCVAsmParser::checkPseudoAddTPRel(
MCInst &Inst,
3336 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3339 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3340 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3341 "%tprel_add modifier");
3347bool RISCVAsmParser::checkPseudoTLSDESCCall(
MCInst &Inst,
3349 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
3352 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3353 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
3354 "%tlsdesc_call modifier");
3360std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3361 return RISCVOperand::createReg(RISCV::NoRegister,
llvm::SMLoc(),
3365std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3366 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3370std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3371 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3375bool RISCVAsmParser::validateInstruction(
MCInst &Inst,
3379 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3380 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3383 if (DestReg == TempReg) {
3385 return Error(Loc,
"The temporary vector register cannot be the same as "
3386 "the destination register.");
3390 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3391 Opcode == RISCV::TH_LWD) {
3396 if (Rs1 == Rd1 && Rs1 == Rd2) {
3398 return Error(Loc,
"The source register and destination registers "
3399 "cannot be equal.");
3403 if (Opcode == RISCV::CM_MVSA01) {
3408 return Error(Loc,
"'rs1' and 'rs2' must be different.");
3412 bool IsTHeadMemPair32 = (Opcode == RISCV::TH_LWD ||
3413 Opcode == RISCV::TH_LWUD || Opcode == RISCV::TH_SWD);
3414 bool IsTHeadMemPair64 = (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_SDD);
3419 return Error(Loc,
"Operand must be constant 3.");
3422 return Error(Loc,
"Operand must be constant 4.");
3429 if (Opcode == RISCV::VC_V_XVW || Opcode == RISCV::VC_V_IVW ||
3430 Opcode == RISCV::VC_V_FVW || Opcode == RISCV::VC_V_VVW) {
3436 if (VCIXDst == VCIXRs1)
3437 return Error(VCIXDstLoc,
"The destination vector register group cannot"
3438 " overlap the source vector register group.");
3442 if (VCIXDst == VCIXRs2)
3443 return Error(VCIXDstLoc,
"The destination vector register group cannot"
3444 " overlap the source vector register group.");
3459 if (DestReg == CheckReg)
3460 return Error(Loc,
"The destination vector register group cannot overlap"
3461 " the source vector register group.");
3465 if (DestReg == CheckReg)
3466 return Error(Loc,
"The destination vector register group cannot overlap"
3467 " the source vector register group.");
3472 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM ||
3473 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM ||
3474 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM ||
3475 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM ||
3476 Opcode == RISCV::VMERGE_VXM)
3477 return Error(Loc,
"The destination vector register group cannot be V0.");
3484 assert((CheckReg == RISCV::V0 || CheckReg == RISCV::NoRegister) &&
3485 "Unexpected register for mask operand");
3487 if (DestReg == CheckReg)
3488 return Error(Loc,
"The destination vector register group cannot overlap"
3489 " the mask register.");
3494bool RISCVAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
3502 case RISCV::PseudoLLAImm:
3503 case RISCV::PseudoLAImm:
3504 case RISCV::PseudoLI: {
3521 Imm = SignExtend64<32>(Imm);
3522 emitLoadImm(
Reg, Imm, Out);
3525 case RISCV::PseudoLLA:
3526 emitLoadLocalAddress(Inst, IDLoc, Out);
3528 case RISCV::PseudoLGA:
3529 emitLoadGlobalAddress(Inst, IDLoc, Out);
3531 case RISCV::PseudoLA:
3532 emitLoadAddress(Inst, IDLoc, Out);
3534 case RISCV::PseudoLA_TLS_IE:
3535 emitLoadTLSIEAddress(Inst, IDLoc, Out);
3537 case RISCV::PseudoLA_TLS_GD:
3538 emitLoadTLSGDAddress(Inst, IDLoc, Out);
3540 case RISCV::PseudoLB:
3541 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
3543 case RISCV::PseudoLBU:
3544 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
3546 case RISCV::PseudoLH:
3547 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
3549 case RISCV::PseudoLHU:
3550 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
3552 case RISCV::PseudoLW:
3553 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
3555 case RISCV::PseudoLWU:
3556 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
3558 case RISCV::PseudoLD:
3559 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
3561 case RISCV::PseudoFLH:
3562 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
3564 case RISCV::PseudoFLW:
3565 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
3567 case RISCV::PseudoFLD:
3568 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
3570 case RISCV::PseudoSB:
3571 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
3573 case RISCV::PseudoSH:
3574 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
3576 case RISCV::PseudoSW:
3577 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
3579 case RISCV::PseudoSD:
3580 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
3582 case RISCV::PseudoFSH:
3583 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
3585 case RISCV::PseudoFSW:
3586 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
3588 case RISCV::PseudoFSD:
3589 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
3591 case RISCV::PseudoAddTPRel:
3592 if (checkPseudoAddTPRel(Inst,
Operands))
3595 case RISCV::PseudoTLSDESCCall:
3596 if (checkPseudoTLSDESCCall(Inst,
Operands))
3599 case RISCV::PseudoSEXT_B:
3600 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
3602 case RISCV::PseudoSEXT_H:
3603 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
3605 case RISCV::PseudoZEXT_H:
3606 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
3608 case RISCV::PseudoZEXT_W:
3609 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
3611 case RISCV::PseudoVMSGEU_VX:
3612 case RISCV::PseudoVMSGEU_VX_M:
3613 case RISCV::PseudoVMSGEU_VX_M_T:
3614 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
3616 case RISCV::PseudoVMSGE_VX:
3617 case RISCV::PseudoVMSGE_VX_M:
3618 case RISCV::PseudoVMSGE_VX_M_T:
3619 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
3621 case RISCV::PseudoVMSGE_VI:
3622 case RISCV::PseudoVMSLT_VI: {
3626 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
3636 case RISCV::PseudoVMSGEU_VI:
3637 case RISCV::PseudoVMSLTU_VI: {
3644 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3655 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3670 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 std::string getTargetFeatureForExtension(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.
std::string str() const
str - Get the contents as an std::string.
char back() const
back - Get the last character in the string.
A switch()-like statement whose cases are string literals.
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
uint16_t StackAdjustment(const RuntimeFunction &RF)
StackAdjustment - calculated stack adjustment in words.
std::optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)
ABI computeTargetABI(const Triple &TT, const FeatureBitset &FeatureBits, StringRef ABIName)
const TagNameMap & getRISCVAttributeTags()
static RoundingMode stringToRoundingMode(StringRef Str)
llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseFeatureBits(bool IsRV64, const FeatureBitset &FeatureBits)
int getLoadFPImm(APFloat FPImm)
getLoadFPImm - Return a 5-bit binary encoding of the floating-point immediate value.
void generateMCInstSeq(int64_t Val, const MCSubtargetInfo &STI, MCRegister DestReg, SmallVectorImpl< MCInst > &Insts)
bool compress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI)
static bool isValidLMUL(unsigned LMUL, bool Fractional)
static RISCVII::VLMUL encodeLMUL(unsigned LMUL, bool Fractional)
static bool isValidSEW(unsigned SEW)
void printVType(unsigned VType, raw_ostream &OS)
unsigned encodeVTYPE(RISCVII::VLMUL VLMUL, unsigned SEW, bool TailAgnostic, bool MaskAgnostic)
unsigned encodeRlist(MCRegister EndReg, bool IsRV32E=false)
void printRlist(unsigned SlistEncode, raw_ostream &OS)
static bool getSpimm(unsigned RlistVal, unsigned &SpimmVal, int64_t StackAdjustment, bool IsRV64)
@ CE
Windows NT (Windows on ARM)
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Target & getTheRISCV32Target()
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
DWARFExpression::Operation Op
Target & getTheRISCV64Target()
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures]
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
Used to provide key value pairs for feature and CPU bit flags.