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;
88 bool enableExperimentalExtension()
const {
94 "do not have a target streamer");
100 unsigned Kind)
override;
105 bool generateImmOutOfRangeError(
SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
111 bool MatchingInlineAsm)
override;
116 SMLoc &EndLoc)
override;
123 bool parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
unsigned &Sew,
124 unsigned &Lmul,
bool &Fractional,
bool &TailAgnostic,
126 bool generateVTypeError(
SMLoc ErrorLoc);
160 void emitLoadStoreSymbol(
MCInst &Inst,
unsigned Opcode,
SMLoc IDLoc,
164 void emitPseudoExtend(
MCInst &Inst,
bool SignExtend, int64_t Width,
193#define GET_ASSEMBLER_HEADER
194#include "RISCVGenAsmMatcher.inc"
222 bool ExpectNegative =
false);
224 return parseZcmpStackAdj(
Operands,
true);
229 bool parseDirectiveOption();
230 bool parseDirectiveAttribute();
231 bool parseDirectiveInsn(
SMLoc L);
232 bool parseDirectiveVariantCC();
238 bool FromOptionDirective);
241 if (!(
getSTI().hasFeature(Feature))) {
249 if (
getSTI().hasFeature(Feature)) {
256 void pushFeatureBits() {
258 "These two stacks must be kept synchronized");
260 ParserOptionsStack.
push_back(ParserOptions);
263 bool popFeatureBits() {
265 "These two stacks must be kept synchronized");
266 if (FeatureBitStack.
empty())
278 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
279 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
280 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
283 enum RISCVMatchResultTy {
285#define GET_OPERAND_DIAGNOSTIC_TYPES
286#include "RISCVGenAsmMatcher.inc"
287#undef GET_OPERAND_DIAGNOSTIC_TYPES
290 static bool classifySymbolRef(
const MCExpr *Expr,
292 static bool isSymbolDiff(
const MCExpr *Expr);
306 if (ABIName.ends_with(
"f") && !getSTI().hasFeature(RISCV::FeatureStdExtF)) {
307 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
308 "doesn't support the F instruction set extension (ignoring "
310 }
else if (ABIName.ends_with(
"d") &&
311 !getSTI().hasFeature(RISCV::FeatureStdExtD)) {
312 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
313 "doesn't support the D instruction set extension (ignoring "
326 getTargetStreamer().emitTargetAttributes(STI,
false);
395 SMLoc StartLoc, EndLoc;
401 struct SysRegOp SysReg;
402 struct VTypeOp VType;
404 struct FenceOp Fence;
405 struct RlistOp Rlist;
406 struct SpimmOp Spimm;
410 RISCVOperand(KindTy K) :
Kind(
K) {}
415 StartLoc =
o.StartLoc;
418 case KindTy::Register:
421 case KindTy::Immediate:
424 case KindTy::FPImmediate:
430 case KindTy::SystemRegister:
454 bool isToken()
const override {
return Kind == KindTy::Token; }
455 bool isReg()
const override {
return Kind == KindTy::Register; }
456 bool isV0Reg()
const {
457 return Kind == KindTy::Register &&
Reg.RegNum == RISCV::V0;
459 bool isAnyReg()
const {
460 return Kind == KindTy::Register &&
461 (RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.RegNum) ||
462 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg.RegNum) ||
463 RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg.RegNum));
465 bool isAnyRegC()
const {
466 return Kind == KindTy::Register &&
467 (RISCVMCRegisterClasses[RISCV::GPRCRegClassID].contains(
469 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
472 bool isImm()
const override {
return Kind == KindTy::Immediate; }
473 bool isMem()
const override {
return false; }
474 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
475 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
476 bool isRlist()
const {
return Kind == KindTy::Rlist; }
477 bool isSpimm()
const {
return Kind == KindTy::Spimm; }
480 return Kind == KindTy::Register &&
481 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.RegNum);
484 bool isGPRPair()
const {
485 return Kind == KindTy::Register &&
486 RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(
490 bool isGPRF16()
const {
491 return Kind == KindTy::Register &&
492 RISCVMCRegisterClasses[RISCV::GPRF16RegClassID].contains(
Reg.RegNum);
495 bool isGPRF32()
const {
496 return Kind == KindTy::Register &&
497 RISCVMCRegisterClasses[RISCV::GPRF32RegClassID].contains(
Reg.RegNum);
500 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
501 bool isGPRAsFPR16()
const {
return isGPRF16() &&
Reg.IsGPRAsFPR; }
502 bool isGPRAsFPR32()
const {
return isGPRF32() &&
Reg.IsGPRAsFPR; }
503 bool isGPRPairAsFPR64()
const {
return isGPRPair() &&
Reg.IsGPRAsFPR; }
505 static bool evaluateConstantImm(
const MCExpr *Expr, int64_t &Imm,
507 if (
auto *RE = dyn_cast<RISCVMCExpr>(Expr)) {
509 return RE->evaluateAsConstant(Imm);
512 if (
auto CE = dyn_cast<MCConstantExpr>(Expr)) {
514 Imm =
CE->getValue();
523 template <
int N>
bool isBareSimmNLsb0()
const {
528 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
531 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
539 bool isBareSymbol()
const {
543 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
545 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
549 bool isCallSymbol()
const {
553 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
555 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
560 bool isPseudoJumpSymbol()
const {
564 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
566 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
570 bool isTPRelAddSymbol()
const {
574 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
576 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
580 bool isTLSDESCCallSymbol()
const {
584 if (!
isImm() || evaluateConstantImm(getImm(), Imm, VK))
586 return RISCVAsmParser::classifySymbolRef(getImm(), VK) &&
590 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
592 bool isVTypeImm(
unsigned N)
const {
597 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
603 bool isVTypeI10()
const {
604 if (Kind == KindTy::Immediate)
605 return isVTypeImm(10);
606 return Kind == KindTy::VType;
608 bool isVTypeI11()
const {
609 if (Kind == KindTy::Immediate)
610 return isVTypeImm(11);
611 return Kind == KindTy::VType;
616 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
619 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
620 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
624 bool isLoadFPImm()
const {
627 if (Kind != KindTy::FPImmediate)
630 APFloat(APFloat::IEEEdouble(),
APInt(64, getFPConst())));
633 return Idx >= 0 &&
Idx != 1;
636 bool isImmXLenLI()
const {
641 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
651 (isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm)));
654 return RISCVAsmParser::isSymbolDiff(getImm());
657 bool isImmXLenLI_Restricted()
const {
662 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
665 (isRV64Imm() || (isInt<32>(Imm) || isUInt<32>(Imm)));
668 bool isUImmLog2XLen()
const {
673 if (!evaluateConstantImm(getImm(), Imm, VK) ||
676 return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm);
679 bool isUImmLog2XLenNonZero()
const {
684 if (!evaluateConstantImm(getImm(), Imm, VK) ||
689 return (isRV64Imm() && isUInt<6>(Imm)) || isUInt<5>(Imm);
692 bool isUImmLog2XLenHalf()
const {
697 if (!evaluateConstantImm(getImm(), Imm, VK) ||
700 return (isRV64Imm() && isUInt<5>(Imm)) || isUInt<4>(Imm);
703 template <
unsigned N>
bool IsUImm()
const {
708 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
712 bool isUImm1()
const {
return IsUImm<1>(); }
713 bool isUImm2()
const {
return IsUImm<2>(); }
714 bool isUImm3()
const {
return IsUImm<3>(); }
715 bool isUImm4()
const {
return IsUImm<4>(); }
716 bool isUImm5()
const {
return IsUImm<5>(); }
717 bool isUImm6()
const {
return IsUImm<6>(); }
718 bool isUImm7()
const {
return IsUImm<7>(); }
719 bool isUImm8()
const {
return IsUImm<8>(); }
720 bool isUImm11()
const {
return IsUImm<11>(); }
721 bool isUImm16()
const {
return IsUImm<16>(); }
722 bool isUImm20()
const {
return IsUImm<20>(); }
723 bool isUImm32()
const {
return IsUImm<32>(); }
724 bool isUImm48()
const {
return IsUImm<48>(); }
725 bool isUImm64()
const {
return IsUImm<64>(); }
727 bool isUImm5NonZero()
const {
732 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
733 return IsConstantImm && isUInt<5>(Imm) && (
Imm != 0) &&
737 bool isUImm8GE32()
const {
742 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
743 return IsConstantImm && isUInt<8>(Imm) &&
Imm >= 32 &&
747 bool isRnumArg()
const {
752 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
753 return IsConstantImm &&
Imm >= INT64_C(0) &&
Imm <= INT64_C(10) &&
757 bool isRnumArg_0_7()
const {
762 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
763 return IsConstantImm &&
Imm >= INT64_C(0) &&
Imm <= INT64_C(7) &&
767 bool isRnumArg_1_10()
const {
772 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
773 return IsConstantImm &&
Imm >= INT64_C(1) &&
Imm <= INT64_C(10) &&
777 bool isRnumArg_2_14()
const {
782 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
783 return IsConstantImm &&
Imm >= INT64_C(2) &&
Imm <= INT64_C(14) &&
787 bool isSImm5()
const {
792 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
793 return IsConstantImm && isInt<5>(fixImmediateForRV32(Imm, isRV64Imm())) &&
797 bool isSImm6()
const {
802 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
803 return IsConstantImm && isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) &&
807 bool isSImm6NonZero()
const {
812 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
813 return IsConstantImm &&
Imm != 0 &&
814 isInt<6>(fixImmediateForRV32(Imm, isRV64Imm())) &&
818 bool isCLUIImm()
const {
823 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
824 return IsConstantImm && (
Imm != 0) &&
825 (isUInt<5>(Imm) || (
Imm >= 0xfffe0 &&
Imm <= 0xfffff)) &&
829 bool isUImm2Lsb0()
const {
834 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
835 return IsConstantImm && isShiftedUInt<1, 1>(Imm) &&
839 bool isUImm5Lsb0()
const {
844 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
845 return IsConstantImm && isShiftedUInt<4, 1>(Imm) &&
849 bool isUImm6Lsb0()
const {
854 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
855 return IsConstantImm && isShiftedUInt<5, 1>(Imm) &&
859 bool isUImm7Lsb00()
const {
864 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
865 return IsConstantImm && isShiftedUInt<5, 2>(Imm) &&
869 bool isUImm8Lsb00()
const {
874 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
875 return IsConstantImm && isShiftedUInt<6, 2>(Imm) &&
879 bool isUImm8Lsb000()
const {
884 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
885 return IsConstantImm && isShiftedUInt<5, 3>(Imm) &&
889 bool isSImm9Lsb0()
const {
return isBareSimmNLsb0<9>(); }
891 bool isUImm9Lsb000()
const {
896 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
897 return IsConstantImm && isShiftedUInt<6, 3>(Imm) &&
901 bool isUImm10Lsb00NonZero()
const {
906 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
907 return IsConstantImm && isShiftedUInt<8, 2>(Imm) && (
Imm != 0) &&
913 static int64_t fixImmediateForRV32(int64_t Imm,
bool IsRV64Imm) {
914 if (IsRV64Imm || !isUInt<32>(Imm))
916 return SignExtend64<32>(Imm);
919 bool isSImm12()
const {
925 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
927 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
929 IsValid = isInt<12>(fixImmediateForRV32(Imm, isRV64Imm()));
938 bool isSImm12Lsb0()
const {
return isBareSimmNLsb0<12>(); }
940 bool isSImm12Lsb00000()
const {
945 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
946 return IsConstantImm && isShiftedInt<7, 5>(Imm) &&
950 bool isSImm13Lsb0()
const {
return isBareSimmNLsb0<13>(); }
952 bool isSImm10Lsb0000NonZero()
const {
957 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
958 return IsConstantImm && (
Imm != 0) && isShiftedInt<6, 4>(Imm) &&
962 bool isUImm20LUI()
const {
968 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
969 if (!IsConstantImm) {
970 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
980 bool isUImm20AUIPC()
const {
986 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
987 if (!IsConstantImm) {
988 IsValid = RISCVAsmParser::classifySymbolRef(getImm(), VK);
1004 bool isSImm21Lsb0JAL()
const {
return isBareSimmNLsb0<21>(); }
1006 bool isImmZero()
const {
1011 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
1015 bool isSImm5Plus1()
const {
1020 bool IsConstantImm = evaluateConstantImm(getImm(), Imm, VK);
1021 return IsConstantImm &&
1022 isInt<5>(fixImmediateForRV32(Imm, isRV64Imm()) - 1) &&
1027 SMLoc getStartLoc()
const override {
return StartLoc; }
1029 SMLoc getEndLoc()
const override {
return EndLoc; }
1031 bool isRV64Imm()
const {
1032 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
1037 assert(Kind == KindTy::Register &&
"Invalid type access!");
1042 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
1043 return StringRef(SysReg.Data, SysReg.Length);
1046 const MCExpr *getImm()
const {
1047 assert(Kind == KindTy::Immediate &&
"Invalid type access!");
1052 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1057 assert(Kind == KindTy::Token &&
"Invalid type access!");
1061 unsigned getVType()
const {
1062 assert(Kind == KindTy::VType &&
"Invalid type access!");
1067 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1071 unsigned getFence()
const {
1072 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1085 case KindTy::Immediate:
1088 case KindTy::FPImmediate:
1090 case KindTy::Register:
1094 OS <<
"'" << getToken() <<
"'";
1096 case KindTy::SystemRegister:
1097 OS <<
"<sysreg: " << getSysReg() <<
'>';
1106 roundingModeToString(getFRM());
1124 case KindTy::RegReg:
1131 static std::unique_ptr<RISCVOperand> createToken(
StringRef Str,
SMLoc S) {
1132 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1139 static std::unique_ptr<RISCVOperand>
1141 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1142 Op->Reg.RegNum =
Reg.id();
1143 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1149 static std::unique_ptr<RISCVOperand> createImm(
const MCExpr *Val,
SMLoc S,
1151 auto Op = std::make_unique<RISCVOperand>(KindTy::Immediate);
1153 Op->Imm.IsRV64 = IsRV64;
1159 static std::unique_ptr<RISCVOperand> createFPImm(
uint64_t Val,
SMLoc S) {
1160 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1161 Op->FPImm.Val = Val;
1167 static std::unique_ptr<RISCVOperand> createSysReg(
StringRef Str,
SMLoc S,
1168 unsigned Encoding) {
1169 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1170 Op->SysReg.Data = Str.data();
1171 Op->SysReg.Length = Str.size();
1178 static std::unique_ptr<RISCVOperand>
1180 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1187 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val,
SMLoc S) {
1188 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1189 Op->Fence.Val = Val;
1195 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI,
SMLoc S) {
1196 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1197 Op->VType.Val = VTypeI;
1203 static std::unique_ptr<RISCVOperand> createRlist(
unsigned RlistEncode,
1205 auto Op = std::make_unique<RISCVOperand>(KindTy::Rlist);
1206 Op->Rlist.Val = RlistEncode;
1211 static std::unique_ptr<RISCVOperand> createRegReg(
MCRegister Reg1,
1213 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1214 Op->RegReg.Reg1 = Reg1.
id();
1215 Op->RegReg.Reg2 = Reg2.
id();
1221 static std::unique_ptr<RISCVOperand> createSpimm(
unsigned Spimm,
SMLoc S) {
1222 auto Op = std::make_unique<RISCVOperand>(KindTy::Spimm);
1223 Op->Spimm.Val = Spimm;
1228 static void addExpr(
MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1229 assert(Expr &&
"Expr shouldn't be null!");
1232 bool IsConstant = evaluateConstantImm(Expr, Imm, VK);
1242 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1243 assert(
N == 1 &&
"Invalid number of operands!");
1247 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1248 assert(
N == 1 &&
"Invalid number of operands!");
1249 addExpr(Inst, getImm(), isRV64Imm());
1252 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
1253 assert(
N == 1 &&
"Invalid number of operands!");
1255 addExpr(Inst, getImm(), isRV64Imm());
1260 APFloat(APFloat::IEEEdouble(),
APInt(64, getFPConst())));
1264 void addFenceArgOperands(
MCInst &Inst,
unsigned N)
const {
1265 assert(
N == 1 &&
"Invalid number of operands!");
1269 void addCSRSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
1270 assert(
N == 1 &&
"Invalid number of operands!");
1277 void addVTypeIOperands(
MCInst &Inst,
unsigned N)
const {
1278 assert(
N == 1 &&
"Invalid number of operands!");
1280 if (Kind == KindTy::Immediate) {
1282 [[maybe_unused]]
bool IsConstantImm =
1283 evaluateConstantImm(getImm(), Imm, VK);
1284 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1291 void addRlistOperands(
MCInst &Inst,
unsigned N)
const {
1292 assert(
N == 1 &&
"Invalid number of operands!");
1296 void addRegRegOperands(
MCInst &Inst,
unsigned N)
const {
1297 assert(
N == 2 &&
"Invalid number of operands!");
1302 void addSpimmOperands(
MCInst &Inst,
unsigned N)
const {
1303 assert(
N == 1 &&
"Invalid number of operands!");
1307 void addFRMArgOperands(
MCInst &Inst,
unsigned N)
const {
1308 assert(
N == 1 &&
"Invalid number of operands!");
1314#define GET_REGISTER_MATCHER
1315#define GET_SUBTARGET_FEATURE_NAME
1316#define GET_MATCHER_IMPLEMENTATION
1317#define GET_MNEMONIC_SPELL_CHECKER
1318#include "RISCVGenAsmMatcher.inc"
1321 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1322 return Reg - RISCV::F0_D + RISCV::F0_H;
1326 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1327 return Reg - RISCV::F0_D + RISCV::F0_F;
1332 unsigned RegClassID;
1333 if (Kind == MCK_VRM2)
1334 RegClassID = RISCV::VRM2RegClassID;
1335 else if (Kind == MCK_VRM4)
1336 RegClassID = RISCV::VRM4RegClassID;
1337 else if (Kind == MCK_VRM8)
1338 RegClassID = RISCV::VRM8RegClassID;
1342 &RISCVMCRegisterClasses[RegClassID]);
1347 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1349 return Match_InvalidOperand;
1353 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg);
1355 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg);
1356 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg);
1360 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1361 (IsRegFPR64C &&
Kind == MCK_FPR32C)) {
1363 return Match_Success;
1367 if (IsRegFPR64 && Kind == MCK_FPR16) {
1369 return Match_Success;
1371 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1372 Op.Reg.RegNum =
Reg - RISCV::X0 + RISCV::X0_H;
1373 return Match_Success;
1375 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1376 Op.Reg.RegNum =
Reg - RISCV::X0 + RISCV::X0_W;
1377 return Match_Success;
1384 if (RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg) &&
1385 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1387 return Match_Success;
1391 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1394 return Match_InvalidOperand;
1395 return Match_Success;
1397 return Match_InvalidOperand;
1400bool RISCVAsmParser::generateImmOutOfRangeError(
1402 const Twine &Msg =
"immediate must be an integer in the range") {
1406bool RISCVAsmParser::generateImmOutOfRangeError(
1408 const Twine &Msg =
"immediate must be an integer in the range") {
1410 return generateImmOutOfRangeError(ErrorLoc,
Lower,
Upper, Msg);
1413bool RISCVAsmParser::matchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
1417 bool MatchingInlineAsm) {
1427 if (validateInstruction(Inst,
Operands))
1429 return processInstruction(Inst, IDLoc,
Operands, Out);
1430 case Match_MissingFeature: {
1431 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1432 bool FirstFeature =
true;
1433 std::string Msg =
"instruction requires the following:";
1434 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1435 if (MissingFeatures[i]) {
1436 Msg += FirstFeature ?
" " :
", ";
1438 FirstFeature =
false;
1441 return Error(IDLoc, Msg);
1443 case Match_MnemonicFail: {
1444 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1445 std::string Suggestion = RISCVMnemonicSpellCheck(
1446 ((RISCVOperand &)*
Operands[0]).getToken(), FBS, 0);
1447 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1449 case Match_InvalidOperand: {
1450 SMLoc ErrorLoc = IDLoc;
1453 return Error(ErrorLoc,
"too few operands for instruction");
1456 if (ErrorLoc ==
SMLoc())
1459 return Error(ErrorLoc,
"invalid operand for instruction");
1466 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1467 SMLoc ErrorLoc = IDLoc;
1469 return Error(ErrorLoc,
"too few operands for instruction");
1475 case Match_InvalidImmXLenLI:
1478 return Error(ErrorLoc,
"operand must be a constant 64-bit integer");
1481 std::numeric_limits<int32_t>::min(),
1482 std::numeric_limits<uint32_t>::max());
1483 case Match_InvalidImmXLenLI_Restricted:
1486 return Error(ErrorLoc,
"operand either must be a constant 64-bit integer "
1487 "or a bare symbol name");
1489 return generateImmOutOfRangeError(
1491 std::numeric_limits<uint32_t>::max(),
1492 "operand either must be a bare symbol name or an immediate integer in "
1494 case Match_InvalidImmZero: {
1496 return Error(ErrorLoc,
"immediate must be zero");
1498 case Match_InvalidUImmLog2XLen:
1502 case Match_InvalidUImmLog2XLenNonZero:
1506 case Match_InvalidUImm1:
1508 case Match_InvalidUImm2:
1510 case Match_InvalidUImm2Lsb0:
1512 "immediate must be one of");
1513 case Match_InvalidUImm3:
1515 case Match_InvalidUImm4:
1517 case Match_InvalidUImm5:
1519 case Match_InvalidUImm5NonZero:
1521 case Match_InvalidUImm6:
1523 case Match_InvalidUImm7:
1525 case Match_InvalidUImm8:
1527 case Match_InvalidUImm8GE32:
1529 case Match_InvalidSImm5:
1532 case Match_InvalidSImm6:
1535 case Match_InvalidSImm6NonZero:
1536 return generateImmOutOfRangeError(
1538 "immediate must be non-zero in the range");
1539 case Match_InvalidCLUIImm:
1540 return generateImmOutOfRangeError(
1542 "immediate must be in [0xfffe0, 0xfffff] or");
1543 case Match_InvalidUImm5Lsb0:
1544 return generateImmOutOfRangeError(
1546 "immediate must be a multiple of 2 bytes in the range");
1547 case Match_InvalidUImm6Lsb0:
1548 return generateImmOutOfRangeError(
1550 "immediate must be a multiple of 2 bytes in the range");
1551 case Match_InvalidUImm7Lsb00:
1552 return generateImmOutOfRangeError(
1554 "immediate must be a multiple of 4 bytes in the range");
1555 case Match_InvalidUImm8Lsb00:
1556 return generateImmOutOfRangeError(
1558 "immediate must be a multiple of 4 bytes in the range");
1559 case Match_InvalidUImm8Lsb000:
1560 return generateImmOutOfRangeError(
1562 "immediate must be a multiple of 8 bytes in the range");
1563 case Match_InvalidSImm9Lsb0:
1564 return generateImmOutOfRangeError(
1566 "immediate must be a multiple of 2 bytes in the range");
1567 case Match_InvalidUImm9Lsb000:
1568 return generateImmOutOfRangeError(
1570 "immediate must be a multiple of 8 bytes in the range");
1571 case Match_InvalidUImm10Lsb00NonZero:
1572 return generateImmOutOfRangeError(
1574 "immediate must be a multiple of 4 bytes in the range");
1575 case Match_InvalidSImm10Lsb0000NonZero:
1576 return generateImmOutOfRangeError(
1578 "immediate must be a multiple of 16 bytes and non-zero in the range");
1579 case Match_InvalidUImm11:
1581 case Match_InvalidSImm12:
1582 return generateImmOutOfRangeError(
1584 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo modifier or an "
1585 "integer in the range");
1586 case Match_InvalidSImm12Lsb0:
1587 return generateImmOutOfRangeError(
1589 "immediate must be a multiple of 2 bytes in the range");
1590 case Match_InvalidSImm12Lsb00000:
1591 return generateImmOutOfRangeError(
1593 "immediate must be a multiple of 32 bytes in the range");
1594 case Match_InvalidSImm13Lsb0:
1595 return generateImmOutOfRangeError(
1597 "immediate must be a multiple of 2 bytes in the range");
1598 case Match_InvalidUImm20LUI:
1600 "operand must be a symbol with "
1601 "%hi/%tprel_hi modifier or an integer in "
1603 case Match_InvalidUImm20:
1605 case Match_InvalidUImm20AUIPC:
1606 return generateImmOutOfRangeError(
1608 "operand must be a symbol with a "
1609 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi modifier or "
1610 "an integer in the range");
1611 case Match_InvalidSImm21Lsb0JAL:
1612 return generateImmOutOfRangeError(
1614 "immediate must be a multiple of 2 bytes in the range");
1615 case Match_InvalidCSRSystemRegister: {
1617 "operand must be a valid system register "
1618 "name or an integer in the range");
1620 case Match_InvalidLoadFPImm: {
1622 return Error(ErrorLoc,
"operand must be a valid floating-point constant");
1624 case Match_InvalidBareSymbol: {
1626 return Error(ErrorLoc,
"operand must be a bare symbol name");
1628 case Match_InvalidPseudoJumpSymbol: {
1630 return Error(ErrorLoc,
"operand must be a valid jump target");
1632 case Match_InvalidCallSymbol: {
1634 return Error(ErrorLoc,
"operand must be a bare symbol name");
1636 case Match_InvalidTPRelAddSymbol: {
1638 return Error(ErrorLoc,
"operand must be a symbol with %tprel_add modifier");
1640 case Match_InvalidTLSDESCCallSymbol: {
1642 return Error(ErrorLoc,
1643 "operand must be a symbol with %tlsdesc_call modifier");
1645 case Match_InvalidRTZArg: {
1647 return Error(ErrorLoc,
"operand must be 'rtz' floating-point rounding mode");
1649 case Match_InvalidVTypeI: {
1651 return generateVTypeError(ErrorLoc);
1653 case Match_InvalidVMaskRegister: {
1655 return Error(ErrorLoc,
"operand must be v0.t");
1657 case Match_InvalidSImm5Plus1: {
1660 "immediate must be in the range");
1662 case Match_InvalidRlist: {
1666 "operand must be {ra [, s0[-sN]]} or {x1 [, x8[-x9][, x18[-xN]]]}");
1668 case Match_InvalidStackAdj: {
1672 "stack adjustment is invalid for this instruction and register list; "
1673 "refer to Zc spec for a detailed range of stack adjustment");
1675 case Match_InvalidRnumArg: {
1678 case Match_InvalidRegReg: {
1680 return Error(ErrorLoc,
"operands must be register and register");
1698 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1699 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1702 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1709 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1710 return Error(StartLoc,
"invalid register name");
1716 const AsmToken &Tok = getParser().getTok();
1731 SMLoc FirstS = getLoc();
1732 bool HadParens =
false;
1739 size_t ReadCount = getLexer().peekTokens(Buf);
1742 LParen = getParser().getTok();
1747 switch (getLexer().getKind()) {
1750 getLexer().UnLex(LParen);
1758 getLexer().UnLex(LParen);
1762 Operands.push_back(RISCVOperand::createToken(
"(", FirstS));
1766 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
1771 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
1782 switch (getLexer().getKind()) {
1792 if (getParser().parseExpression(Res,
E))
1795 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1797 int64_t
Imm =
CE->getValue();
1798 if (isUInt<7>(Imm)) {
1799 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1808 if (getParser().parseIdentifier(Identifier))
1811 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1813 assert(isUInt<7>(Opcode->Value) && (Opcode->Value & 0x3) == 3 &&
1814 "Unexpected opcode");
1817 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1827 return generateImmOutOfRangeError(
1829 "opcode must be a valid opcode name or an immediate in the range");
1837 switch (getLexer().getKind()) {
1847 if (getParser().parseExpression(Res,
E))
1850 auto *
CE = dyn_cast<MCConstantExpr>(Res);
1852 int64_t
Imm =
CE->getValue();
1853 if (Imm >= 0 && Imm <= 2) {
1854 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1863 if (getParser().parseIdentifier(Identifier))
1867 if (Identifier ==
"C0")
1869 else if (Identifier ==
"C1")
1871 else if (Identifier ==
"C2")
1878 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
1887 return generateImmOutOfRangeError(
1889 "opcode must be a valid opcode name or an immediate in the range");
1896 auto SysRegFromConstantInt = [
this](
const MCExpr *
E,
SMLoc S) {
1897 if (
auto *CE = dyn_cast<MCConstantExpr>(
E)) {
1898 int64_t
Imm =
CE->getValue();
1899 if (isUInt<12>(Imm)) {
1900 auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
1905 return RISCVOperand::createSysReg(
Reg.Name, S, Imm);
1909 return RISCVOperand::createSysReg(
"", S, Imm);
1912 return std::unique_ptr<RISCVOperand>();
1915 switch (getLexer().getKind()) {
1925 if (getParser().parseExpression(Res))
1928 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
1929 Operands.push_back(std::move(SysOpnd));
1933 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1937 if (getParser().parseIdentifier(Identifier))
1940 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1942 SysReg = RISCVSysReg::lookupSysRegByAltName(Identifier);
1944 if ((SysReg = RISCVSysReg::lookupSysRegByDeprecatedName(Identifier)))
1945 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
1946 SysReg->Name +
"'");
1950 const auto &FeatureBits = getSTI().getFeatureBits();
1951 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
1953 return SysReg->FeaturesRequired[Feature.Value];
1955 auto ErrorMsg = std::string(
"system register '") + SysReg->Name +
"' ";
1956 if (SysReg->isRV32Only && FeatureBits[RISCV::Feature64Bit]) {
1957 ErrorMsg +=
"is RV32 only";
1959 ErrorMsg +=
" and ";
1963 "requires '" + std::string(Feature->Key) +
"' to be enabled";
1966 return Error(S, ErrorMsg);
1969 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
1974 MCSymbol *
Sym = getContext().lookupSymbol(Identifier);
1975 if (
Sym &&
Sym->isVariable()) {
1978 if (
auto SysOpnd = SysRegFromConstantInt(
1979 Sym->getVariableValue(
false), S)) {
1980 Operands.push_back(std::move(SysOpnd));
1985 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
1986 "operand must be a valid system register "
1987 "name or an integer in the range");
1991 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2004 if (
Identifier.compare_insensitive(
"inf") == 0) {
2007 getTok().getEndLoc(), isRV64()));
2008 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2011 getTok().getEndLoc(), isRV64()));
2012 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2015 getTok().getEndLoc(), isRV64()));
2017 return TokError(
"invalid floating point literal");
2030 return TokError(
"invalid floating point immediate");
2033 APFloat RealVal(APFloat::IEEEdouble());
2035 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2037 return TokError(
"invalid floating point representation");
2040 RealVal.changeSign();
2042 Operands.push_back(RISCVOperand::createFPImm(
2043 RealVal.bitcastToAPInt().getZExtValue(), S));
2055 switch (getLexer().getKind()) {
2067 if (getParser().parseExpression(Res,
E))
2071 return parseOperandWithModifier(
Operands);
2074 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2086 return Error(getLoc(),
"expected valid identifier for operand modifier");
2090 return Error(getLoc(),
"unrecognized operand modifier");
2097 if (getParser().parseParenExpression(SubExpr,
E))
2101 Operands.push_back(RISCVOperand::createImm(ModExpr, S,
E, isRV64()));
2113 AsmToken Tok = getLexer().getTok();
2115 if (getParser().parseIdentifier(Identifier))
2121 return Error(getLoc(),
"'@plt' operand not valid for instruction");
2123 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
2125 if (
Sym->isVariable()) {
2126 const MCExpr *
V =
Sym->getVariableValue(
false);
2127 if (!isa<MCSymbolRefExpr>(V)) {
2128 getLexer().UnLex(Tok);
2136 switch (getLexer().getKind()) {
2138 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2151 if (getParser().parseExpression(Expr,
E))
2154 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2170 if (getParser().parseIdentifier(Identifier))
2178 MCSymbol *
Sym = getContext().getOrCreateSymbol(Identifier);
2181 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2190 if (getParser().parseExpression(Res,
E))
2193 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef ||
2194 cast<MCSymbolRefExpr>(Res)->getKind() ==
2195 MCSymbolRefExpr::VariantKind::VK_PLT)
2196 return Error(S,
"operand must be a valid jump target");
2199 Operands.push_back(RISCVOperand::createImm(Res, S,
E, isRV64()));
2220bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2221 unsigned &Sew,
unsigned &Lmul,
2222 bool &Fractional,
bool &TailAgnostic,
2223 bool &MaskAgnostic) {
2230 case VTypeState_SEW:
2237 State = VTypeState_LMUL;
2239 case VTypeState_LMUL: {
2249 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2250 unsigned MinLMUL = ELEN / 8;
2253 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2254 Twine(MinLMUL) +
" is reserved");
2257 State = VTypeState_TailPolicy;
2260 case VTypeState_TailPolicy:
2261 if (Identifier ==
"ta")
2262 TailAgnostic =
true;
2263 else if (Identifier ==
"tu")
2264 TailAgnostic =
false;
2267 State = VTypeState_MaskPolicy;
2269 case VTypeState_MaskPolicy:
2270 if (Identifier ==
"ma")
2271 MaskAgnostic =
true;
2272 else if (Identifier ==
"mu")
2273 MaskAgnostic =
false;
2276 State = VTypeState_Done;
2278 case VTypeState_Done:
2291 bool Fractional =
false;
2292 bool TailAgnostic =
false;
2293 bool MaskAgnostic =
false;
2295 VTypeState State = VTypeState_SEW;
2298 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2305 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2315 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2316 unsigned MaxSEW = ELEN / Lmul;
2318 if (MaxSEW >= 8 && Sew > MaxSEW)
2320 "use of vtype encodings with SEW > " +
Twine(MaxSEW) +
2321 " and LMUL == mf" +
Twine(Lmul) +
2322 " may not be compatible with all RVV implementations");
2327 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2331 return generateVTypeError(S);
2334bool RISCVAsmParser::generateVTypeError(
SMLoc ErrorLoc) {
2338 "e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2346 if (!
Name.consume_back(
".t"))
2347 return Error(getLoc(),
"expected '.t' suffix");
2352 if (
Reg != RISCV::V0)
2357 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2362 if (!isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2380 Operands.push_back(RISCVOperand::createReg(
2381 Reg, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2386 if (isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2398 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2401 if ((
Reg - RISCV::X0) & 1) {
2404 if (getSTI().hasFeature(RISCV::FeatureStdExtZfinx))
2405 return TokError(
"double precision floating point operands must use even "
2406 "numbered X register");
2416 Reg, RISCV::sub_gpr_even,
2417 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2418 Operands.push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2422template <
bool IsRV64>
2424 return parseGPRPair(
Operands, IsRV64);
2434 if (!IsRV64Inst && isRV64())
2446 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2449 if ((
Reg - RISCV::X0) & 1)
2450 return TokError(
"register must be even");
2458 Reg, RISCV::sub_gpr_even,
2459 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2460 Operands.push_back(RISCVOperand::createReg(Pair, S,
E));
2467 "operand must be a valid floating point rounding mode mnemonic");
2469 StringRef Str = getLexer().getTok().getIdentifier();
2474 "operand must be a valid floating point rounding mode mnemonic");
2476 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2482 const AsmToken &Tok = getLexer().getTok();
2488 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2502 for (
char c : Str) {
2531 Operands.push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2537 return TokError(
"operand must be formed of letters selected in-order from "
2544 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
2546 if (!parseRegister(
Operands).isSuccess())
2547 return Error(getLoc(),
"expected register");
2551 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2575 std::unique_ptr<RISCVOperand> OptionalImmOp;
2582 SMLoc ImmStart = getLoc();
2583 if (getParser().parseIntToken(ImmVal,
2584 "expected '(' or optional integer offset"))
2589 SMLoc ImmEnd = getLoc();
2592 ImmStart, ImmEnd, isRV64());
2596 OptionalImmOp ?
"expected '(' after optional integer offset"
2597 :
"expected '(' or optional integer offset"))
2600 if (!parseRegister(
Operands).isSuccess())
2601 return Error(getLoc(),
"expected register");
2607 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2609 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2610 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2623 return Error(getLoc(),
"invalid register");
2630 return Error(getLoc(),
"expected register");
2632 StringRef Reg2Name = getLexer().getTok().getIdentifier();
2635 return Error(getLoc(),
"invalid register");
2641 Operands.push_back(RISCVOperand::createRegReg(
Reg, Reg2, getLoc()));
2654 bool IsEABI = isRVE();
2657 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2662 if (RegStart != RISCV::X1)
2663 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2669 return Error(getLoc(),
"invalid register");
2673 return Error(getLoc(),
"invalid register");
2674 if (RegStart != RISCV::X8)
2675 return Error(getLoc(),
2676 "continuous register list must start from 's0' or 'x8'");
2682 StringRef EndName = getLexer().getTok().getIdentifier();
2686 return Error(getLoc(),
"invalid register");
2687 if (IsEABI && RegEnd != RISCV::X9)
2688 return Error(getLoc(),
"contiguous register list of EABI can only be "
2689 "'s0-s1' or 'x8-x9' pair");
2696 if (RegEnd != RISCV::X9)
2699 "first contiguous registers pair of register list must be 'x8-x9'");
2703 return Error(getLoc(),
"invalid register");
2704 StringRef EndName = getLexer().getTok().getIdentifier();
2706 return Error(getLoc(),
2707 "second contiguous registers pair of register list "
2708 "must start from 'x18'");
2714 return Error(getLoc(),
"invalid register");
2715 EndName = getLexer().getTok().getIdentifier();
2717 return Error(getLoc(),
"invalid register");
2724 if (RegEnd == RISCV::X26)
2725 return Error(getLoc(),
"invalid register list, {ra, s0-s10} or {x1, x8-x9, "
2726 "x18-x26} is not supported");
2736 return Error(S,
"invalid register list");
2737 Operands.push_back(RISCVOperand::createRlist(Encode, S));
2743 bool ExpectNegative) {
2749 unsigned RlistVal =
static_cast<RISCVOperand *
>(
Operands[1].get())->Rlist.Val;
2751 if (Negative != ExpectNegative ||
2754 Operands.push_back(RISCVOperand::createSpimm(Spimm << 4, S));
2766 MatchOperandParserImpl(
Operands, Mnemonic,
true);
2773 if (parseRegister(
Operands,
true).isSuccess())
2780 return !parseMemOpBaseReg(
Operands).isSuccess();
2785 Error(getLoc(),
"unknown operand");
2798 if (getSTI().hasFeature(RISCV::FeatureRelax)) {
2799 auto *Assembler = getTargetStreamer().getStreamer().getAssemblerPtr();
2800 if (Assembler !=
nullptr) {
2808 Operands.push_back(RISCVOperand::createToken(
Name, NameLoc));
2827 if (getParser().parseEOL(
"unexpected token")) {
2828 getParser().eatToEndOfStatement();
2834bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
2838 if (
const RISCVMCExpr *RE = dyn_cast<RISCVMCExpr>(Expr)) {
2839 Kind = RE->getKind();
2840 Expr = RE->getSubExpr();
2850bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
2863 if (IDVal ==
".option")
2864 return parseDirectiveOption();
2865 if (IDVal ==
".attribute")
2866 return parseDirectiveAttribute();
2867 if (IDVal ==
".insn")
2868 return parseDirectiveInsn(DirectiveID.
getLoc());
2869 if (IDVal ==
".variant_cc")
2870 return parseDirectiveVariantCC();
2875bool RISCVAsmParser::resetToArch(
StringRef Arch,
SMLoc Loc, std::string &Result,
2876 bool FromOptionDirective) {
2879 clearFeatureBits(Feature.Value, Feature.Key);
2888 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
2889 << ErrMsg.getMessage();
2892 return Error(Loc, OutputErrMsg.str());
2897 if (ISAInfo->hasExtension(Feature.Key))
2898 setFeatureBits(Feature.Value, Feature.Key);
2900 if (FromOptionDirective) {
2901 if (ISAInfo->getXLen() == 32 && isRV64())
2902 return Error(Loc,
"bad arch string switching from rv64 to rv32");
2903 else if (ISAInfo->getXLen() == 64 && !isRV64())
2904 return Error(Loc,
"bad arch string switching from rv32 to rv64");
2907 if (ISAInfo->getXLen() == 32)
2908 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
2909 else if (ISAInfo->getXLen() == 64)
2910 setFeatureBits(RISCV::Feature64Bit,
"64bit");
2912 return Error(Loc,
"bad arch string " + Arch);
2914 Result = ISAInfo->toString();
2918bool RISCVAsmParser::parseDirectiveOption() {
2929 if (Option ==
"push") {
2933 getTargetStreamer().emitDirectiveOptionPush();
2938 if (Option ==
"pop") {
2943 getTargetStreamer().emitDirectiveOptionPop();
2944 if (popFeatureBits())
2945 return Error(StartLoc,
".option pop with no .option push");
2950 if (Option ==
"arch") {
2958 Type = RISCVOptionArchArgType::Plus;
2960 Type = RISCVOptionArchArgType::Minus;
2961 else if (!
Args.empty())
2963 "unexpected token, expected + or -");
2965 Type = RISCVOptionArchArgType::Full;
2969 "unexpected token, expected identifier");
2975 if (
Type == RISCVOptionArchArgType::Full) {
2977 if (resetToArch(Arch, Loc, Result,
true))
2986 Loc,
"extension version number parsing not currently implemented");
2989 if (!enableExperimentalExtension() &&
2991 return Error(Loc,
"unexpected experimental extensions");
2994 return Error(Loc,
"unknown extension feature");
2998 if (
Type == RISCVOptionArchArgType::Plus) {
3001 setFeatureBits(
Ext->Value,
Ext->Key);
3004 copySTI().setFeatureBits(OldFeatureBits);
3005 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3010 OutputErrMsg << ErrMsg.getMessage();
3013 return Error(Loc, OutputErrMsg.str());
3016 assert(
Type == RISCVOptionArchArgType::Minus);
3021 if (getSTI().hasFeature(Feature.Value) &&
3022 Feature.Implies.test(
Ext->Value))
3024 " extension; " + Feature.Key +
3025 " extension requires " +
Ext->Key +
3029 clearFeatureBits(
Ext->Value,
Ext->Key);
3036 getTargetStreamer().emitDirectiveOptionArch(Args);
3040 if (Option ==
"rvc") {
3044 getTargetStreamer().emitDirectiveOptionRVC();
3045 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3049 if (Option ==
"norvc") {
3053 getTargetStreamer().emitDirectiveOptionNoRVC();
3054 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3055 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3059 if (Option ==
"pic") {
3063 getTargetStreamer().emitDirectiveOptionPIC();
3064 ParserOptions.IsPicEnabled =
true;
3068 if (Option ==
"nopic") {
3072 getTargetStreamer().emitDirectiveOptionNoPIC();
3073 ParserOptions.IsPicEnabled =
false;
3077 if (Option ==
"relax") {
3081 getTargetStreamer().emitDirectiveOptionRelax();
3082 setFeatureBits(RISCV::FeatureRelax,
"relax");
3086 if (Option ==
"norelax") {
3090 getTargetStreamer().emitDirectiveOptionNoRelax();
3091 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3097 "'rvc', 'norvc', 'arch', 'relax' or "
3106bool RISCVAsmParser::parseDirectiveAttribute() {
3113 std::optional<unsigned>
Ret =
3116 return Error(TagLoc,
"attribute name not recognised: " +
Name);
3127 if (check(!CE, TagLoc,
"expected numeric constant"))
3130 Tag =
CE->getValue();
3137 int64_t IntegerValue = 0;
3138 bool IsIntegerValue =
true;
3143 IsIntegerValue =
false;
3146 if (IsIntegerValue) {
3153 return Error(ValueExprLoc,
"expected numeric constant");
3154 IntegerValue =
CE->getValue();
3167 getTargetStreamer().emitAttribute(Tag, IntegerValue);
3169 getTargetStreamer().emitTextAttribute(Tag, StringValue);
3172 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3176 getTargetStreamer().emitTextAttribute(Tag, Result);
3184 .
Cases(
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s",
true)
3185 .
Cases(
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj", AllowC)
3193bool RISCVAsmParser::parseDirectiveInsn(
SMLoc L) {
3196 bool AllowC = getSTI().hasFeature(RISCV::FeatureStdExtC) ||
3197 getSTI().hasFeature(RISCV::FeatureStdExtZca);
3204 std::optional<int64_t>
Length;
3214 return Error(ErrorLoc,
3215 "instruction lengths must be a non-zero multiple of two");
3219 return Error(ErrorLoc,
3220 "instruction lengths over 64 bits are not supported");
3226 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3231 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3232 return Error(ErrorLoc,
3233 "instruction length does not match the encoding");
3236 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3239 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3242 if (!AllowC && (EncodingDerivedLength == 2))
3243 return Error(ErrorLoc,
"compressed instructions are not allowed");
3245 if (getParser().parseEOL(
"invalid operand for instruction")) {
3246 getParser().eatToEndOfStatement();
3254 Opcode = RISCV::Insn16;
3257 Opcode = RISCV::Insn32;
3260 Opcode = RISCV::Insn48;
3263 Opcode = RISCV::Insn64;
3269 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3276 return Error(ErrorLoc,
"invalid instruction format");
3278 std::string FormatName = (
".insn_" +
Format).str();
3295bool RISCVAsmParser::parseDirectiveVariantCC() {
3297 if (getParser().parseIdentifier(
Name))
3298 return TokError(
"expected symbol name");
3301 getTargetStreamer().emitDirectiveVariantCC(
3302 *getContext().getOrCreateSymbol(
Name));
3310 ++RISCVNumInstrsCompressed;
3319 for (
MCInst &Inst : Seq) {
3320 emitToStreamer(Out, Inst);
3327 unsigned SecondOpcode,
SMLoc IDLoc,
3341 const MCExpr *RefToLinkTmpLabel =
3348 .addExpr(RefToLinkTmpLabel));
3351void RISCVAsmParser::emitLoadLocalAddress(
MCInst &Inst,
SMLoc IDLoc,
3362 RISCV::ADDI, IDLoc, Out);
3365void RISCVAsmParser::emitLoadGlobalAddress(
MCInst &Inst,
SMLoc IDLoc,
3375 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3377 SecondOpcode, IDLoc, Out);
3380void RISCVAsmParser::emitLoadAddress(
MCInst &Inst,
SMLoc IDLoc,
3389 if (ParserOptions.IsPicEnabled)
3390 emitLoadGlobalAddress(Inst, IDLoc, Out);
3392 emitLoadLocalAddress(Inst, IDLoc, Out);
3395void RISCVAsmParser::emitLoadTLSIEAddress(
MCInst &Inst,
SMLoc IDLoc,
3405 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3407 SecondOpcode, IDLoc, Out);
3410void RISCVAsmParser::emitLoadTLSGDAddress(
MCInst &Inst,
SMLoc IDLoc,
3421 RISCV::ADDI, IDLoc, Out);
3424void RISCVAsmParser::emitLoadStoreSymbol(
MCInst &Inst,
unsigned Opcode,
3434 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3436 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3440 Opcode, IDLoc, Out);
3443void RISCVAsmParser::emitPseudoExtend(
MCInst &Inst,
bool SignExtend,
3444 int64_t Width,
SMLoc IDLoc,
3456 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3457 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3459 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3472void RISCVAsmParser::emitVMSGE(
MCInst &Inst,
unsigned Opcode,
SMLoc IDLoc,
3496 "The destination register should not be V0.");
3515 "The destination register should be V0.");
3517 "The temporary vector register should not be V0.");
3536 "The temporary vector register should not be V0.");
3561bool RISCVAsmParser::checkPseudoAddTPRel(
MCInst &Inst,
3563 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3566 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3567 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3568 "%tprel_add modifier");
3574bool RISCVAsmParser::checkPseudoTLSDESCCall(
MCInst &Inst,
3576 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
3579 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
3580 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
3581 "%tlsdesc_call modifier");
3587std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3591std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3592 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3596std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3597 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3601bool RISCVAsmParser::validateInstruction(
MCInst &Inst,
3605 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3606 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3609 if (DestReg == TempReg) {
3611 return Error(Loc,
"the temporary vector register cannot be the same as "
3612 "the destination register");
3616 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3617 Opcode == RISCV::TH_LWD) {
3622 if (Rs1 == Rd1 && Rs1 == Rd2) {
3624 return Error(Loc,
"rs1, rd1, and rd2 cannot all be the same");
3628 if (Opcode == RISCV::CM_MVSA01) {
3633 return Error(Loc,
"rs1 and rs2 must be different");
3637 bool IsTHeadMemPair32 = (Opcode == RISCV::TH_LWD ||
3638 Opcode == RISCV::TH_LWUD || Opcode == RISCV::TH_SWD);
3639 bool IsTHeadMemPair64 = (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_SDD);
3644 return Error(Loc,
"operand must be constant 3");
3647 return Error(Loc,
"operand must be constant 4");
3654 if (Opcode == RISCV::VC_V_XVW || Opcode == RISCV::VC_V_IVW ||
3655 Opcode == RISCV::VC_V_FVW || Opcode == RISCV::VC_V_VVW) {
3661 if (VCIXDst == VCIXRs1)
3662 return Error(VCIXDstLoc,
"the destination vector register group cannot"
3663 " overlap the source vector register group");
3667 if (VCIXDst == VCIXRs2)
3668 return Error(VCIXDstLoc,
"the destination vector register group cannot"
3669 " overlap the source vector register group");
3684 if (DestReg == CheckReg)
3685 return Error(Loc,
"the destination vector register group cannot overlap"
3686 " the source vector register group");
3690 if (DestReg == CheckReg)
3691 return Error(Loc,
"the destination vector register group cannot overlap"
3692 " the source vector register group");
3697 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM ||
3698 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM ||
3699 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM ||
3700 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM ||
3701 Opcode == RISCV::VMERGE_VXM)
3702 return Error(Loc,
"the destination vector register group cannot be V0");
3709 assert((CheckReg == RISCV::V0 || !CheckReg) &&
3710 "Unexpected register for mask operand");
3712 if (DestReg == CheckReg)
3713 return Error(Loc,
"the destination vector register group cannot overlap"
3714 " the mask register");
3719bool RISCVAsmParser::processInstruction(
MCInst &Inst,
SMLoc IDLoc,
3727 case RISCV::PseudoC_ADDI_NOP:
3730 case RISCV::PseudoLLAImm:
3731 case RISCV::PseudoLAImm:
3732 case RISCV::PseudoLI: {
3749 Imm = SignExtend64<32>(Imm);
3750 emitLoadImm(
Reg, Imm, Out);
3753 case RISCV::PseudoLLA:
3754 emitLoadLocalAddress(Inst, IDLoc, Out);
3756 case RISCV::PseudoLGA:
3757 emitLoadGlobalAddress(Inst, IDLoc, Out);
3759 case RISCV::PseudoLA:
3760 emitLoadAddress(Inst, IDLoc, Out);
3762 case RISCV::PseudoLA_TLS_IE:
3763 emitLoadTLSIEAddress(Inst, IDLoc, Out);
3765 case RISCV::PseudoLA_TLS_GD:
3766 emitLoadTLSGDAddress(Inst, IDLoc, Out);
3768 case RISCV::PseudoLB:
3769 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
3771 case RISCV::PseudoLBU:
3772 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
3774 case RISCV::PseudoLH:
3775 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
3777 case RISCV::PseudoLHU:
3778 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
3780 case RISCV::PseudoLW:
3781 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
3783 case RISCV::PseudoLWU:
3784 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
3786 case RISCV::PseudoLD:
3787 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
3789 case RISCV::PseudoFLH:
3790 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
3792 case RISCV::PseudoFLW:
3793 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
3795 case RISCV::PseudoFLD:
3796 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
3798 case RISCV::PseudoSB:
3799 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
3801 case RISCV::PseudoSH:
3802 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
3804 case RISCV::PseudoSW:
3805 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
3807 case RISCV::PseudoSD:
3808 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
3810 case RISCV::PseudoFSH:
3811 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
3813 case RISCV::PseudoFSW:
3814 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
3816 case RISCV::PseudoFSD:
3817 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
3819 case RISCV::PseudoAddTPRel:
3820 if (checkPseudoAddTPRel(Inst,
Operands))
3823 case RISCV::PseudoTLSDESCCall:
3824 if (checkPseudoTLSDESCCall(Inst,
Operands))
3827 case RISCV::PseudoSEXT_B:
3828 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
3830 case RISCV::PseudoSEXT_H:
3831 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
3833 case RISCV::PseudoZEXT_H:
3834 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
3836 case RISCV::PseudoZEXT_W:
3837 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
3839 case RISCV::PseudoVMSGEU_VX:
3840 case RISCV::PseudoVMSGEU_VX_M:
3841 case RISCV::PseudoVMSGEU_VX_M_T:
3842 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
3844 case RISCV::PseudoVMSGE_VX:
3845 case RISCV::PseudoVMSGE_VX_M:
3846 case RISCV::PseudoVMSGE_VX_M_T:
3847 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
3849 case RISCV::PseudoVMSGE_VI:
3850 case RISCV::PseudoVMSLT_VI: {
3854 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
3864 case RISCV::PseudoVMSGEU_VI:
3865 case RISCV::PseudoVMSLTU_VI: {
3872 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3883 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
3898 emitToStreamer(Out, Inst);
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
static MCDisassembler::DecodeStatus addOperand(MCInst &Inst, const MCOperand &Opnd)
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
static MCRegister MatchRegisterAltName(StringRef Name)
Maps from the set of all alternative registernames to a register number.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Analysis containing CSE Info
static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, MCRegister &Reg, StringRef Name)
#define LLVM_EXTERNAL_VISIBILITY
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
mir Rename Register Operands
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
PowerPC TLS Dynamic Call Fixup
bool isValidInsnFormat(StringRef Format, bool AllowC)
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser()
static MCRegister convertFPR64ToFPR32(MCRegister Reg)
static cl::opt< bool > AddBuildAttributes("riscv-add-build-attributes", cl::init(false))
static MCRegister convertFPR64ToFPR16(MCRegister Reg)
static MCRegister convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg, unsigned Kind)
static bool isDigit(const char C)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
bool parseImmediate(MCInst &MI, uint64_t &Size, ArrayRef< uint8_t > Bytes)
Class for arbitrary precision integers.
Target independent representation for an assembler token.
int64_t getIntVal() const
bool isNot(TokenKind K) const
StringRef getString() const
Get the string for the current token, this includes all characters (for example, the quotes on string...
StringRef getStringContents() const
Get the contents of a string token (without quotes).
bool is(TokenKind K) const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
This class represents an Operation in the Expression.
Encoding
Size and signedness of expression operations' operands.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Container class for subtarget features.
constexpr size_t size() const
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
MCStreamer & getStreamer()
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
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 bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
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 MCAssembler *Asm, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
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 createExpr(const MCExpr *Val)
static MCOperand createReg(MCRegister Reg)
static MCOperand createImm(int64_t Val)
MCRegister 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.
constexpr unsigned id() const
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.
virtual bool parseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
Parse one assembly instruction.
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
virtual bool matchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
Recognize a series of operands of a parsed instruction as an actual MCInst and emit it to the specifi...
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...
Target specific streamer interface.
This represents an "assembler immediate".
uint32_t getRefKind() const
const MCSymbolRefExpr * getSymB() const
const MCSymbolRefExpr * getSymA() const
This class represents success/failure for parsing-like operations that find it important to chain tog...
Ternary parse status returned by various parse* methods.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
static bool isSupportedExtensionFeature(StringRef Ext)
static std::string getTargetFeatureForExtension(StringRef Ext)
static llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseArchString(StringRef Arch, bool EnableExperimentalExtension, bool ExperimentalExtensionVersionCheck=true)
Parse RISC-V ISA info from arch string.
static const char * getRegisterName(MCRegister Reg)
static const RISCVMCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx)
@ VK_RISCV_TLSDESC_ADD_LO
@ VK_RISCV_TLSDESC_LOAD_LO
static VariantKind getVariantKindForName(StringRef name)
Wrapper class representing virtual and physical registers.
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
Represents a range in source code.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class wraps a string in an Error.
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
char back() const
back - Get the last character in the string.
A switch()-like statement whose cases are string literals.
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
uint16_t StackAdjustment(const RuntimeFunction &RF)
StackAdjustment - calculated stack adjustment in words.
std::optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)
ABI computeTargetABI(const Triple &TT, const FeatureBitset &FeatureBits, StringRef ABIName)
const TagNameMap & getRISCVAttributeTags()
static RoundingMode stringToRoundingMode(StringRef Str)
llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseFeatureBits(bool IsRV64, const FeatureBitset &FeatureBits)
int getLoadFPImm(APFloat FPImm)
getLoadFPImm - Return a 5-bit binary encoding of the floating-point immediate value.
void generateMCInstSeq(int64_t Val, const MCSubtargetInfo &STI, MCRegister DestReg, SmallVectorImpl< MCInst > &Insts)
bool compress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI)
static bool isValidLMUL(unsigned LMUL, bool Fractional)
static RISCVII::VLMUL encodeLMUL(unsigned LMUL, bool Fractional)
static bool isValidSEW(unsigned SEW)
void printVType(unsigned VType, raw_ostream &OS)
unsigned encodeVTYPE(RISCVII::VLMUL VLMUL, unsigned SEW, bool TailAgnostic, bool MaskAgnostic)
unsigned encodeRlist(MCRegister EndReg, bool IsRV32E=false)
void printRlist(unsigned SlistEncode, raw_ostream &OS)
static bool getSpimm(unsigned RlistVal, unsigned &SpimmVal, int64_t StackAdjustment, bool IsRV64)
@ CE
Windows NT (Windows on ARM)
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Target & getTheRISCV32Target()
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
DWARFExpression::Operation Op
Target & getTheRISCV64Target()
constexpr bool isShiftedInt(int64_t x)
Checks if a signed integer is an N bit number shifted left by S.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
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.