48#define DEBUG_TYPE "riscv-asm-parser"
51 "Number of RISC-V Compressed instructions emitted");
63struct ParserOptionsSet {
75 VTypeState_TailPolicy,
76 VTypeState_MaskPolicy,
83 ParserOptionsSet ParserOptions;
91 "do not have a target streamer");
97 unsigned Kind)
override;
103 bool generateImmOutOfRangeError(
SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
109 bool MatchingInlineAsm)
override;
113 SMLoc &EndLoc)
override;
120 bool parseVTypeToken(
StringRef Identifier, VTypeState &State,
unsigned &Sew,
123 bool generateVTypeError(
SMLoc ErrorLoc);
157 void emitLoadStoreSymbol(
MCInst &Inst,
unsigned Opcode,
SMLoc IDLoc,
161 void emitPseudoExtend(
MCInst &Inst,
bool SignExtend, int64_t Width,
184#define GET_ASSEMBLER_HEADER
185#include "RISCVGenAsmMatcher.inc"
211 bool parseDirectiveOption();
212 bool parseDirectiveAttribute();
213 bool parseDirectiveInsn(
SMLoc L);
214 bool parseDirectiveVariantCC();
220 bool FromOptionDirective);
223 if (!(
getSTI().hasFeature(Feature))) {
231 if (
getSTI().hasFeature(Feature)) {
238 void pushFeatureBits() {
240 "These two stacks must be kept synchronized");
242 ParserOptionsStack.
push_back(ParserOptions);
245 bool popFeatureBits() {
247 "These two stacks must be kept synchronized");
248 if (FeatureBitStack.
empty())
260 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
261 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
262 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
265 enum RISCVMatchResultTy {
267 Match_RequiresEvenGPRs,
268#define GET_OPERAND_DIAGNOSTIC_TYPES
269#include "RISCVGenAsmMatcher.inc"
270#undef GET_OPERAND_DIAGNOSTIC_TYPES
273 static bool classifySymbolRef(
const MCExpr *Expr,
275 static bool isSymbolDiff(
const MCExpr *Expr);
289 if (ABIName.endswith(
"f") && !getSTI().hasFeature(RISCV::FeatureStdExtF)) {
290 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
291 "doesn't support the F instruction set extension (ignoring "
293 }
else if (ABIName.endswith(
"d") &&
294 !getSTI().hasFeature(RISCV::FeatureStdExtD)) {
295 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
296 "doesn't support the D instruction set extension (ignoring "
309 getTargetStreamer().emitTargetAttributes(STI,
false);
372 SMLoc StartLoc, EndLoc;
378 struct SysRegOp SysReg;
379 struct VTypeOp VType;
381 struct FenceOp Fence;
382 struct RlistOp Rlist;
383 struct SpimmOp Spimm;
386 RISCVOperand(KindTy K) :
Kind(
K) {}
391 StartLoc =
o.StartLoc;
394 case KindTy::Register:
397 case KindTy::Immediate:
400 case KindTy::FPImmediate:
406 case KindTy::SystemRegister:
427 bool isToken()
const override {
return Kind == KindTy::Token; }
428 bool isReg()
const override {
return Kind == KindTy::Register; }
429 bool isV0Reg()
const {
430 return Kind == KindTy::Register &&
Reg.RegNum == RISCV::V0;
432 bool isAnyReg()
const {
433 return Kind == KindTy::Register &&
434 (RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.RegNum) ||
435 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg.RegNum) ||
436 RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg.RegNum));
438 bool isAnyRegC()
const {
439 return Kind == KindTy::Register &&
440 (RISCVMCRegisterClasses[RISCV::GPRCRegClassID].contains(
442 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
445 bool isImm()
const override {
return Kind == KindTy::Immediate; }
446 bool isMem()
const override {
return false; }
447 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
448 bool isRlist()
const {
return Kind == KindTy::Rlist; }
449 bool isSpimm()
const {
return Kind == KindTy::Spimm; }
452 return Kind == KindTy::Register &&
453 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.RegNum);
456 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
458 bool isGPRF64AsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
460 bool isGPRPF64AsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
462 static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &Imm,
464 if (
auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
466 return RE->evaluateAsConstant(Imm);
469 if (
auto CE = dyn_cast<MCConstantExpr>(Expr)) {
471 Imm =
CE->getValue();
480 template <
int N>
bool isBareSimmNLsb0()
const {
485 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
488 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
496 bool isBareSymbol()
const {
500 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
502 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
506 bool isCallSymbol()
const {
510 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
512 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
517 bool isPseudoJumpSymbol()
const {
521 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
523 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
527 bool isTPRelAddSymbol()
const {
531 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
533 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
537 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
539 bool isVTypeImm(
unsigned N)
const {
544 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
550 bool isVTypeI10()
const {
551 if (Kind == KindTy::Immediate)
552 return isVTypeImm(10);
553 return Kind == KindTy::VType;
555 bool isVTypeI11()
const {
556 if (Kind == KindTy::Immediate)
557 return isVTypeImm(11);
558 return Kind == KindTy::VType;
563 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
566 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
567 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
571 bool isLoadFPImm()
const {
574 if (Kind != KindTy::FPImmediate)
577 APFloat(APFloat::IEEEdouble(),
APInt(64, getFPConst())));
580 return Idx >= 0 &&
Idx != 1;
583 bool isImmXLenLI()
const {
588 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
595 (isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm)));
598 return RISCVAsmParser::isSymbolDiff(getImm());
601 bool isImmXLenLI_Restricted()
const {
606 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
609 (isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm)));
612 bool isUImmLog2XLen()
const {
617 if (!evaluateConstantImm(getImm(), Imm, VK) ||
620 return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm);
623 bool isUImmLog2XLenNonZero()
const {
628 if (!evaluateConstantImm(getImm(), Imm, VK) ||
633 return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm);
636 bool isUImmLog2XLenHalf()
const {
641 if (!evaluateConstantImm(getImm(), Imm, VK) ||
644 return (isRV64Imm() && isUInt<5>(Imm)) || isUInt<4>(Imm);
647 template <
unsigned N>
bool IsUImm()
const {
652 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
656 bool isUImm1()
const {
return IsUImm<1>(); }
657 bool isUImm2()
const {
return IsUImm<2>(); }
658 bool isUImm3()
const {
return IsUImm<3>(); }
659 bool isUImm4()
const {
return IsUImm<4>(); }
660 bool isUImm5()
const {
return IsUImm<5>(); }
661 bool isUImm6()
const {
return IsUImm<6>(); }
662 bool isUImm7()
const {
return IsUImm<7>(); }
663 bool isUImm8()
const {
return IsUImm<8>(); }
664 bool isUImm20()
const {
return IsUImm<20>(); }
666 bool isUImm8GE32()
const {
671 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
672 return IsConstantImm && isUInt<8>(Imm) &&
Imm >= 32 &&
676 bool isRnumArg()
const {
681 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
682 return IsConstantImm &&
Imm >= INT64_C(0) &&
Imm <= INT64_C(10) &&
686 bool isRnumArg_0_7()
const {
691 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
692 return IsConstantImm &&
Imm >= INT64_C(0) &&
Imm <= INT64_C(7) &&
696 bool isRnumArg_1_10()
const {
701 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
702 return IsConstantImm &&
Imm >= INT64_C(1) &&
Imm <= INT64_C(10) &&
706 bool isRnumArg_2_14()
const {
711 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
712 return IsConstantImm &&
Imm >= INT64_C(2) &&
Imm <= INT64_C(14) &&
716 bool isSImm5()
const {
721 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
722 return IsConstantImm && isInt<5>(fixImmediateForRV32(Imm, isRV64Imm())) &&
726 bool isSImm6()
const {
731 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
732 return IsConstantImm && isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) &&
736 bool isSImm6NonZero()
const {
741 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
742 return IsConstantImm &&
Imm != 0 &&
743 isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) &&
747 bool isCLUIImm()
const {
752 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
753 return IsConstantImm && (
Imm != 0) &&
754 (isUInt<5>(Imm) || (
Imm >= 0xfffe0 &&
Imm <= 0xfffff)) &&
758 bool isUImm2Lsb0()
const {
763 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
764 return IsConstantImm && isShiftedUInt<1, 1>(Imm) &&
768 bool isUImm7Lsb00()
const {
773 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
774 return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
778 bool isUImm8Lsb00()
const {
783 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
784 return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
788 bool isUImm8Lsb000()
const {
793 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
794 return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
798 bool isSImm9Lsb0()
const {
return isBareSimmNLsb0<9>(); }
800 bool isUImm9Lsb000()
const {
805 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
806 return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
810 bool isUImm10Lsb00NonZero()
const {
815 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
816 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (
Imm != 0) &&
822 static int64_t fixImmediateForRV32(int64_t Imm,
bool IsRV64Imm) {
823 if (IsRV64Imm || !isUInt<32>(Imm))
825 return SignExtend64<32>(Imm);
828 bool isSImm12()
const {
834 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
836 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
838 IsValid = isInt<12>(fixImmediateForRV32(Imm, isRV64Imm()));
845 bool isSImm12Lsb0()
const {
return isBareSimmNLsb0<12>(); }
847 bool isSImm12Lsb00000()
const {
852 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
853 return IsConstantImm && isShiftedInt<7, 5>(Imm) &&
857 bool isSImm13Lsb0()
const {
return isBareSimmNLsb0<13>(); }
859 bool isSImm10Lsb0000NonZero()
const {
864 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
865 return IsConstantImm && (
Imm != 0) && isShiftedInt<6, 4>(Imm) &&
869 bool isUImm20LUI()
const {
875 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
876 if (!IsConstantImm) {
877 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
887 bool isUImm20AUIPC()
const {
893 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
894 if (!IsConstantImm) {
895 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
909 bool isSImm21Lsb0JAL()
const {
return isBareSimmNLsb0<21>(); }
911 bool isImmZero()
const {
916 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
920 bool isSImm5Plus1()
const {
925 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
926 return IsConstantImm &&
927 isInt<5>(fixImmediateForRV32(Imm, isRV64Imm()) - 1) &&
932 SMLoc getStartLoc()
const override {
return StartLoc; }
934 SMLoc getEndLoc()
const override {
return EndLoc; }
936 bool isRV64Imm()
const {
937 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
941 unsigned getReg()
const override {
942 assert(Kind == KindTy::Register &&
"Invalid type access!");
943 return Reg.RegNum.id();
947 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
948 return StringRef(SysReg.Data, SysReg.Length);
951 const MCExpr *getImm()
const {
952 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
957 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
962 assert(Kind == KindTy::Token &&
"Invalid type access!");
966 unsigned getVType()
const {
967 assert(Kind == KindTy::VType &&
"Invalid type access!");
972 assert(Kind == KindTy::FRM &&
"Invalid type access!");
976 unsigned getFence()
const {
977 assert(Kind == KindTy::Fence &&
"Invalid type access!");
990 case KindTy::Immediate:
993 case KindTy::FPImmediate:
995 case KindTy::Register:
999 OS <<
"'" << getToken() <<
"'";
1001 case KindTy::SystemRegister:
1002 OS <<
"<sysreg: " << getSysReg() <<
'>';
1011 roundingModeToString(getFRM());
1032 static std::unique_ptr<RISCVOperand> createToken(
StringRef Str,
SMLoc S) {
1033 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1040 static std::unique_ptr<RISCVOperand>
1041 createReg(
unsigned RegNo,
SMLoc S,
SMLoc E,
bool IsGPRAsFPR =
false) {
1042 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1043 Op->Reg.RegNum = RegNo;
1044 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1050 static std::unique_ptr<RISCVOperand> createImm(
const MCExpr *Val,
SMLoc S,
1052 auto Op = std::make_unique<RISCVOperand>(KindTy::Immediate);
1054 Op->Imm.IsRV64 = IsRV64;
1060 static std::unique_ptr<RISCVOperand> createFPImm(
uint64_t Val,
SMLoc S) {
1061 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1062 Op->FPImm.Val = Val;
1068 static std::unique_ptr<RISCVOperand> createSysReg(
StringRef Str,
SMLoc S,
1069 unsigned Encoding) {
1070 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1071 Op->SysReg.Data = Str.data();
1072 Op->SysReg.Length = Str.size();
1079 static std::unique_ptr<RISCVOperand>
1081 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1088 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val,
SMLoc S) {
1089 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1090 Op->Fence.Val = Val;
1096 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI,
SMLoc S) {
1097 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1098 Op->VType.Val = VTypeI;
1104 static std::unique_ptr<RISCVOperand> createRlist(
unsigned RlistEncode,
1106 auto Op = std::make_unique<RISCVOperand>(KindTy::Rlist);
1107 Op->Rlist.Val = RlistEncode;
1112 static std::unique_ptr<RISCVOperand> createSpimm(
unsigned Spimm,
SMLoc S) {
1113 auto Op = std::make_unique<RISCVOperand>(KindTy::Spimm);
1114 Op->Spimm.Val = Spimm;
1119 static void addExpr(
MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1120 assert(Expr &&
"Expr shouldn't be null!");
1123 bool IsConstant = evaluateConstantImm(Expr, Imm, VK);
1133 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1134 assert(
N == 1 &&
"Invalid number of operands!");
1138 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1139 assert(
N == 1 &&
"Invalid number of operands!");
1140 addExpr(Inst, getImm(), isRV64Imm());
1143 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
1144 assert(
N == 1 &&
"Invalid number of operands!");
1146 addExpr(Inst, getImm(), isRV64Imm());
1151 APFloat(APFloat::IEEEdouble(),
APInt(64, getFPConst())));
1155 void addFenceArgOperands(
MCInst &Inst,
unsigned N)
const {
1156 assert(
N == 1 &&
"Invalid number of operands!");
1160 void addCSRSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
1161 assert(
N == 1 &&
"Invalid number of operands!");
1168 void addVTypeIOperands(
MCInst &Inst,
unsigned N)
const {
1169 assert(
N == 1 &&
"Invalid number of operands!");
1171 if (Kind == KindTy::Immediate) {
1173 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
1174 (void)IsConstantImm;
1175 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1182 void addRlistOperands(
MCInst &Inst,
unsigned N)
const {
1183 assert(
N == 1 &&
"Invalid number of operands!");
1187 void addSpimmOperands(
MCInst &Inst,
unsigned N)
const {
1188 assert(
N == 1 &&
"Invalid number of operands!");
1192 void addFRMArgOperands(
MCInst &Inst,
unsigned N)
const {
1193 assert(
N == 1 &&
"Invalid number of operands!");
1199#define GET_REGISTER_MATCHER
1200#define GET_SUBTARGET_FEATURE_NAME
1201#define GET_MATCHER_IMPLEMENTATION
1202#define GET_MNEMONIC_SPELL_CHECKER
1203#include "RISCVGenAsmMatcher.inc"
1206 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1207 return Reg - RISCV::F0_D + RISCV::F0_H;
1211 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1212 return Reg - RISCV::F0_D + RISCV::F0_F;
1217 unsigned RegClassID;
1218 if (Kind == MCK_VRM2)
1219 RegClassID = RISCV::VRM2RegClassID;
1220 else if (Kind == MCK_VRM4)
1221 RegClassID = RISCV::VRM4RegClassID;
1222 else if (Kind == MCK_VRM8)
1223 RegClassID = RISCV::VRM8RegClassID;
1227 &RISCVMCRegisterClasses[RegClassID]);
1232 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1234 return Match_InvalidOperand;
1238 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg);
1240 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg);
1241 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg);
1245 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1246 (IsRegFPR64C &&
Kind == MCK_FPR32C)) {
1248 return Match_Success;
1252 if (IsRegFPR64 && Kind == MCK_FPR16) {
1254 return Match_Success;
1258 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1260 if (
Op.Reg.RegNum == 0)
1261 return Match_InvalidOperand;
1262 return Match_Success;
1264 return Match_InvalidOperand;
1267unsigned RISCVAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
1271 if (MCID.
operands()[
I].RegClass == RISCV::GPRPF64RegClassID) {
1276 if (((
Reg.id() - RISCV::X0) & 1) != 0)
1277 return Match_RequiresEvenGPRs;
1281 return Match_Success;
1284bool RISCVAsmParser::generateImmOutOfRangeError(
1286 const Twine &Msg =
"immediate must be an integer in the range") {
1290bool RISCVAsmParser::generateImmOutOfRangeError(
1292 const Twine &Msg =
"immediate must be an integer in the range") {
1294 return generateImmOutOfRangeError(ErrorLoc,
Lower,
Upper, Msg);
1297bool RISCVAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1301 bool MatchingInlineAsm) {
1311 if (validateInstruction(Inst,
Operands))
1313 return processInstruction(Inst, IDLoc,
Operands, Out);
1314 case Match_MissingFeature: {
1315 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1316 bool FirstFeature =
true;
1317 std::string
Msg =
"instruction requires the following:";
1318 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1319 if (MissingFeatures[i]) {
1320 Msg += FirstFeature ?
" " :
", ";
1322 FirstFeature =
false;
1325 return Error(IDLoc, Msg);
1327 case Match_MnemonicFail: {
1328 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1329 std::string Suggestion = RISCVMnemonicSpellCheck(
1330 ((RISCVOperand &)*
Operands[0]).getToken(), FBS, 0);
1331 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1333 case Match_InvalidOperand: {
1334 SMLoc ErrorLoc = IDLoc;
1337 return Error(ErrorLoc,
"too few operands for instruction");
1340 if (ErrorLoc ==
SMLoc())
1343 return Error(ErrorLoc,
"invalid operand for instruction");
1350 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1351 SMLoc ErrorLoc = IDLoc;
1353 return Error(ErrorLoc,
"too few operands for instruction");
1359 case Match_RequiresEvenGPRs:
1361 "double precision floating point operands must use even "
1362 "numbered X register");
1363 case Match_InvalidImmXLenLI:
1366 return Error(ErrorLoc,
"operand must be a constant 64-bit integer");
1369 std::numeric_limits<int32_t>::min(),
1370 std::numeric_limits<uint32_t>::max());
1371 case Match_InvalidImmXLenLI_Restricted:
1374 return Error(ErrorLoc,
"operand either must be a constant 64-bit integer "
1375 "or a bare symbol name");
1377 return generateImmOutOfRangeError(
1379 std::numeric_limits<uint32_t>::max(),
1380 "operand either must be a bare symbol name or an immediate integer in "
1382 case Match_InvalidImmZero: {
1384 return Error(ErrorLoc,
"immediate must be zero");
1386 case Match_InvalidUImmLog2XLen:
1390 case Match_InvalidUImmLog2XLenNonZero:
1394 case Match_InvalidUImmLog2XLenHalf:
1398 case Match_InvalidUImm1:
1400 case Match_InvalidUImm2:
1402 case Match_InvalidUImm2Lsb0:
1404 "immediate must be one of");
1405 case Match_InvalidUImm3:
1407 case Match_InvalidUImm4:
1409 case Match_InvalidUImm5:
1411 case Match_InvalidUImm6:
1413 case Match_InvalidUImm7:
1415 case Match_InvalidUImm8:
1417 case Match_InvalidUImm8GE32:
1419 case Match_InvalidSImm5:
1422 case Match_InvalidSImm6:
1425 case Match_InvalidSImm6NonZero:
1426 return generateImmOutOfRangeError(
1428 "immediate must be non-zero in the range");
1429 case Match_InvalidCLUIImm:
1430 return generateImmOutOfRangeError(
1432 "immediate must be in [0xfffe0, 0xfffff] or");
1433 case Match_InvalidUImm7Lsb00:
1434 return generateImmOutOfRangeError(
1436 "immediate must be a multiple of 4 bytes in the range");
1437 case Match_InvalidUImm8Lsb00:
1438 return generateImmOutOfRangeError(
1440 "immediate must be a multiple of 4 bytes in the range");
1441 case Match_InvalidUImm8Lsb000:
1442 return generateImmOutOfRangeError(
1444 "immediate must be a multiple of 8 bytes in the range");
1445 case Match_InvalidSImm9Lsb0:
1446 return generateImmOutOfRangeError(
1448 "immediate must be a multiple of 2 bytes in the range");
1449 case Match_InvalidUImm9Lsb000:
1450 return generateImmOutOfRangeError(
1452 "immediate must be a multiple of 8 bytes in the range");
1453 case Match_InvalidUImm10Lsb00NonZero:
1454 return generateImmOutOfRangeError(
1456 "immediate must be a multiple of 4 bytes in the range");
1457 case Match_InvalidSImm10Lsb0000NonZero:
1458 return generateImmOutOfRangeError(
1460 "immediate must be a multiple of 16 bytes and non-zero in the range");
1461 case Match_InvalidSImm12:
1462 return generateImmOutOfRangeError(
1464 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an "
1465 "integer in the range");
1466 case Match_InvalidSImm12Lsb0:
1467 return generateImmOutOfRangeError(
1469 "immediate must be a multiple of 2 bytes in the range");
1470 case Match_InvalidSImm12Lsb00000:
1471 return generateImmOutOfRangeError(
1473 "immediate must be a multiple of 32 bytes in the range");
1474 case Match_InvalidSImm13Lsb0:
1475 return generateImmOutOfRangeError(
1477 "immediate must be a multiple of 2 bytes in the range");
1478 case Match_InvalidUImm20LUI:
1480 "operand must be a symbol with "
1481 "%hi/%tprel_hi modifier or an integer in "
1483 case Match_InvalidUImm20:
1485 case Match_InvalidUImm20AUIPC:
1486 return generateImmOutOfRangeError(
1488 "operand must be a symbol with a "
1489 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
1490 "an integer in the range");
1491 case Match_InvalidSImm21Lsb0JAL:
1492 return generateImmOutOfRangeError(
1494 "immediate must be a multiple of 2 bytes in the range");
1495 case Match_InvalidCSRSystemRegister: {
1497 "operand must be a valid system register "
1498 "name or an integer in the range");
1500 case Match_InvalidLoadFPImm: {
1502 return Error(ErrorLoc,
"operand must be a valid floating-point constant");
1504 case Match_InvalidBareSymbol: {
1506 return Error(ErrorLoc,
"operand must be a bare symbol name");
1508 case Match_InvalidPseudoJumpSymbol: {
1510 return Error(ErrorLoc,
"operand must be a valid jump target");
1512 case Match_InvalidCallSymbol: {
1514 return Error(ErrorLoc,
"operand must be a bare symbol name");
1516 case Match_InvalidTPRelAddSymbol: {
1518 return Error(ErrorLoc,
"operand must be a symbol with %tprel_add modifier");
1520 case Match_InvalidRTZArg: {
1522 return Error(ErrorLoc,
"operand must be 'rtz' floating-point rounding mode");
1524 case Match_InvalidVTypeI: {
1526 return generateVTypeError(ErrorLoc);
1528 case Match_InvalidVMaskRegister: {
1530 return Error(ErrorLoc,
"operand must be v0.t");
1532 case Match_InvalidSImm5Plus1: {
1535 "immediate must be in the range");
1537 case Match_InvalidRlist: {
1541 "operand must be {ra [, s0[-sN]]} or {x1 [, x8[-x9][, x18[-xN]]]}");
1543 case Match_InvalidSpimm: {
1547 "stack adjustment is invalid for this instruction and register list; "
1548 "refer to Zc spec for a detailed range of stack adjustment");
1550 case Match_InvalidRnumArg: {
1569 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1570 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1573 if (IsRVE &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1574 Reg = RISCV::NoRegister;
1580 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1581 return Error(StartLoc,
"invalid register name");
1587 const AsmToken &Tok = getParser().getTok();
1602 SMLoc FirstS = getLoc();
1603 bool HadParens =
false;
1610 size_t ReadCount = getLexer().peekTokens(Buf);
1613 LParen = getParser().getTok();
1618 switch (getLexer().getKind()) {
1621 getLexer().UnLex(LParen);
1629 getLexer().UnLex(LParen);
1633 Operands.push_back(RISCVOperand::createToken(
"(", FirstS));
1637 Operands.push_back(RISCVOperand::createReg(RegNo, S,
E));
1642 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
1653 switch (getLexer().getKind()) {
1663 if (getParser().parseExpression(Res,
E))
1666 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1668 int64_t
Imm =
CE->getValue();
1669 if (isUInt<7>(Imm)) {
1670 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1679 if (getParser().parseIdentifier(Identifier))
1682 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1684 assert(isUInt<7>(Opcode->Value) && (Opcode->Value & 0x3) == 3 &&
1685 "Unexpected opcode");
1688 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1698 return generateImmOutOfRangeError(
1700 "opcode must be a valid opcode name or an immediate in the range");
1708 switch (getLexer().getKind()) {
1718 if (getParser().parseExpression(Res,
E))
1721 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1723 int64_t
Imm =
CE->getValue();
1724 if (Imm >= 0 && Imm <= 2) {
1725 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1734 if (getParser().parseIdentifier(Identifier))
1738 if (Identifier ==
"C0")
1740 else if (Identifier ==
"C1")
1742 else if (Identifier ==
"C2")
1749 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1758 return generateImmOutOfRangeError(
1760 "opcode must be a valid opcode name or an immediate in the range");
1767 switch (getLexer().getKind()) {
1777 if (getParser().parseExpression(Res))
1780 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1782 int64_t
Imm =
CE->getValue();
1783 if (isUInt<12>(Imm)) {
1784 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm);
1788 RISCVOperand::createSysReg(SysReg ? SysReg->Name :
"", S, Imm));
1793 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1797 if (getParser().parseIdentifier(Identifier))
1803 auto CheckCSRNameConflict = [&]() {
1804 if (!(RISCVSysReg::lookupSysRegByName(Identifier))) {
1805 Error(S,
"system register use requires an option to be enabled");
1812 auto SiFiveReg = RISCVSysReg::lookupSiFiveRegByName(Identifier);
1814 if (SiFiveReg->haveVendorRequiredFeatures(getSTI().getFeatureBits())) {
1816 RISCVOperand::createSysReg(Identifier, S, SiFiveReg->Encoding));
1819 if (CheckCSRNameConflict())
1823 auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1825 if ((SysReg = RISCVSysReg::lookupSysRegByDeprecatedName(Identifier)))
1826 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
1827 SysReg->Name +
"'");
1832 auto CheckCSREncodingConflict = [&]() {
1833 auto Reg = RISCVSysReg::lookupSiFiveRegByEncoding(SysReg->Encoding);
1834 if (
Reg &&
Reg->haveVendorRequiredFeatures(getSTI().getFeatureBits())) {
1835 Warning(S,
"'" + Identifier +
"' CSR is not available on the current " +
1836 "subtarget. Instead '" +
Reg->Name +
1837 "' CSR will be used.");
1839 RISCVOperand::createSysReg(
Reg->Name, S,
Reg->Encoding));
1847 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits()))
1848 return Error(S,
"system register use requires an option to be enabled");
1849 if (CheckCSREncodingConflict())
1852 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
1856 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
1857 "operand must be a valid system register "
1858 "name or an integer in the range");
1862 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1875 if (
Identifier.compare_insensitive(
"inf") == 0) {
1878 getTok().getEndLoc(), isRV64()));
1879 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
1882 getTok().getEndLoc(), isRV64()));
1883 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
1886 getTok().getEndLoc(), isRV64()));
1888 return TokError(
"invalid floating point literal");
1901 return TokError(
"invalid floating point immediate");
1904 APFloat RealVal(APFloat::IEEEdouble());
1906 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
1908 return TokError(
"invalid floating point representation");
1911 RealVal.changeSign();
1913 Operands.push_back(RISCVOperand::createFPImm(
1914 RealVal.bitcastToAPInt().getZExtValue(), S));
1926 switch (getLexer().getKind()) {
1938 if (getParser().parseExpression(Res,
E))
1942 return parseOperandWithModifier(
Operands);
1945 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1957 return Error(getLoc(),
"expected valid identifier for operand modifier");
1961 return Error(getLoc(),
"unrecognized operand modifier");
1968 if (getParser().parseParenExpression(SubExpr,
E))
1972 Operands.push_back(RISCVOperand::createImm(ModExpr, S,
E, isRV64()));
1984 AsmToken Tok = getLexer().getTok();
1986 if (getParser().parseIdentifier(Identifier))
1992 return Error(getLoc(),
"'@plt' operand not valid for instruction");
1994 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
1996 if (
Sym->isVariable()) {
1997 const MCExpr *
V =
Sym->getVariableValue(
false);
1998 if (!isa<MCSymbolRefExpr>(V)) {
1999 getLexer().UnLex(Tok);
2007 switch (getLexer().getKind()) {
2009 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2022 if (getParser().parseExpression(Expr,
E))
2025 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2041 if (getParser().parseIdentifier(Identifier))
2050 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
2053 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2062 if (getParser().parseExpression(Res,
E))
2065 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef ||
2066 cast<MCSymbolRefExpr>(Res)->getKind() ==
2067 MCSymbolRefExpr::VariantKind::VK_PLT)
2068 return Error(S,
"operand must be a valid jump target");
2071 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2092bool RISCVAsmParser::parseVTypeToken(
StringRef Identifier, VTypeState &State,
2093 unsigned &Sew,
unsigned &Lmul,
2097 case VTypeState_SEW:
2104 State = VTypeState_LMUL;
2106 case VTypeState_LMUL: {
2114 State = VTypeState_TailPolicy;
2117 case VTypeState_TailPolicy:
2118 if (Identifier ==
"ta")
2120 else if (Identifier ==
"tu")
2124 State = VTypeState_MaskPolicy;
2126 case VTypeState_MaskPolicy:
2127 if (Identifier ==
"ma")
2129 else if (Identifier ==
"mu")
2133 State = VTypeState_Done;
2135 case VTypeState_Done:
2148 bool Fractional =
false;
2152 VTypeState State = VTypeState_SEW;
2159 if (parseVTypeToken(Identifier, State, Sew, Lmul, Fractional,
TailAgnostic,
2171 if (parseVTypeToken(Identifier, State, Sew, Lmul, Fractional,
TailAgnostic,
2183 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2187 return generateVTypeError(S);
2190bool RISCVAsmParser::generateVTypeError(
SMLoc ErrorLoc) {
2194 "e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2202 if (!
Name.consume_back(
".t"))
2203 return Error(getLoc(),
"expected '.t' suffix");
2208 if (RegNo != RISCV::V0)
2213 Operands.push_back(RISCVOperand::createReg(RegNo, S,
E));
2229 Operands.push_back(RISCVOperand::createReg(
2230 RegNo, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2237 "operand must be a valid floating point rounding mode mnemonic");
2239 StringRef Str = getLexer().getTok().getIdentifier();
2244 "operand must be a valid floating point rounding mode mnemonic");
2246 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2252 const AsmToken &Tok = getLexer().getTok();
2258 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2272 for (
char c : Str) {
2301 Operands.push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2307 return TokError(
"operand must be formed of letters selected in-order from "
2314 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
2316 if (!parseRegister(
Operands).isSuccess())
2317 return Error(getLoc(),
"expected register");
2321 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2345 std::unique_ptr<RISCVOperand> OptionalImmOp;
2352 SMLoc ImmStart = getLoc();
2353 if (getParser().parseIntToken(ImmVal,
2354 "expected '(' or optional integer offset"))
2359 SMLoc ImmEnd = getLoc();
2362 ImmStart, ImmEnd, isRV64());
2366 OptionalImmOp ?
"expected '(' after optional integer offset"
2367 :
"expected '(' or optional integer offset"))
2370 if (!parseRegister(
Operands).isSuccess())
2371 return Error(getLoc(),
"expected register");
2377 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2379 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2380 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2393 bool IsEABI = isRVE();
2396 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2401 if (RegStart != RISCV::X1)
2402 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2408 return Error(getLoc(),
"invalid register");
2412 return Error(getLoc(),
"invalid register");
2413 if (RegStart != RISCV::X8)
2414 return Error(getLoc(),
2415 "continuous register list must start from 's0' or 'x8'");
2421 StringRef EndName = getLexer().getTok().getIdentifier();
2425 return Error(getLoc(),
"invalid register");
2426 if (IsEABI && RegEnd != RISCV::X9)
2427 return Error(getLoc(),
"contiguous register list of EABI can only be "
2428 "'s0-s1' or 'x8-x9' pair");
2435 if (RegEnd != RISCV::X9)
2438 "first contiguous registers pair of register list must be 'x8-x9'");
2442 return Error(getLoc(),
"invalid register");
2443 StringRef EndName = getLexer().getTok().getIdentifier();
2445 return Error(getLoc(),
2446 "second contiguous registers pair of register list "
2447 "must start from 'x18'");
2453 return Error(getLoc(),
"invalid register");
2454 EndName = getLexer().getTok().getIdentifier();
2456 return Error(getLoc(),
"invalid register");
2463 if (RegEnd == RISCV::X26)
2464 return Error(getLoc(),
"invalid register list, {ra, s0-s10} or {x1, x8-x9, "
2465 "x18-x26} is not supported");
2470 if (RegEnd == RISCV::NoRegister)
2475 return Error(S,
"invalid register list");
2476 Operands.push_back(RISCVOperand::createRlist(Encode, S));
2487 unsigned RlistVal =
static_cast<RISCVOperand *
>(
Operands[1].get())->Rlist.Val;
2489 bool IsEABI = isRVE();
2492 Operands.push_back(RISCVOperand::createSpimm(Spimm << 4, S));
2504 MatchOperandParserImpl(
Operands, Mnemonic,
true);
2511 if (parseRegister(
Operands,
true).isSuccess())
2518 return !parseMemOpBaseReg(
Operands).isSuccess();
2523 Error(getLoc(),
"unknown operand");
2536 if (getSTI().hasFeature(RISCV::FeatureRelax)) {
2537 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
2538 if (Assembler !=
nullptr) {
2546 Operands.push_back(RISCVOperand::createToken(
Name, NameLoc));
2565 if (getParser().parseEOL(
"unexpected token")) {
2566 getParser().eatToEndOfStatement();
2572bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
2576 if (
const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
2577 Kind = RE->getKind();
2578 Expr = RE->getSubExpr();
2588bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
2601 if (IDVal ==
".option")
2602 return parseDirectiveOption();
2603 if (IDVal ==
".attribute")
2604 return parseDirectiveAttribute();
2605 if (IDVal ==
".insn")
2606 return parseDirectiveInsn(DirectiveID.
getLoc());
2607 if (IDVal ==
".variant_cc")
2608 return parseDirectiveVariantCC();
2613bool RISCVAsmParser::resetToArch(
StringRef Arch,
SMLoc Loc, std::string &Result,
2614 bool FromOptionDirective) {
2617 clearFeatureBits(Feature.Value, Feature.Key);
2626 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
2627 << ErrMsg.getMessage();
2630 return Error(Loc, OutputErrMsg.str());
2632 auto &ISAInfo = *ParseResult;
2635 if (ISAInfo->hasExtension(Feature.Key))
2636 setFeatureBits(Feature.Value, Feature.Key);
2638 if (FromOptionDirective) {
2639 if (ISAInfo->getXLen() == 32 && isRV64())
2640 return Error(Loc,
"bad arch string switching from rv64 to rv32");
2641 else if (ISAInfo->getXLen() == 64 && !isRV64())
2642 return Error(Loc,
"bad arch string switching from rv32 to rv64");
2645 if (ISAInfo->getXLen() == 32)
2646 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
2647 else if (ISAInfo->getXLen() == 64)
2648 setFeatureBits(RISCV::Feature64Bit,
"64bit");
2650 return Error(Loc,
"bad arch string " + Arch);
2652 Result = ISAInfo->toString();
2656bool RISCVAsmParser::parseDirectiveOption() {
2667 if (Option ==
"push") {
2671 getTargetStreamer().emitDirectiveOptionPush();
2676 if (Option ==
"pop") {
2681 getTargetStreamer().emitDirectiveOptionPop();
2682 if (popFeatureBits())
2683 return Error(StartLoc,
".option pop with no .option push");
2688 if (Option ==
"arch") {
2696 Type = RISCVOptionArchArgType::Plus;
2698 Type = RISCVOptionArchArgType::Minus;
2699 else if (!
Args.empty())
2701 "unexpected token, expected + or -");
2703 Type = RISCVOptionArchArgType::Full;
2707 "unexpected token, expected identifier");
2713 if (
Type == RISCVOptionArchArgType::Full) {
2715 if (resetToArch(Arch, Loc, Result,
true))
2724 if (Ext == KVArray.end() ||
StringRef(
Ext->Key) != Arch ||
2729 "Extension version number parsing not currently implemented");
2730 return Error(Loc,
"unknown extension feature");
2735 if (
Type == RISCVOptionArchArgType::Plus) {
2738 setFeatureBits(
Ext->Value,
Ext->Key);
2741 copySTI().setFeatureBits(OldFeatureBits);
2742 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
2747 OutputErrMsg << ErrMsg.getMessage();
2750 return Error(Loc, OutputErrMsg.str());
2753 assert(
Type == RISCVOptionArchArgType::Minus);
2757 for (
auto Feature : KVArray) {
2758 if (getSTI().hasFeature(Feature.Value) &&
2759 Feature.Implies.test(
Ext->Value))
2761 Twine(
"Can't disable ") +
Ext->Key +
" extension, " +
2762 Feature.Key +
" extension requires " +
Ext->Key +
2763 " extension be enabled");
2766 clearFeatureBits(
Ext->Value,
Ext->Key);
2773 getTargetStreamer().emitDirectiveOptionArch(Args);
2777 if (Option ==
"rvc") {
2781 getTargetStreamer().emitDirectiveOptionRVC();
2782 setFeatureBits(RISCV::FeatureStdExtC,
"c");
2786 if (Option ==
"norvc") {
2790 getTargetStreamer().emitDirectiveOptionNoRVC();
2791 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
2792 clearFeatureBits(RISCV::FeatureStdExtZca,
"+zca");
2796 if (Option ==
"pic") {
2800 getTargetStreamer().emitDirectiveOptionPIC();
2801 ParserOptions.IsPicEnabled =
true;
2805 if (Option ==
"nopic") {
2809 getTargetStreamer().emitDirectiveOptionNoPIC();
2810 ParserOptions.IsPicEnabled =
false;
2814 if (Option ==
"relax") {
2818 getTargetStreamer().emitDirectiveOptionRelax();
2819 setFeatureBits(RISCV::FeatureRelax,
"relax");
2823 if (Option ==
"norelax") {
2827 getTargetStreamer().emitDirectiveOptionNoRelax();
2828 clearFeatureBits(RISCV::FeatureRelax,
"relax");
2834 "'rvc', 'norvc', 'arch', 'relax' or "
2843bool RISCVAsmParser::parseDirectiveAttribute() {
2850 std::optional<unsigned>
Ret =
2853 return Error(TagLoc,
"attribute name not recognised: " +
Name);
2864 if (
check(!CE, TagLoc,
"expected numeric constant"))
2867 Tag =
CE->getValue();
2874 int64_t IntegerValue = 0;
2875 bool IsIntegerValue =
true;
2880 IsIntegerValue =
false;
2883 if (IsIntegerValue) {
2890 return Error(ValueExprLoc,
"expected numeric constant");
2891 IntegerValue =
CE->getValue();
2904 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
2906 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
2909 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
2913 getTargetStreamer().emitTextAttribute(
Tag, Result);
2921 .
Cases(
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s",
true)
2922 .
Cases(
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj", AllowC)
2928bool RISCVAsmParser::parseDirectiveInsn(
SMLoc L) {
2935 return Error(ErrorLoc,
"expected instruction format");
2937 bool AllowC = getSTI().hasFeature(RISCV::FeatureStdExtC) ||
2938 getSTI().hasFeature(RISCV::FeatureStdExtZca);
2940 return Error(ErrorLoc,
"invalid instruction format");
2942 std::string FormatName = (
".insn_" +
Format).str();
2959bool RISCVAsmParser::parseDirectiveVariantCC() {
2961 if (getParser().parseIdentifier(
Name))
2962 return TokError(
"expected symbol name");
2965 getTargetStreamer().emitDirectiveVariantCC(
2966 *getContext().getOrCreateSymbol(
Name));
2974 ++RISCVNumInstrsCompressed;
2985 switch (Inst.getOpndKind()) {
3015 unsigned SecondOpcode,
SMLoc IDLoc,
3029 const MCExpr *RefToLinkTmpLabel =
3036 .addExpr(RefToLinkTmpLabel));
3039void RISCVAsmParser::emitLoadLocalAddress(
MCInst &Inst,
SMLoc IDLoc,
3050 RISCV::ADDI, IDLoc, Out);
3053void RISCVAsmParser::emitLoadGlobalAddress(
MCInst &Inst,
SMLoc IDLoc,
3063 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3065 SecondOpcode, IDLoc, Out);
3068void RISCVAsmParser::emitLoadAddress(
MCInst &Inst,
SMLoc IDLoc,
3077 if (ParserOptions.IsPicEnabled)
3078 emitLoadGlobalAddress(Inst, IDLoc, Out);
3080 emitLoadLocalAddress(Inst, IDLoc, Out);
3083void RISCVAsmParser::emitLoadTLSIEAddress(
MCInst &Inst,
SMLoc IDLoc,
3093 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3095 SecondOpcode, IDLoc, Out);
3098void RISCVAsmParser::emitLoadTLSGDAddress(
MCInst &Inst,
SMLoc IDLoc,
3109 RISCV::ADDI, IDLoc, Out);
3112void RISCVAsmParser::emitLoadStoreSymbol(
MCInst &Inst,
unsigned Opcode,
3122 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3124 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3128 Opcode, IDLoc, Out);
3131void RISCVAsmParser::emitPseudoExtend(
MCInst &Inst,
bool SignExtend,
3132 int64_t Width,
SMLoc IDLoc,
3144 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3145 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3147 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3160void RISCVAsmParser::emitVMSGE(
MCInst &Inst,
unsigned Opcode,
SMLoc IDLoc,
3171 .addReg(RISCV::NoRegister));
3182 "The destination register should not be V0.");
3191 .addReg(RISCV::V0));
3199 "The destination register should be V0.");
3201 "The temporary vector register should not be V0.");
3206 .addReg(RISCV::NoRegister));
3218 "The temporary vector register should not be V0.");
3223 .addReg(RISCV::NoRegister));
3231 .addReg(RISCV::V0));
3239bool RISCVAsmParser::checkPseudoAddTPRel(
MCInst &Inst,
3241 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3244 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3245 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3246 "%tprel_add modifier");
3252std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3253 return RISCVOperand::createReg(RISCV::NoRegister,
llvm::SMLoc(),
3257std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3258 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3262std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3263 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3267bool RISCVAsmParser::validateInstruction(
MCInst &Inst,
3271 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3272 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3275 if (DestReg == TempReg) {
3277 return Error(Loc,
"The temporary vector register cannot be the same as "
3278 "the destination register.");
3282 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3283 Opcode == RISCV::TH_LWD) {
3288 if (Rs1 == Rd1 && Rs1 == Rd2) {
3290 return Error(Loc,
"The source register and destination registers "
3291 "cannot be equal.");
3295 if (Opcode == RISCV::CM_MVSA01) {
3300 return Error(Loc,
"'rs1' and 'rs2' must be different.");
3304 bool IsTHeadMemPair32 = (Opcode == RISCV::TH_LWD ||
3305 Opcode == RISCV::TH_LWUD || Opcode == RISCV::TH_SWD);
3306 bool IsTHeadMemPair64 = (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_SDD);
3311 return Error(Loc,
"Operand must be constant 3.");
3314 return Error(Loc,
"Operand must be constant 4.");
3317 bool IsAMOCAS_D = Opcode == RISCV::AMOCAS_D || Opcode == RISCV::AMOCAS_D_AQ ||
3318 Opcode == RISCV::AMOCAS_D_RL ||
3319 Opcode == RISCV::AMOCAS_D_AQ_RL;
3320 bool IsAMOCAS_Q = Opcode == RISCV::AMOCAS_Q || Opcode == RISCV::AMOCAS_Q_AQ ||
3321 Opcode == RISCV::AMOCAS_Q_RL ||
3322 Opcode == RISCV::AMOCAS_Q_AQ_RL;
3323 if ((!isRV64() && IsAMOCAS_D) || IsAMOCAS_Q) {
3326 assert(Rd >= RISCV::X0 && Rd <= RISCV::X31);
3327 if ((Rd - RISCV::X0) % 2 != 0) {
3329 return Error(Loc,
"The destination register must be even.");
3331 assert(Rs2 >= RISCV::X0 && Rs2 <= RISCV::X31);
3332 if ((Rs2 - RISCV::X0) % 2 != 0) {
3334 return Error(Loc,
"The source register must be even.");
3342 if (Opcode == RISCV::VC_V_XVW || Opcode == RISCV::VC_V_IVW ||
3343 Opcode == RISCV::VC_V_FVW || Opcode == RISCV::VC_V_VVW) {
3349 if (VCIXDst == VCIXRs1)
3350 return Error(VCIXDstLoc,
"The destination vector register group cannot"
3351 " overlap the source vector register group.");
3355 if (VCIXDst == VCIXRs2)
3356 return Error(VCIXDstLoc,
"The destination vector register group cannot"
3357 " overlap the source vector register group.");
3372 if (DestReg == CheckReg)
3373 return Error(Loc,
"The destination vector register group cannot overlap"
3374 " the source vector register group.");
3378 if (DestReg == CheckReg)
3379 return Error(Loc,
"The destination vector register group cannot overlap"
3380 " the source vector register group.");
3385 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM ||
3386 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM ||
3387 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM ||
3388 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM ||
3389 Opcode == RISCV::VMERGE_VXM)
3390 return Error(Loc,
"The destination vector register group cannot be V0.");
3397 assert((CheckReg == RISCV::V0 || CheckReg == RISCV::NoRegister) &&
3398 "Unexpected register for mask operand");
3400 if (DestReg == CheckReg)
3401 return Error(Loc,
"The destination vector register group cannot overlap"
3402 " the mask register.");
3407bool RISCVAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
3415 case RISCV::PseudoLLAImm:
3416 case RISCV::PseudoLAImm:
3417 case RISCV::PseudoLI: {
3434 Imm = SignExtend64<32>(Imm);
3435 emitLoadImm(
Reg, Imm, Out);
3438 case RISCV::PseudoLLA:
3439 emitLoadLocalAddress(Inst, IDLoc, Out);
3441 case RISCV::PseudoLGA:
3442 emitLoadGlobalAddress(Inst, IDLoc, Out);
3444 case RISCV::PseudoLA:
3445 emitLoadAddress(Inst, IDLoc, Out);
3447 case RISCV::PseudoLA_TLS_IE:
3448 emitLoadTLSIEAddress(Inst, IDLoc, Out);
3450 case RISCV::PseudoLA_TLS_GD:
3451 emitLoadTLSGDAddress(Inst, IDLoc, Out);
3453 case RISCV::PseudoLB:
3454 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
3456 case RISCV::PseudoLBU:
3457 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
3459 case RISCV::PseudoLH:
3460 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
3462 case RISCV::PseudoLHU:
3463 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
3465 case RISCV::PseudoLW:
3466 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
3468 case RISCV::PseudoLWU:
3469 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
3471 case RISCV::PseudoLD:
3472 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
3474 case RISCV::PseudoFLH:
3475 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
3477 case RISCV::PseudoFLW:
3478 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
3480 case RISCV::PseudoFLD:
3481 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
3483 case RISCV::PseudoSB:
3484 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
3486 case RISCV::PseudoSH:
3487 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
3489 case RISCV::PseudoSW:
3490 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
3492 case RISCV::PseudoSD:
3493 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
3495 case RISCV::PseudoFSH:
3496 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
3498 case RISCV::PseudoFSW:
3499 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
3501 case RISCV::PseudoFSD:
3502 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
3504 case RISCV::PseudoAddTPRel:
3505 if (checkPseudoAddTPRel(Inst,
Operands))
3508 case RISCV::PseudoSEXT_B:
3509 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
3511 case RISCV::PseudoSEXT_H:
3512 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
3514 case RISCV::PseudoZEXT_H:
3515 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
3517 case RISCV::PseudoZEXT_W:
3518 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
3520 case RISCV::PseudoVMSGEU_VX:
3521 case RISCV::PseudoVMSGEU_VX_M:
3522 case RISCV::PseudoVMSGEU_VX_M_T:
3523 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
3525 case RISCV::PseudoVMSGE_VX:
3526 case RISCV::PseudoVMSGE_VX_M:
3527 case RISCV::PseudoVMSGE_VX_M_T:
3528 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
3530 case RISCV::PseudoVMSGE_VI:
3531 case RISCV::PseudoVMSLT_VI: {
3535 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
3544 case RISCV::PseudoVMSGEU_VI:
3545 case RISCV::PseudoVMSLTU_VI: {
3552 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3562 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3576 emitToStreamer(Out, Inst);
static const char * getSubtargetFeatureName(uint64_t Val)
static unsigned MatchRegisterName(StringRef Name)
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
static unsigned 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
#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 matchRegisterNameHelper(bool IsRVE, StringRef Name)
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 SmallString 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)
bool parseImmediate(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes)
Class for arbitrary precision integers.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Target independent representation for an assembler token.
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
StringRef getStringContents() const
Get the contents of a string token (without quotes).
bool is(TokenKind K) const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
This class represents an Operation in the Expression.
Encoding
Size and signedness of expression operations' operands.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Container class for subtarget features.
constexpr size_t size() const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
MCStreamer & getStreamer()
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual MCContext & getContext()=0
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCObjectFileInfo * getObjectFileInfo() const
MCSymbol * createNamedTempSymbol()
Create a temporary symbol with a unique name whose name cannot be omitted in the symbol table.
Base class for the full range of assembler expressions which are needed for parsing.
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
MCInstBuilder & addReg(unsigned Reg)
Add a new register operand.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
ArrayRef< MCOperandInfo > operands() const
unsigned short NumOperands
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specified operand constraint if it is present.
Interface to description of machine instruction set.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
bool isPositionIndependent() const
Instances of this class represent operands of the MCInst class.
static MCOperand createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createImm(int64_t Val)
unsigned getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const MCRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
Wrapper class representing physical registers. Should be passed by value.
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
MCTargetStreamer * getTargetStreamer()
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
void setFeatureBits(const FeatureBitset &FeatureBits_)
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual ParseStatus parseDirective(AsmToken DirectiveID)
Parses a target-specific assembler directive.
MCSubtargetInfo & copySTI()
Create a copy of STI and return a non-const reference to it.
@ FIRST_TARGET_MATCH_RESULT_TY
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
void setAvailableFeatures(const FeatureBitset &Value)
const MCSubtargetInfo & getSTI() const
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)
Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
ParseInstruction - Parse one assembly instruction.
virtual unsigned checkTargetMatchPredicate(MCInst &Inst)
checkTargetMatchPredicate - Validate the instruction match against any complex target predicates not ...
virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
MatchAndEmitInstruction - Recognize a series of operands of a parsed instruction as an actual MCInst ...
Target specific streamer interface.
This represents an "assembler immediate".
uint32_t getRefKind() const
const MCSymbolRefExpr * getSymB() const
const MCSymbolRefExpr * getSymA() const
Ternary parse status returned by various parse* methods.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
static bool isSupportedExtensionFeature(StringRef Ext)
static bool isSupportedExtension(StringRef Ext)
static llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseArchString(StringRef Arch, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck=true, bool IgnoreUnknown=false)
Parse RISC-V ISA info from arch string.
static const char * getRegisterName(MCRegister Reg)
static const RISCVMCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx)
static VariantKind getVariantKindForName(StringRef name)
Wrapper class representing virtual and physical registers.
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
Represents a range in source code.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class wraps a string in an Error.
StringRef - Represent a constant reference to a string, i.e.
char back() const
back - Get the last character in the string.
A switch()-like statement whose cases are string literals.
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
const CustomOperand< const MCSubtargetInfo & > Msg[]
uint16_t StackAdjustment(const RuntimeFunction &RF)
StackAdjustment - calculated stack adjustment in words.
std::optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)
ABI computeTargetABI(const Triple &TT, const FeatureBitset &FeatureBits, StringRef ABIName)
const TagNameMap & getRISCVAttributeTags()
static RoundingMode stringToRoundingMode(StringRef Str)
llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseFeatureBits(bool IsRV64, const FeatureBitset &FeatureBits)
int getLoadFPImm(APFloat FPImm)
getLoadFPImm - Return a 5-bit binary encoding of the floating-point immediate value.
InstSeq generateInstSeq(int64_t Val, const FeatureBitset &ActiveFeatures)
bool compress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI)
static bool isValidLMUL(unsigned LMUL, bool Fractional)
static RISCVII::VLMUL encodeLMUL(unsigned LMUL, bool Fractional)
static bool isValidSEW(unsigned SEW)
void printVType(unsigned VType, raw_ostream &OS)
unsigned encodeVTYPE(RISCVII::VLMUL VLMUL, unsigned SEW, bool TailAgnostic, bool MaskAgnostic)
unsigned encodeRlist(MCRegister EndReg, bool IsRV32E=false)
void printRlist(unsigned SlistEncode, raw_ostream &OS)
static bool getSpimm(unsigned RlistVal, unsigned &SpimmVal, int64_t StackAdjustment, bool IsRV64, bool IsEABI)
void printSpimm(int64_t Spimm, raw_ostream &OS)
@ CE
Windows NT (Windows on ARM)
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Target & getTheRISCV32Target()
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
DWARFExpression::Operation Op
Target & getTheRISCV64Target()
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures]
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
Used to provide key value pairs for feature and CPU bit flags.