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 == 2 &&
"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: {
2160 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2161 unsigned MinLMUL = ELEN / 8;
2164 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2165 Twine(MinLMUL) +
" is reserved");
2168 State = VTypeState_TailPolicy;
2171 case VTypeState_TailPolicy:
2172 if (Identifier ==
"ta")
2173 TailAgnostic =
true;
2174 else if (Identifier ==
"tu")
2175 TailAgnostic =
false;
2178 State = VTypeState_MaskPolicy;
2180 case VTypeState_MaskPolicy:
2181 if (Identifier ==
"ma")
2182 MaskAgnostic =
true;
2183 else if (Identifier ==
"mu")
2184 MaskAgnostic =
false;
2187 State = VTypeState_Done;
2189 case VTypeState_Done:
2202 bool Fractional =
false;
2203 bool TailAgnostic =
false;
2204 bool MaskAgnostic =
false;
2206 VTypeState State = VTypeState_SEW;
2209 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2216 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2226 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2227 unsigned MaxSEW = ELEN / Lmul;
2229 if (MaxSEW >= 8 && Sew > MaxSEW)
2231 "use of vtype encodings with SEW > " +
Twine(MaxSEW) +
2232 " and LMUL == mf" +
Twine(Lmul) +
2233 " may not be compatible with all RVV implementations");
2238 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2242 return generateVTypeError(S);
2245bool RISCVAsmParser::generateVTypeError(
SMLoc ErrorLoc) {
2249 "e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2257 if (!
Name.consume_back(
".t"))
2258 return Error(getLoc(),
"expected '.t' suffix");
2263 if (RegNo != RISCV::V0)
2268 Operands.push_back(RISCVOperand::createReg(RegNo, S,
E));
2284 Operands.push_back(RISCVOperand::createReg(
2285 RegNo, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2289template <
bool IsRV64>
2291 return parseGPRPair(
Operands, IsRV64);
2301 if (!IsRV64Inst && isRV64())
2313 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(RegNo))
2316 if ((RegNo - RISCV::X0) & 1)
2317 return TokError(
"register must be even");
2325 RegNo, RISCV::sub_gpr_even,
2326 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2327 Operands.push_back(RISCVOperand::createReg(Pair, S,
E));
2334 "operand must be a valid floating point rounding mode mnemonic");
2336 StringRef Str = getLexer().getTok().getIdentifier();
2341 "operand must be a valid floating point rounding mode mnemonic");
2343 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2349 const AsmToken &Tok = getLexer().getTok();
2355 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2369 for (
char c : Str) {
2398 Operands.push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2404 return TokError(
"operand must be formed of letters selected in-order from "
2411 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
2413 if (!parseRegister(
Operands).isSuccess())
2414 return Error(getLoc(),
"expected register");
2418 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2442 std::unique_ptr<RISCVOperand> OptionalImmOp;
2449 SMLoc ImmStart = getLoc();
2450 if (getParser().parseIntToken(ImmVal,
2451 "expected '(' or optional integer offset"))
2456 SMLoc ImmEnd = getLoc();
2459 ImmStart, ImmEnd, isRV64());
2463 OptionalImmOp ?
"expected '(' after optional integer offset"
2464 :
"expected '(' or optional integer offset"))
2467 if (!parseRegister(
Operands).isSuccess())
2468 return Error(getLoc(),
"expected register");
2474 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2476 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2477 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2490 return Error(getLoc(),
"invalid register");
2497 return Error(getLoc(),
"expected register");
2499 StringRef Reg2Name = getLexer().getTok().getIdentifier();
2502 return Error(getLoc(),
"invalid register");
2508 Operands.push_back(RISCVOperand::createRegReg(
Reg, Reg2, getLoc()));
2521 bool IsEABI = isRVE();
2524 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2529 if (RegStart != RISCV::X1)
2530 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2536 return Error(getLoc(),
"invalid register");
2540 return Error(getLoc(),
"invalid register");
2541 if (RegStart != RISCV::X8)
2542 return Error(getLoc(),
2543 "continuous register list must start from 's0' or 'x8'");
2549 StringRef EndName = getLexer().getTok().getIdentifier();
2553 return Error(getLoc(),
"invalid register");
2554 if (IsEABI && RegEnd != RISCV::X9)
2555 return Error(getLoc(),
"contiguous register list of EABI can only be "
2556 "'s0-s1' or 'x8-x9' pair");
2563 if (RegEnd != RISCV::X9)
2566 "first contiguous registers pair of register list must be 'x8-x9'");
2570 return Error(getLoc(),
"invalid register");
2571 StringRef EndName = getLexer().getTok().getIdentifier();
2573 return Error(getLoc(),
2574 "second contiguous registers pair of register list "
2575 "must start from 'x18'");
2581 return Error(getLoc(),
"invalid register");
2582 EndName = getLexer().getTok().getIdentifier();
2584 return Error(getLoc(),
"invalid register");
2591 if (RegEnd == RISCV::X26)
2592 return Error(getLoc(),
"invalid register list, {ra, s0-s10} or {x1, x8-x9, "
2593 "x18-x26} is not supported");
2598 if (RegEnd == RISCV::NoRegister)
2603 return Error(S,
"invalid register list");
2604 Operands.push_back(RISCVOperand::createRlist(Encode, S));
2610 bool ExpectNegative) {
2616 unsigned RlistVal =
static_cast<RISCVOperand *
>(
Operands[1].get())->Rlist.Val;
2618 if (Negative != ExpectNegative ||
2621 Operands.push_back(RISCVOperand::createSpimm(Spimm << 4, S));
2633 MatchOperandParserImpl(
Operands, Mnemonic,
true);
2640 if (parseRegister(
Operands,
true).isSuccess())
2647 return !parseMemOpBaseReg(
Operands).isSuccess();
2652 Error(getLoc(),
"unknown operand");
2665 if (getSTI().hasFeature(RISCV::FeatureRelax)) {
2666 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
2667 if (Assembler !=
nullptr) {
2675 Operands.push_back(RISCVOperand::createToken(
Name, NameLoc));
2694 if (getParser().parseEOL(
"unexpected token")) {
2695 getParser().eatToEndOfStatement();
2701bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
2705 if (
const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
2706 Kind = RE->getKind();
2707 Expr = RE->getSubExpr();
2717bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
2730 if (IDVal ==
".option")
2731 return parseDirectiveOption();
2732 if (IDVal ==
".attribute")
2733 return parseDirectiveAttribute();
2734 if (IDVal ==
".insn")
2735 return parseDirectiveInsn(DirectiveID.
getLoc());
2736 if (IDVal ==
".variant_cc")
2737 return parseDirectiveVariantCC();
2742bool RISCVAsmParser::resetToArch(
StringRef Arch,
SMLoc Loc, std::string &Result,
2743 bool FromOptionDirective) {
2746 clearFeatureBits(Feature.Value, Feature.Key);
2755 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
2756 << ErrMsg.getMessage();
2759 return Error(Loc, OutputErrMsg.str());
2761 auto &ISAInfo = *ParseResult;
2764 if (ISAInfo->hasExtension(Feature.Key))
2765 setFeatureBits(Feature.Value, Feature.Key);
2767 if (FromOptionDirective) {
2768 if (ISAInfo->getXLen() == 32 && isRV64())
2769 return Error(Loc,
"bad arch string switching from rv64 to rv32");
2770 else if (ISAInfo->getXLen() == 64 && !isRV64())
2771 return Error(Loc,
"bad arch string switching from rv32 to rv64");
2774 if (ISAInfo->getXLen() == 32)
2775 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
2776 else if (ISAInfo->getXLen() == 64)
2777 setFeatureBits(RISCV::Feature64Bit,
"64bit");
2779 return Error(Loc,
"bad arch string " + Arch);
2781 Result = ISAInfo->toString();
2785bool RISCVAsmParser::parseDirectiveOption() {
2796 if (Option ==
"push") {
2800 getTargetStreamer().emitDirectiveOptionPush();
2805 if (Option ==
"pop") {
2810 getTargetStreamer().emitDirectiveOptionPop();
2811 if (popFeatureBits())
2812 return Error(StartLoc,
".option pop with no .option push");
2817 if (Option ==
"arch") {
2825 Type = RISCVOptionArchArgType::Plus;
2827 Type = RISCVOptionArchArgType::Minus;
2828 else if (!
Args.empty())
2830 "unexpected token, expected + or -");
2832 Type = RISCVOptionArchArgType::Full;
2836 "unexpected token, expected identifier");
2842 if (
Type == RISCVOptionArchArgType::Full) {
2844 if (resetToArch(Arch, Loc, Result,
true))
2853 Loc,
"extension version number parsing not currently implemented");
2856 if (!enableExperimentalExtension() &&
2858 return Error(Loc,
"unexpected experimental extensions");
2861 return Error(Loc,
"unknown extension feature");
2865 if (
Type == RISCVOptionArchArgType::Plus) {
2868 setFeatureBits(
Ext->Value,
Ext->Key);
2871 copySTI().setFeatureBits(OldFeatureBits);
2872 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
2877 OutputErrMsg << ErrMsg.getMessage();
2880 return Error(Loc, OutputErrMsg.str());
2883 assert(
Type == RISCVOptionArchArgType::Minus);
2888 if (getSTI().hasFeature(Feature.Value) &&
2889 Feature.Implies.test(
Ext->Value))
2891 " extension; " + Feature.Key +
2892 " extension requires " +
Ext->Key +
2896 clearFeatureBits(
Ext->Value,
Ext->Key);
2903 getTargetStreamer().emitDirectiveOptionArch(Args);
2907 if (Option ==
"rvc") {
2911 getTargetStreamer().emitDirectiveOptionRVC();
2912 setFeatureBits(RISCV::FeatureStdExtC,
"c");
2916 if (Option ==
"norvc") {
2920 getTargetStreamer().emitDirectiveOptionNoRVC();
2921 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
2922 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
2926 if (Option ==
"pic") {
2930 getTargetStreamer().emitDirectiveOptionPIC();
2931 ParserOptions.IsPicEnabled =
true;
2935 if (Option ==
"nopic") {
2939 getTargetStreamer().emitDirectiveOptionNoPIC();
2940 ParserOptions.IsPicEnabled =
false;
2944 if (Option ==
"relax") {
2948 getTargetStreamer().emitDirectiveOptionRelax();
2949 setFeatureBits(RISCV::FeatureRelax,
"relax");
2953 if (Option ==
"norelax") {
2957 getTargetStreamer().emitDirectiveOptionNoRelax();
2958 clearFeatureBits(RISCV::FeatureRelax,
"relax");
2964 "'rvc', 'norvc', 'arch', 'relax' or "
2973bool RISCVAsmParser::parseDirectiveAttribute() {
2980 std::optional<unsigned>
Ret =
2983 return Error(TagLoc,
"attribute name not recognised: " +
Name);
2994 if (
check(!CE, TagLoc,
"expected numeric constant"))
2997 Tag =
CE->getValue();
3004 int64_t IntegerValue = 0;
3005 bool IsIntegerValue =
true;
3010 IsIntegerValue =
false;
3013 if (IsIntegerValue) {
3020 return Error(ValueExprLoc,
"expected numeric constant");
3021 IntegerValue =
CE->getValue();
3034 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3036 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3039 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3043 getTargetStreamer().emitTextAttribute(
Tag, Result);
3051 .
Cases(
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s",
true)
3052 .
Cases(
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj", AllowC)
3058bool RISCVAsmParser::parseDirectiveInsn(
SMLoc L) {
3065 return Error(ErrorLoc,
"expected instruction format");
3067 bool AllowC = getSTI().hasFeature(RISCV::FeatureStdExtC) ||
3068 getSTI().hasFeature(RISCV::FeatureStdExtZca);
3070 return Error(ErrorLoc,
"invalid instruction format");
3072 std::string FormatName = (
".insn_" +
Format).str();
3089bool RISCVAsmParser::parseDirectiveVariantCC() {
3091 if (getParser().parseIdentifier(
Name))
3092 return TokError(
"expected symbol name");
3095 getTargetStreamer().emitDirectiveVariantCC(
3096 *getContext().getOrCreateSymbol(
Name));
3104 ++RISCVNumInstrsCompressed;
3113 for (
MCInst &Inst : Seq) {
3114 emitToStreamer(Out, Inst);
3121 unsigned SecondOpcode,
SMLoc IDLoc,
3135 const MCExpr *RefToLinkTmpLabel =
3142 .addExpr(RefToLinkTmpLabel));
3145void RISCVAsmParser::emitLoadLocalAddress(
MCInst &Inst,
SMLoc IDLoc,
3156 RISCV::ADDI, IDLoc, Out);
3159void RISCVAsmParser::emitLoadGlobalAddress(
MCInst &Inst,
SMLoc IDLoc,
3169 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3171 SecondOpcode, IDLoc, Out);
3174void RISCVAsmParser::emitLoadAddress(
MCInst &Inst,
SMLoc IDLoc,
3183 if (ParserOptions.IsPicEnabled)
3184 emitLoadGlobalAddress(Inst, IDLoc, Out);
3186 emitLoadLocalAddress(Inst, IDLoc, Out);
3189void RISCVAsmParser::emitLoadTLSIEAddress(
MCInst &Inst,
SMLoc IDLoc,
3199 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3201 SecondOpcode, IDLoc, Out);
3204void RISCVAsmParser::emitLoadTLSGDAddress(
MCInst &Inst,
SMLoc IDLoc,
3215 RISCV::ADDI, IDLoc, Out);
3218void RISCVAsmParser::emitLoadStoreSymbol(
MCInst &Inst,
unsigned Opcode,
3228 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3230 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3234 Opcode, IDLoc, Out);
3237void RISCVAsmParser::emitPseudoExtend(
MCInst &Inst,
bool SignExtend,
3238 int64_t Width,
SMLoc IDLoc,
3250 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3251 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3253 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3266void RISCVAsmParser::emitVMSGE(
MCInst &Inst,
unsigned Opcode,
SMLoc IDLoc,
3277 .addReg(RISCV::NoRegister)
3290 "The destination register should not be V0.");
3309 "The destination register should be V0.");
3311 "The temporary vector register should not be V0.");
3316 .addReg(RISCV::NoRegister)
3330 "The temporary vector register should not be V0.");
3335 .addReg(RISCV::NoRegister)
3355bool RISCVAsmParser::checkPseudoAddTPRel(
MCInst &Inst,
3357 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3360 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3361 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3362 "%tprel_add modifier");
3368bool RISCVAsmParser::checkPseudoTLSDESCCall(
MCInst &Inst,
3370 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
3373 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3374 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
3375 "%tlsdesc_call modifier");
3381std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3382 return RISCVOperand::createReg(RISCV::NoRegister,
llvm::SMLoc(),
3386std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3387 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3391std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3392 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3396bool RISCVAsmParser::validateInstruction(
MCInst &Inst,
3400 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3401 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3404 if (DestReg == TempReg) {
3406 return Error(Loc,
"the temporary vector register cannot be the same as "
3407 "the destination register");
3411 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3412 Opcode == RISCV::TH_LWD) {
3417 if (Rs1 == Rd1 && Rs1 == Rd2) {
3419 return Error(Loc,
"rs1, rd1, and rd2 cannot all be the same");
3423 if (Opcode == RISCV::CM_MVSA01) {
3428 return Error(Loc,
"rs1 and rs2 must be different");
3432 bool IsTHeadMemPair32 = (Opcode == RISCV::TH_LWD ||
3433 Opcode == RISCV::TH_LWUD || Opcode == RISCV::TH_SWD);
3434 bool IsTHeadMemPair64 = (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_SDD);
3439 return Error(Loc,
"operand must be constant 3");
3442 return Error(Loc,
"operand must be constant 4");
3449 if (Opcode == RISCV::VC_V_XVW || Opcode == RISCV::VC_V_IVW ||
3450 Opcode == RISCV::VC_V_FVW || Opcode == RISCV::VC_V_VVW) {
3456 if (VCIXDst == VCIXRs1)
3457 return Error(VCIXDstLoc,
"the destination vector register group cannot"
3458 " overlap the source vector register group");
3462 if (VCIXDst == VCIXRs2)
3463 return Error(VCIXDstLoc,
"the destination vector register group cannot"
3464 " overlap the source vector register group");
3479 if (DestReg == CheckReg)
3480 return Error(Loc,
"the destination vector register group cannot overlap"
3481 " the source vector register group");
3485 if (DestReg == CheckReg)
3486 return Error(Loc,
"the destination vector register group cannot overlap"
3487 " the source vector register group");
3492 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM ||
3493 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM ||
3494 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM ||
3495 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM ||
3496 Opcode == RISCV::VMERGE_VXM)
3497 return Error(Loc,
"the destination vector register group cannot be V0");
3504 assert((CheckReg == RISCV::V0 || CheckReg == RISCV::NoRegister) &&
3505 "Unexpected register for mask operand");
3507 if (DestReg == CheckReg)
3508 return Error(Loc,
"the destination vector register group cannot overlap"
3509 " the mask register");
3514bool RISCVAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
3522 case RISCV::PseudoLLAImm:
3523 case RISCV::PseudoLAImm:
3524 case RISCV::PseudoLI: {
3541 Imm = SignExtend64<32>(Imm);
3542 emitLoadImm(
Reg, Imm, Out);
3545 case RISCV::PseudoLLA:
3546 emitLoadLocalAddress(Inst, IDLoc, Out);
3548 case RISCV::PseudoLGA:
3549 emitLoadGlobalAddress(Inst, IDLoc, Out);
3551 case RISCV::PseudoLA:
3552 emitLoadAddress(Inst, IDLoc, Out);
3554 case RISCV::PseudoLA_TLS_IE:
3555 emitLoadTLSIEAddress(Inst, IDLoc, Out);
3557 case RISCV::PseudoLA_TLS_GD:
3558 emitLoadTLSGDAddress(Inst, IDLoc, Out);
3560 case RISCV::PseudoLB:
3561 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
3563 case RISCV::PseudoLBU:
3564 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
3566 case RISCV::PseudoLH:
3567 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
3569 case RISCV::PseudoLHU:
3570 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
3572 case RISCV::PseudoLW:
3573 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
3575 case RISCV::PseudoLWU:
3576 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
3578 case RISCV::PseudoLD:
3579 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
3581 case RISCV::PseudoFLH:
3582 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
3584 case RISCV::PseudoFLW:
3585 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
3587 case RISCV::PseudoFLD:
3588 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
3590 case RISCV::PseudoSB:
3591 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
3593 case RISCV::PseudoSH:
3594 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
3596 case RISCV::PseudoSW:
3597 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
3599 case RISCV::PseudoSD:
3600 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
3602 case RISCV::PseudoFSH:
3603 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
3605 case RISCV::PseudoFSW:
3606 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
3608 case RISCV::PseudoFSD:
3609 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
3611 case RISCV::PseudoAddTPRel:
3612 if (checkPseudoAddTPRel(Inst,
Operands))
3615 case RISCV::PseudoTLSDESCCall:
3616 if (checkPseudoTLSDESCCall(Inst,
Operands))
3619 case RISCV::PseudoSEXT_B:
3620 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
3622 case RISCV::PseudoSEXT_H:
3623 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
3625 case RISCV::PseudoZEXT_H:
3626 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
3628 case RISCV::PseudoZEXT_W:
3629 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
3631 case RISCV::PseudoVMSGEU_VX:
3632 case RISCV::PseudoVMSGEU_VX_M:
3633 case RISCV::PseudoVMSGEU_VX_M_T:
3634 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
3636 case RISCV::PseudoVMSGE_VX:
3637 case RISCV::PseudoVMSGE_VX_M:
3638 case RISCV::PseudoVMSGE_VX_M_T:
3639 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
3641 case RISCV::PseudoVMSGE_VI:
3642 case RISCV::PseudoVMSLT_VI: {
3646 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
3656 case RISCV::PseudoVMSGEU_VI:
3657 case RISCV::PseudoVMSLTU_VI: {
3664 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3675 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3690 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.