46#define DEBUG_TYPE "riscv-asm-parser"
49 "Number of RISC-V Compressed instructions emitted");
58struct ParserOptionsSet {
66 ParserOptionsSet ParserOptions;
74 "do not have a target streamer");
80 unsigned Kind)
override;
89 bool MatchingInlineAsm)
override;
92 SMLoc &EndLoc)
override;
94 SMLoc &EndLoc)
override;
130 void emitLoadStoreSymbol(
MCInst &Inst,
unsigned Opcode,
SMLoc IDLoc,
134 void emitPseudoExtend(
MCInst &Inst,
bool SignExtend, int64_t Width,
157#define GET_ASSEMBLER_HEADER
158#include "RISCVGenAsmMatcher.inc"
163 bool AllowParens =
false);
180 bool parseDirectiveOption();
181 bool parseDirectiveAttribute();
182 bool parseDirectiveInsn(
SMLoc L);
183 bool parseDirectiveVariantCC();
186 if (!(
getSTI().getFeatureBits()[Feature])) {
193 bool getFeatureBits(
uint64_t Feature) {
198 if (
getSTI().getFeatureBits()[Feature]) {
205 void pushFeatureBits() {
207 "These two stacks must be kept synchronized");
209 ParserOptionsStack.
push_back(ParserOptions);
212 bool popFeatureBits() {
214 "These two stacks must be kept synchronized");
215 if (FeatureBitStack.
empty())
227 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
228 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
231 enum RISCVMatchResultTy {
233 Match_RequiresEvenGPRs,
234#define GET_OPERAND_DIAGNOSTIC_TYPES
235#include "RISCVGenAsmMatcher.inc"
236#undef GET_OPERAND_DIAGNOSTIC_TYPES
239 static bool classifySymbolRef(
const MCExpr *Expr,
252 if (ABIName.endswith(
"f") &&
253 !getSTI().getFeatureBits()[RISCV::FeatureStdExtF]) {
254 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
255 "doesn't support the F instruction set extension (ignoring "
257 }
else if (ABIName.endswith(
"d") &&
258 !getSTI().getFeatureBits()[RISCV::FeatureStdExtD]) {
259 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
260 "doesn't support the D instruction set extension (ignoring "
318 SMLoc StartLoc, EndLoc;
323 struct SysRegOp SysReg;
324 struct VTypeOp VType;
326 struct FenceOp Fence;
329 RISCVOperand(KindTy K) :
Kind(K) {}
334 StartLoc = o.StartLoc;
337 case KindTy::Register:
340 case KindTy::Immediate:
346 case KindTy::SystemRegister:
361 bool isToken()
const override {
return Kind == KindTy::Token; }
362 bool isReg()
const override {
return Kind == KindTy::Register; }
363 bool isV0Reg()
const {
364 return Kind == KindTy::Register &&
Reg.RegNum == RISCV::V0;
366 bool isImm()
const override {
return Kind == KindTy::Immediate; }
367 bool isMem()
const override {
return false; }
368 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
371 return Kind == KindTy::Register &&
372 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.RegNum);
375 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
377 bool isGPRF64AsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
379 bool isGPRPF64AsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
381 static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &Imm,
383 if (
auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
385 return RE->evaluateAsConstant(Imm);
388 if (
auto CE = dyn_cast<MCConstantExpr>(Expr)) {
390 Imm =
CE->getValue();
399 template <
int N>
bool isBareSimmNLsb0()
const {
404 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
407 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
415 bool isBareSymbol()
const {
419 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
421 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
425 bool isCallSymbol()
const {
429 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
431 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
436 bool isPseudoJumpSymbol()
const {
440 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
442 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
446 bool isTPRelAddSymbol()
const {
450 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
452 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
456 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
458 bool isVTypeImm(
unsigned N)
const {
463 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
469 bool isVTypeI10()
const {
470 if (Kind == KindTy::Immediate)
471 return isVTypeImm(10);
472 return Kind == KindTy::VType;
474 bool isVTypeI11()
const {
475 if (Kind == KindTy::Immediate)
476 return isVTypeImm(11);
477 return Kind == KindTy::VType;
482 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
485 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
487 bool isImmXLenLI()
const {
492 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
498 (isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm)));
501 bool isUImmLog2XLen()
const {
506 if (!evaluateConstantImm(getImm(), Imm, VK) ||
509 return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm);
512 bool isUImmLog2XLenNonZero()
const {
517 if (!evaluateConstantImm(getImm(), Imm, VK) ||
522 return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm);
525 bool isUImmLog2XLenHalf()
const {
530 if (!evaluateConstantImm(getImm(), Imm, VK) ||
533 return (isRV64Imm() && isUInt<5>(Imm)) || isUInt<4>(Imm);
536 template <
unsigned N>
bool IsUImm()
const {
541 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
545 bool isUImm2() {
return IsUImm<2>(); }
546 bool isUImm3() {
return IsUImm<3>(); }
547 bool isUImm5() {
return IsUImm<5>(); }
548 bool isUImm7() {
return IsUImm<7>(); }
550 bool isRnumArg()
const {
555 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
556 return IsConstantImm &&
Imm >= INT64_C(0) &&
Imm <= INT64_C(10) &&
560 bool isSImm5()
const {
565 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
569 bool isSImm6()
const {
574 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
578 bool isSImm6NonZero()
const {
583 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
584 return IsConstantImm && isInt<6>(Imm) && (
Imm != 0) &&
588 bool isCLUIImm()
const {
593 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
594 return IsConstantImm && (
Imm != 0) &&
595 (isUInt<5>(Imm) || (
Imm >= 0xfffe0 &&
Imm <= 0xfffff)) &&
599 bool isUImm2Lsb0()
const {
604 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
605 return IsConstantImm && isShiftedUInt<1, 1>(Imm) &&
609 bool isUImm7Lsb00()
const {
614 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
615 return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
619 bool isUImm8Lsb00()
const {
624 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
625 return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
629 bool isUImm8Lsb000()
const {
634 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
635 return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
639 bool isSImm9Lsb0()
const {
return isBareSimmNLsb0<9>(); }
641 bool isUImm9Lsb000()
const {
646 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
647 return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
651 bool isUImm10Lsb00NonZero()
const {
656 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
657 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (
Imm != 0) &&
661 bool isSImm12()
const {
667 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
669 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
671 IsValid = isInt<12>(Imm);
678 bool isSImm12Lsb0()
const {
return isBareSimmNLsb0<12>(); }
680 bool isSImm12Lsb00000()
const {
685 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
686 return IsConstantImm && isShiftedInt<7, 5>(Imm) &&
690 bool isSImm13Lsb0()
const {
return isBareSimmNLsb0<13>(); }
692 bool isSImm10Lsb0000NonZero()
const {
697 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
698 return IsConstantImm && (
Imm != 0) && isShiftedInt<6, 4>(Imm) &&
702 bool isUImm20LUI()
const {
708 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
709 if (!IsConstantImm) {
710 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
720 bool isUImm20AUIPC()
const {
726 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
727 if (!IsConstantImm) {
728 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
742 bool isSImm21Lsb0JAL()
const {
return isBareSimmNLsb0<21>(); }
744 bool isImmZero()
const {
749 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
753 bool isSImm5Plus1()
const {
758 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
759 return IsConstantImm && isInt<5>(Imm - 1) &&
764 SMLoc getStartLoc()
const override {
return StartLoc; }
766 SMLoc getEndLoc()
const override {
return EndLoc; }
768 bool isRV64Imm()
const {
769 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
773 unsigned getReg()
const override {
774 assert(Kind == KindTy::Register &&
"Invalid type access!");
775 return Reg.RegNum.id();
779 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
780 return StringRef(SysReg.Data, SysReg.Length);
783 const MCExpr *getImm()
const {
784 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
789 assert(Kind == KindTy::Token &&
"Invalid type access!");
793 unsigned getVType()
const {
794 assert(Kind == KindTy::VType &&
"Invalid type access!");
799 assert(Kind == KindTy::FRM &&
"Invalid type access!");
803 unsigned getFence()
const {
804 assert(Kind == KindTy::Fence &&
"Invalid type access!");
817 case KindTy::Immediate:
820 case KindTy::Register:
824 OS <<
"'" << getToken() <<
"'";
826 case KindTy::SystemRegister:
827 OS <<
"<sysreg: " << getSysReg() <<
'>';
836 roundingModeToString(getFRM());
847 static std::unique_ptr<RISCVOperand> createToken(
StringRef Str,
SMLoc S) {
848 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
855 static std::unique_ptr<RISCVOperand>
856 createReg(
unsigned RegNo,
SMLoc S,
SMLoc E,
bool IsGPRAsFPR =
false) {
857 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
858 Op->Reg.RegNum = RegNo;
859 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
865 static std::unique_ptr<RISCVOperand> createImm(
const MCExpr *Val,
SMLoc S,
867 auto Op = std::make_unique<RISCVOperand>(KindTy::Immediate);
869 Op->Imm.IsRV64 = IsRV64;
875 static std::unique_ptr<RISCVOperand> createSysReg(
StringRef Str,
SMLoc S,
877 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
878 Op->SysReg.Data = Str.data();
879 Op->SysReg.Length = Str.size();
880 Op->SysReg.Encoding = Encoding;
886 static std::unique_ptr<RISCVOperand>
888 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
895 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val,
SMLoc S) {
896 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
903 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI,
SMLoc S) {
904 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
905 Op->VType.Val = VTypeI;
912 assert(Expr &&
"Expr shouldn't be null!");
915 bool IsConstant = evaluateConstantImm(Expr, Imm, VK);
924 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
925 assert(
N == 1 &&
"Invalid number of operands!");
929 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
930 assert(
N == 1 &&
"Invalid number of operands!");
931 addExpr(Inst, getImm());
934 void addFenceArgOperands(
MCInst &Inst,
unsigned N)
const {
935 assert(
N == 1 &&
"Invalid number of operands!");
939 void addCSRSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
940 assert(
N == 1 &&
"Invalid number of operands!");
947 void addVTypeIOperands(
MCInst &Inst,
unsigned N)
const {
948 assert(
N == 1 &&
"Invalid number of operands!");
950 if (Kind == KindTy::Immediate) {
952 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
954 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
961 void addFRMArgOperands(
MCInst &Inst,
unsigned N)
const {
962 assert(
N == 1 &&
"Invalid number of operands!");
968#define GET_REGISTER_MATCHER
969#define GET_SUBTARGET_FEATURE_NAME
970#define GET_MATCHER_IMPLEMENTATION
971#define GET_MNEMONIC_SPELL_CHECKER
972#include "RISCVGenAsmMatcher.inc"
975 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
976 return Reg - RISCV::F0_D + RISCV::F0_H;
980 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
981 return Reg - RISCV::F0_D + RISCV::F0_F;
987 if (Kind == MCK_VRM2)
988 RegClassID = RISCV::VRM2RegClassID;
989 else if (Kind == MCK_VRM4)
990 RegClassID = RISCV::VRM4RegClassID;
991 else if (Kind == MCK_VRM8)
992 RegClassID = RISCV::VRM8RegClassID;
996 &RISCVMCRegisterClasses[RegClassID]);
1001 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1003 return Match_InvalidOperand;
1007 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg);
1009 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg);
1010 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg);
1014 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1015 (IsRegFPR64C &&
Kind == MCK_FPR32C)) {
1017 return Match_Success;
1021 if (IsRegFPR64 && Kind == MCK_FPR16) {
1023 return Match_Success;
1027 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1029 if (
Op.Reg.RegNum == 0)
1030 return Match_InvalidOperand;
1031 return Match_Success;
1033 return Match_InvalidOperand;
1036unsigned RISCVAsmParser::checkTargetMatchPredicate(
MCInst &Inst) {
1040 if (MCID.
operands()[
I].RegClass == RISCV::GPRPF64RegClassID) {
1045 if (((
Reg.id() - RISCV::X0) & 1) != 0)
1046 return Match_RequiresEvenGPRs;
1050 return Match_Success;
1053bool RISCVAsmParser::generateImmOutOfRangeError(
1055 Twine Msg =
"immediate must be an integer in the range") {
1060bool RISCVAsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1064 bool MatchingInlineAsm) {
1074 if (validateInstruction(Inst,
Operands))
1076 return processInstruction(Inst, IDLoc,
Operands, Out);
1077 case Match_MissingFeature: {
1078 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1079 bool FirstFeature =
true;
1080 std::string
Msg =
"instruction requires the following:";
1081 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1082 if (MissingFeatures[i]) {
1083 Msg += FirstFeature ?
" " :
", ";
1085 FirstFeature =
false;
1088 return Error(IDLoc, Msg);
1090 case Match_MnemonicFail: {
1091 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1092 std::string Suggestion = RISCVMnemonicSpellCheck(
1093 ((RISCVOperand &)*
Operands[0]).getToken(), FBS, 0);
1094 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1096 case Match_InvalidOperand: {
1097 SMLoc ErrorLoc = IDLoc;
1100 return Error(ErrorLoc,
"too few operands for instruction");
1103 if (ErrorLoc ==
SMLoc())
1106 return Error(ErrorLoc,
"invalid operand for instruction");
1113 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1114 SMLoc ErrorLoc = IDLoc;
1116 return Error(ErrorLoc,
"too few operands for instruction");
1122 case Match_RequiresEvenGPRs:
1124 "double precision floating point operands must use even "
1125 "numbered X register");
1126 case Match_InvalidImmXLenLI:
1129 return Error(ErrorLoc,
"operand must be a constant 64-bit integer");
1132 std::numeric_limits<int32_t>::min(),
1133 std::numeric_limits<uint32_t>::max());
1134 case Match_InvalidImmZero: {
1136 return Error(ErrorLoc,
"immediate must be zero");
1138 case Match_InvalidUImmLog2XLen:
1142 case Match_InvalidUImmLog2XLenNonZero:
1146 case Match_InvalidUImmLog2XLenHalf:
1150 case Match_InvalidUImm2:
1152 case Match_InvalidUImm2Lsb0:
1154 "immediate must be one of");
1155 case Match_InvalidUImm3:
1157 case Match_InvalidUImm5:
1159 case Match_InvalidUImm7:
1161 case Match_InvalidSImm5:
1164 case Match_InvalidSImm6:
1167 case Match_InvalidSImm6NonZero:
1168 return generateImmOutOfRangeError(
1170 "immediate must be non-zero in the range");
1171 case Match_InvalidCLUIImm:
1172 return generateImmOutOfRangeError(
1174 "immediate must be in [0xfffe0, 0xfffff] or");
1175 case Match_InvalidUImm7Lsb00:
1176 return generateImmOutOfRangeError(
1178 "immediate must be a multiple of 4 bytes in the range");
1179 case Match_InvalidUImm8Lsb00:
1180 return generateImmOutOfRangeError(
1182 "immediate must be a multiple of 4 bytes in the range");
1183 case Match_InvalidUImm8Lsb000:
1184 return generateImmOutOfRangeError(
1186 "immediate must be a multiple of 8 bytes in the range");
1187 case Match_InvalidSImm9Lsb0:
1188 return generateImmOutOfRangeError(
1190 "immediate must be a multiple of 2 bytes in the range");
1191 case Match_InvalidUImm9Lsb000:
1192 return generateImmOutOfRangeError(
1194 "immediate must be a multiple of 8 bytes in the range");
1195 case Match_InvalidUImm10Lsb00NonZero:
1196 return generateImmOutOfRangeError(
1198 "immediate must be a multiple of 4 bytes in the range");
1199 case Match_InvalidSImm10Lsb0000NonZero:
1200 return generateImmOutOfRangeError(
1202 "immediate must be a multiple of 16 bytes and non-zero in the range");
1203 case Match_InvalidSImm12:
1204 return generateImmOutOfRangeError(
1206 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an "
1207 "integer in the range");
1208 case Match_InvalidSImm12Lsb0:
1209 return generateImmOutOfRangeError(
1211 "immediate must be a multiple of 2 bytes in the range");
1212 case Match_InvalidSImm12Lsb00000:
1213 return generateImmOutOfRangeError(
1215 "immediate must be a multiple of 32 bytes in the range");
1216 case Match_InvalidSImm13Lsb0:
1217 return generateImmOutOfRangeError(
1219 "immediate must be a multiple of 2 bytes in the range");
1220 case Match_InvalidUImm20LUI:
1222 "operand must be a symbol with "
1223 "%hi/%tprel_hi modifier or an integer in "
1225 case Match_InvalidUImm20AUIPC:
1226 return generateImmOutOfRangeError(
1228 "operand must be a symbol with a "
1229 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
1230 "an integer in the range");
1231 case Match_InvalidSImm21Lsb0JAL:
1232 return generateImmOutOfRangeError(
1234 "immediate must be a multiple of 2 bytes in the range");
1235 case Match_InvalidCSRSystemRegister: {
1237 "operand must be a valid system register "
1238 "name or an integer in the range");
1240 case Match_InvalidBareSymbol: {
1242 return Error(ErrorLoc,
"operand must be a bare symbol name");
1244 case Match_InvalidPseudoJumpSymbol: {
1246 return Error(ErrorLoc,
"operand must be a valid jump target");
1248 case Match_InvalidCallSymbol: {
1250 return Error(ErrorLoc,
"operand must be a bare symbol name");
1252 case Match_InvalidTPRelAddSymbol: {
1254 return Error(ErrorLoc,
"operand must be a symbol with %tprel_add modifier");
1256 case Match_InvalidVTypeI: {
1261 "e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
1263 case Match_InvalidVMaskRegister: {
1265 return Error(ErrorLoc,
"operand must be v0.t");
1267 case Match_InvalidSImm5Plus1: {
1270 "immediate must be in the range");
1272 case Match_InvalidRnumArg: {
1289 assert(!(RegNo >= RISCV::F0_H && RegNo <= RISCV::F31_H));
1290 assert(!(RegNo >= RISCV::F0_F && RegNo <= RISCV::F31_F));
1292 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1293 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1294 if (RegNo == RISCV::NoRegister)
1296 if (IsRV32E && RegNo >= RISCV::X16 && RegNo <= RISCV::X31)
1297 RegNo = RISCV::NoRegister;
1298 return RegNo == RISCV::NoRegister;
1304 return Error(StartLoc,
"invalid register name");
1311 const AsmToken &Tok = getParser().getTok();
1326 SMLoc FirstS = getLoc();
1327 bool HadParens =
false;
1334 size_t ReadCount = getLexer().peekTokens(Buf);
1337 LParen = getParser().getTok();
1342 switch (getLexer().getKind()) {
1345 getLexer().UnLex(LParen);
1352 if (RegNo == RISCV::NoRegister) {
1354 getLexer().UnLex(LParen);
1358 Operands.push_back(RISCVOperand::createToken(
"(", FirstS));
1362 Operands.push_back(RISCVOperand::createReg(RegNo, S,
E));
1367 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
1379 switch (getLexer().getKind()) {
1389 if (getParser().parseExpression(Res,
E))
1392 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1394 int64_t
Imm =
CE->getValue();
1395 if (isUInt<7>(Imm)) {
1396 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1401 Twine Msg =
"immediate must be an integer in the range";
1407 if (getParser().parseIdentifier(Identifier))
1410 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1414 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1418 Twine Msg =
"operand must be a valid opcode name or an "
1419 "integer in the range";
1425 Twine Msg =
"immediate must be an integer in the range";
1439 switch (getLexer().getKind()) {
1449 if (getParser().parseExpression(Res))
1452 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1454 int64_t
Imm =
CE->getValue();
1455 if (isUInt<12>(Imm)) {
1456 auto SysReg = RISCVSysReg::lookupSysRegByEncoding(Imm);
1460 RISCVOperand::createSysReg(SysReg ? SysReg->Name :
"", S, Imm));
1465 Twine Msg =
"immediate must be an integer in the range";
1471 if (getParser().parseIdentifier(Identifier))
1474 auto SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1476 SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier);
1478 if ((SysReg = RISCVSysReg::lookupSysRegByDeprecatedName(Identifier)))
1479 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
1480 SysReg->Name +
"'");
1484 if (!SysReg->haveRequiredFeatures(getSTI().getFeatureBits())) {
1485 Error(S,
"system register use requires an option to be enabled");
1489 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
1493 Twine Msg =
"operand must be a valid system register name "
1494 "or an integer in the range";
1500 Twine Msg =
"immediate must be an integer in the range";
1514 switch (getLexer().getKind()) {
1526 if (getParser().parseExpression(Res,
E))
1530 return parseOperandWithModifier(
Operands);
1533 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1543 Error(getLoc(),
"expected '%' for operand modifier");
1550 Error(getLoc(),
"expected valid identifier for operand modifier");
1556 Error(getLoc(),
"unrecognized operand modifier");
1562 Error(getLoc(),
"expected '('");
1568 if (getParser().parseParenExpression(SubExpr,
E)) {
1573 Operands.push_back(RISCVOperand::createImm(ModExpr, S,
E, isRV64()));
1585 AsmToken Tok = getLexer().getTok();
1587 if (getParser().parseIdentifier(Identifier))
1593 Error(getLoc(),
"'@plt' operand not valid for instruction");
1597 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1601 if (!isa<MCSymbolRefExpr>(V)) {
1602 getLexer().UnLex(Tok);
1610 switch (getLexer().getKind()) {
1612 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1625 if (getParser().parseExpression(Expr,
E))
1628 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1644 if (getParser().parseIdentifier(Identifier))
1653 MCSymbol *Sym = getContext().getOrCreateSymbol(Identifier);
1656 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1666 if (getParser().parseExpression(Res,
E))
1669 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef ||
1670 cast<MCSymbolRefExpr>(Res)->getKind() ==
1671 MCSymbolRefExpr::VariantKind::VK_PLT) {
1672 Error(S,
"operand must be a valid jump target");
1677 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1706 VTypeIElements.
push_back(getLexer().getTok());
1717 if (VTypeIElements.
size() == 7) {
1722 if (!
Name.consume_front(
"e"))
1725 if (
Name.getAsInteger(10, Sew))
1730 Name = VTypeIElements[2].getIdentifier();
1731 if (!
Name.consume_front(
"m"))
1734 bool Fractional =
Name.consume_front(
"f");
1736 if (
Name.getAsInteger(10, Lmul))
1742 Name = VTypeIElements[4].getIdentifier();
1746 else if (
Name ==
"tu")
1752 Name = VTypeIElements[6].getIdentifier();
1756 else if (
Name ==
"mu")
1765 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
1771 while (!VTypeIElements.
empty())
1781 if (!
Name.consume_back(
".t")) {
1782 Error(getLoc(),
"expected '.t' suffix");
1788 if (RegNo == RISCV::NoRegister)
1790 if (RegNo != RISCV::V0)
1795 Operands.push_back(RISCVOperand::createReg(RegNo, S,
E));
1807 if (RegNo == RISCV::NoRegister)
1812 Operands.push_back(RISCVOperand::createReg(
1813 RegNo, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
1819 TokError(
"operand must be a valid floating point rounding mode mnemonic");
1823 StringRef Str = getLexer().getTok().getIdentifier();
1827 TokError(
"operand must be a valid floating point rounding mode mnemonic");
1831 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
1837 const AsmToken &Tok = getLexer().getTok();
1843 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
1857 for (
char c : Str) {
1886 Operands.push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
1892 TokError(
"operand must be formed of letters selected in-order from 'iorw' "
1900 Error(getLoc(),
"expected '('");
1905 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
1908 Error(getLoc(),
"expected register");
1913 Error(getLoc(),
"expected ')'");
1918 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
1943 std::unique_ptr<RISCVOperand> OptionalImmOp;
1950 SMLoc ImmStart = getLoc();
1951 if (getParser().parseIntToken(ImmVal,
1952 "expected '(' or optional integer offset"))
1957 SMLoc ImmEnd = getLoc();
1960 ImmStart, ImmEnd, isRV64());
1964 Error(getLoc(), OptionalImmOp ?
"expected '(' after optional integer offset"
1965 :
"expected '(' or optional integer offset");
1971 Error(getLoc(),
"expected register");
1976 Error(getLoc(),
"expected ')'");
1982 if (OptionalImmOp && !OptionalImmOp->isImmZero()) {
1983 Error(OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
1984 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
1998 MatchOperandParserImpl(
Operands, Mnemonic,
true);
2017 Error(getLoc(),
"unknown operand");
2030 if (getSTI().getFeatureBits()[RISCV::FeatureRelax]) {
2031 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
2032 if (Assembler !=
nullptr) {
2040 Operands.push_back(RISCVOperand::createToken(
Name, NameLoc));
2063 SMLoc Loc = getLexer().getLoc();
2064 getParser().eatToEndOfStatement();
2065 return Error(Loc,
"unexpected token");
2072bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
2076 if (
const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
2077 Kind = RE->getKind();
2078 Expr = RE->getSubExpr();
2088bool RISCVAsmParser::ParseDirective(
AsmToken DirectiveID) {
2095 if (IDVal ==
".option")
2096 return parseDirectiveOption();
2097 if (IDVal ==
".attribute")
2098 return parseDirectiveAttribute();
2099 if (IDVal ==
".insn")
2100 return parseDirectiveInsn(DirectiveID.
getLoc());
2101 if (IDVal ==
".variant_cc")
2102 return parseDirectiveVariantCC();
2107bool RISCVAsmParser::parseDirectiveOption() {
2118 if (Option ==
"push") {
2122 getTargetStreamer().emitDirectiveOptionPush();
2127 if (Option ==
"pop") {
2132 getTargetStreamer().emitDirectiveOptionPop();
2133 if (popFeatureBits())
2134 return Error(StartLoc,
".option pop with no .option push");
2139 if (Option ==
"rvc") {
2143 getTargetStreamer().emitDirectiveOptionRVC();
2144 setFeatureBits(RISCV::FeatureStdExtC,
"c");
2148 if (Option ==
"norvc") {
2152 getTargetStreamer().emitDirectiveOptionNoRVC();
2153 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
2154 clearFeatureBits(RISCV::FeatureExtZca,
"+experimental-zca");
2158 if (Option ==
"pic") {
2162 getTargetStreamer().emitDirectiveOptionPIC();
2163 ParserOptions.IsPicEnabled =
true;
2167 if (Option ==
"nopic") {
2171 getTargetStreamer().emitDirectiveOptionNoPIC();
2172 ParserOptions.IsPicEnabled =
false;
2176 if (Option ==
"relax") {
2180 getTargetStreamer().emitDirectiveOptionRelax();
2181 setFeatureBits(RISCV::FeatureRelax,
"relax");
2185 if (Option ==
"norelax") {
2189 getTargetStreamer().emitDirectiveOptionNoRelax();
2190 clearFeatureBits(RISCV::FeatureRelax,
"relax");
2196 "unknown option, expected 'push', 'pop', 'rvc', 'norvc', 'relax' or "
2205bool RISCVAsmParser::parseDirectiveAttribute() {
2212 std::optional<unsigned>
Ret =
2215 Error(TagLoc,
"attribute name not recognised: " +
Name);
2228 if (
check(!CE, TagLoc,
"expected numeric constant"))
2231 Tag =
CE->getValue();
2238 int64_t IntegerValue = 0;
2239 bool IsIntegerValue =
true;
2244 IsIntegerValue =
false;
2247 if (IsIntegerValue) {
2254 return Error(ValueExprLoc,
"expected numeric constant");
2255 IntegerValue =
CE->getValue();
2268 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
2270 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
2275 clearFeatureBits(Feature.Value, Feature.Key);
2284 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
2285 << ErrMsg.getMessage();
2288 return Error(ValueExprLoc, OutputErrMsg.str());
2290 auto &ISAInfo = *ParseResult;
2293 if (ISAInfo->hasExtension(Feature.Key))
2294 setFeatureBits(Feature.Value, Feature.Key);
2296 if (ISAInfo->getXLen() == 32)
2297 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
2298 else if (ISAInfo->getXLen() == 64)
2299 setFeatureBits(RISCV::Feature64Bit,
"64bit");
2301 return Error(ValueExprLoc,
"bad arch string " + Arch);
2304 getTargetStreamer().emitTextAttribute(
Tag, ISAInfo->toString());
2312bool RISCVAsmParser::parseDirectiveInsn(
SMLoc L) {
2319 return Error(ErrorLoc,
"expected instruction format");
2321 if (Format !=
"r" && Format !=
"r4" && Format !=
"i" && Format !=
"b" &&
2322 Format !=
"sb" && Format !=
"u" && Format !=
"j" && Format !=
"uj" &&
2324 return Error(ErrorLoc,
"invalid instruction format");
2326 std::string FormatName = (
".insn_" +
Format).str();
2343bool RISCVAsmParser::parseDirectiveVariantCC() {
2345 if (getParser().parseIdentifier(
Name))
2346 return TokError(
"expected symbol name");
2349 getTargetStreamer().emitDirectiveVariantCC(
2350 *getContext().getOrCreateSymbol(
Name));
2358 ++RISCVNumInstrsCompressed;
2369 switch (Inst.getOpndKind()) {
2399 unsigned SecondOpcode,
SMLoc IDLoc,
2413 const MCExpr *RefToLinkTmpLabel =
2420 .addExpr(RefToLinkTmpLabel));
2423void RISCVAsmParser::emitLoadLocalAddress(
MCInst &Inst,
SMLoc IDLoc,
2434 RISCV::ADDI, IDLoc, Out);
2437void RISCVAsmParser::emitLoadAddress(
MCInst &Inst,
SMLoc IDLoc,
2450 unsigned SecondOpcode;
2452 if (ParserOptions.IsPicEnabled) {
2453 SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
2456 SecondOpcode = RISCV::ADDI;
2459 emitAuipcInstPair(DestReg, DestReg, Symbol, VKHi, SecondOpcode, IDLoc, Out);
2462void RISCVAsmParser::emitLoadTLSIEAddress(
MCInst &Inst,
SMLoc IDLoc,
2472 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
2474 SecondOpcode, IDLoc, Out);
2477void RISCVAsmParser::emitLoadTLSGDAddress(
MCInst &Inst,
SMLoc IDLoc,
2488 RISCV::ADDI, IDLoc, Out);
2491void RISCVAsmParser::emitLoadStoreSymbol(
MCInst &Inst,
unsigned Opcode,
2501 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
2503 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
2507 Opcode, IDLoc, Out);
2510void RISCVAsmParser::emitPseudoExtend(
MCInst &Inst,
bool SignExtend,
2511 int64_t Width,
SMLoc IDLoc,
2523 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
2524 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
2526 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
2539void RISCVAsmParser::emitVMSGE(
MCInst &Inst,
unsigned Opcode,
SMLoc IDLoc,
2550 .addReg(RISCV::NoRegister));
2561 "The destination register should not be V0.");
2570 .addReg(RISCV::V0));
2578 "The destination register should be V0.");
2580 "The temporary vector register should not be V0.");
2597 "The temporary vector register should not be V0.");
2602 .addReg(RISCV::NoRegister));
2610 .addReg(RISCV::V0));
2618bool RISCVAsmParser::checkPseudoAddTPRel(
MCInst &Inst,
2620 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
2623 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
2624 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
2625 "%tprel_add modifier");
2631std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
2632 return RISCVOperand::createReg(RISCV::NoRegister,
llvm::SMLoc(),
2636std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
2637 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
2641bool RISCVAsmParser::validateInstruction(
MCInst &Inst,
2643 if (Inst.
getOpcode() == RISCV::PseudoVMSGEU_VX_M_T ||
2644 Inst.
getOpcode() == RISCV::PseudoVMSGE_VX_M_T) {
2647 if (DestReg == TempReg) {
2649 return Error(Loc,
"The temporary vector register cannot be the same as "
2650 "the destination register.");
2664 if (DestReg == CheckReg)
2665 return Error(Loc,
"The destination vector register group cannot overlap"
2666 " the source vector register group.");
2670 if (DestReg == CheckReg)
2671 return Error(Loc,
"The destination vector register group cannot overlap"
2672 " the source vector register group.");
2678 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM ||
2679 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM ||
2680 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM ||
2681 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM ||
2682 Opcode == RISCV::VMERGE_VXM)
2683 return Error(Loc,
"The destination vector register group cannot be V0.");
2690 assert((CheckReg == RISCV::V0 || CheckReg == RISCV::NoRegister) &&
2691 "Unexpected register for mask operand");
2693 if (DestReg == CheckReg)
2694 return Error(Loc,
"The destination vector register group cannot overlap"
2695 " the mask register.");
2700bool RISCVAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
2708 case RISCV::PseudoLI: {
2725 Imm = SignExtend64<32>(Imm);
2726 emitLoadImm(
Reg, Imm, Out);
2729 case RISCV::PseudoLLA:
2730 emitLoadLocalAddress(Inst, IDLoc, Out);
2732 case RISCV::PseudoLA:
2733 emitLoadAddress(Inst, IDLoc, Out);
2735 case RISCV::PseudoLA_TLS_IE:
2736 emitLoadTLSIEAddress(Inst, IDLoc, Out);
2738 case RISCV::PseudoLA_TLS_GD:
2739 emitLoadTLSGDAddress(Inst, IDLoc, Out);
2741 case RISCV::PseudoLB:
2742 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
2744 case RISCV::PseudoLBU:
2745 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
2747 case RISCV::PseudoLH:
2748 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
2750 case RISCV::PseudoLHU:
2751 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
2753 case RISCV::PseudoLW:
2754 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
2756 case RISCV::PseudoLWU:
2757 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
2759 case RISCV::PseudoLD:
2760 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
2762 case RISCV::PseudoFLH:
2763 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
2765 case RISCV::PseudoFLW:
2766 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
2768 case RISCV::PseudoFLD:
2769 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
2771 case RISCV::PseudoSB:
2772 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
2774 case RISCV::PseudoSH:
2775 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
2777 case RISCV::PseudoSW:
2778 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
2780 case RISCV::PseudoSD:
2781 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
2783 case RISCV::PseudoFSH:
2784 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
2786 case RISCV::PseudoFSW:
2787 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
2789 case RISCV::PseudoFSD:
2790 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
2792 case RISCV::PseudoAddTPRel:
2793 if (checkPseudoAddTPRel(Inst,
Operands))
2796 case RISCV::PseudoSEXT_B:
2797 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
2799 case RISCV::PseudoSEXT_H:
2800 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
2802 case RISCV::PseudoZEXT_H:
2803 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
2805 case RISCV::PseudoZEXT_W:
2806 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
2808 case RISCV::PseudoVMSGEU_VX:
2809 case RISCV::PseudoVMSGEU_VX_M:
2810 case RISCV::PseudoVMSGEU_VX_M_T:
2811 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
2813 case RISCV::PseudoVMSGE_VX:
2814 case RISCV::PseudoVMSGE_VX_M:
2815 case RISCV::PseudoVMSGE_VX_M_T:
2816 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
2818 case RISCV::PseudoVMSGE_VI:
2819 case RISCV::PseudoVMSLT_VI: {
2823 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
2832 case RISCV::PseudoVMSGEU_VI:
2833 case RISCV::PseudoVMSLTU_VI: {
2840 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
2850 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
2864 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
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
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser()
static MCRegister convertFPR64ToFPR32(MCRegister Reg)
static MCRegister convertFPR64ToFPR16(MCRegister Reg)
static bool matchRegisterNameHelper(bool IsRV32E, MCRegister &RegNo, StringRef Name)
static MCRegister convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg, unsigned Kind)
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)
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.
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
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
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 ...
const MCExpr * getVariableValue(bool SetUsed=true) const
getVariableValue - Get the value for variable symbols.
bool isVariable() const
isVariable - Check if this is a variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
virtual bool ParseDirective(AsmToken DirectiveID)=0
ParseDirective - Parse 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
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 ...
virtual OperandMatchResultTy tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
Target specific streamer interface.
This represents an "assembler immediate".
uint32_t getRefKind() const
static bool isSupportedExtensionFeature(StringRef Ext)
static llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseArchString(StringRef Arch, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck=true, bool IgnoreUnknown=false)
Parse RISCV 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)
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.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
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.
const CustomOperand< const MCSubtargetInfo & > Msg[]
std::optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)
ABI computeTargetABI(const Triple &TT, FeatureBitset FeatureBits, StringRef ABIName)
const TagNameMap & getRISCVAttributeTags()
static RoundingMode stringToRoundingMode(StringRef Str)
static VConstraintType getConstraint(uint64_t TSFlags)
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)
@ CE
Windows NT (Windows on ARM)
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
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.
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.