49#define DEBUG_TYPE "riscv-asm-parser"
52 "Number of RISC-V Compressed instructions emitted");
64struct ParserOptionsSet {
71 enum class VTypeState {
82 ParserOptionsSet ParserOptions;
84 SMLoc getLoc()
const {
return getParser().
getTok().
getLoc(); }
85 bool isRV64()
const {
return getSTI().hasFeature(RISCV::Feature64Bit); }
86 bool isRVE()
const {
return getSTI().hasFeature(RISCV::FeatureStdExtE); }
87 bool enableExperimentalExtension()
const {
88 return getSTI().hasFeature(RISCV::Experimental);
91 RISCVTargetStreamer &getTargetStreamer() {
92 assert(getParser().getStreamer().getTargetStreamer() &&
93 "do not have a target streamer");
94 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
95 return static_cast<RISCVTargetStreamer &
>(TS);
98 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
99 unsigned Kind)
override;
101 bool generateImmOutOfRangeError(
OperandVector &Operands, uint64_t ErrorInfo,
104 bool generateImmOutOfRangeError(SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
107 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
110 bool MatchingInlineAsm)
override;
113 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
114 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
115 SMLoc &EndLoc)
override;
117 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
120 ParseStatus parseDirective(AsmToken DirectiveID)
override;
122 bool parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
unsigned &Sew,
123 unsigned &Lmul,
bool &Fractional,
bool &TailAgnostic,
124 bool &MaskAgnostic,
bool &AltFmt);
125 bool generateVTypeError(SMLoc ErrorLoc);
127 bool generateXSfmmVTypeError(SMLoc ErrorLoc);
130 void emitToStreamer(MCStreamer &S,
const MCInst &Inst);
134 void emitLoadImm(MCRegister DestReg, int64_t
Value, MCStreamer &Out);
138 void emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
140 unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out);
143 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
146 void emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
149 void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
153 void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
157 void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
160 void emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
161 MCStreamer &Out,
bool HasTmpReg);
166 void emitQCELILoadStoreSymbol(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
167 MCStreamer &Out,
bool HasTmpReg);
170 void emitPseudoExtend(MCInst &Inst,
bool SignExtend, int64_t Width,
171 SMLoc IDLoc, MCStreamer &Out);
174 void emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc, MCStreamer &Out);
180 bool checkPseudoAddTPRel(MCInst &Inst,
OperandVector &Operands);
186 bool checkPseudoTLSDESCCall(MCInst &Inst,
OperandVector &Operands);
189 bool validateInstruction(MCInst &Inst,
OperandVector &Operands);
195 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
OperandVector &Operands,
199#define GET_ASSEMBLER_HEADER
200#include "RISCVGenAsmMatcher.inc"
228 return parseRegList(Operands,
true);
234 bool ExpectNegative =
false);
236 return parseZcmpStackAdj(Operands,
true);
239 bool parseOperand(
OperandVector &Operands, StringRef Mnemonic);
240 bool parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
241 bool parseDataExpr(
const MCExpr *&Res)
override;
243 bool parseDirectiveOption();
244 bool parseDirectiveAttribute();
245 bool parseDirectiveInsn(SMLoc L);
246 bool parseDirectiveVariantCC();
251 bool resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
252 bool FromOptionDirective);
254 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
255 if (!(getSTI().hasFeature(Feature))) {
256 MCSubtargetInfo &STI = copySTI();
262 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
266 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
267 if (getSTI().hasFeature(Feature)) {
268 MCSubtargetInfo &STI = copySTI();
269 setAvailableFeatures(
274 void pushFeatureBits() {
275 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
276 "These two stacks must be kept synchronized");
277 FeatureBitStack.push_back(getSTI().getFeatureBits());
278 ParserOptionsStack.push_back(ParserOptions);
281 bool popFeatureBits() {
282 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
283 "These two stacks must be kept synchronized");
284 if (FeatureBitStack.empty())
287 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
288 copySTI().setFeatureBits(FeatureBits);
289 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
291 ParserOptions = ParserOptionsStack.pop_back_val();
296 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
297 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
298 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
301 enum RISCVMatchResultTy :
unsigned {
302 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
303#define GET_OPERAND_DIAGNOSTIC_TYPES
304#include "RISCVGenAsmMatcher.inc"
305#undef GET_OPERAND_DIAGNOSTIC_TYPES
309 static bool isSymbolDiff(
const MCExpr *Expr);
311 RISCVAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
312 const MCInstrInfo &MII)
313 : MCTargetAsmParser(STI, MII) {
320 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
322 auto ABIName = StringRef(getTargetOptions().ABIName);
323 if (ABIName.ends_with(
"f") && !getSTI().hasFeature(RISCV::FeatureStdExtF)) {
324 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
325 "doesn't support the F instruction set extension (ignoring "
327 }
else if (ABIName.ends_with(
"d") &&
328 !getSTI().hasFeature(RISCV::FeatureStdExtD)) {
329 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
330 "doesn't support the D instruction set extension (ignoring "
343 getTargetStreamer().emitTargetAttributes(STI,
false);
409 MCRegister OffsetReg;
412 SMLoc StartLoc, EndLoc;
427 RISCVOperand(KindTy K) : Kind(
K) {}
430 RISCVOperand(
const RISCVOperand &o) : MCParsedAsmOperand() {
432 StartLoc =
o.StartLoc;
435 case KindTy::Register:
438 case KindTy::Expression:
441 case KindTy::FPImmediate:
447 case KindTy::SystemRegister:
459 case KindTy::RegList:
462 case KindTy::StackAdj:
463 StackAdj =
o.StackAdj;
471 bool isToken()
const override {
return Kind == KindTy::Token; }
472 bool isReg()
const override {
return Kind == KindTy::Register; }
473 bool isExpr()
const {
return Kind == KindTy::Expression; }
474 bool isV0Reg()
const {
475 return Kind == KindTy::Register &&
Reg.Reg == RISCV::V0;
477 bool isAnyReg()
const {
478 return Kind == KindTy::Register &&
479 (RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.Reg) ||
480 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg.Reg) ||
481 RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg.Reg));
483 bool isAnyRegC()
const {
484 return Kind == KindTy::Register &&
485 (RISCVMCRegisterClasses[RISCV::GPRCRegClassID].contains(
Reg.Reg) ||
486 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg.Reg));
488 bool isImm()
const override {
return isExpr(); }
489 bool isMem()
const override {
return false; }
490 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
491 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
492 bool isRegList()
const {
return Kind == KindTy::RegList; }
493 bool isRegListS0()
const {
494 return Kind == KindTy::RegList && RegList.Encoding !=
RISCVZC::RA;
496 bool isStackAdj()
const {
return Kind == KindTy::StackAdj; }
499 return Kind == KindTy::Register &&
500 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.Reg);
503 bool isYGPR()
const {
504 return Kind == KindTy::Register &&
505 RISCVMCRegisterClasses[RISCV::YGPRRegClassID].contains(
Reg.Reg);
508 bool isGPRPair()
const {
509 return Kind == KindTy::Register &&
510 RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(
Reg.Reg);
513 bool isGPRPairC()
const {
514 return Kind == KindTy::Register &&
515 RISCVMCRegisterClasses[RISCV::GPRPairCRegClassID].contains(
Reg.Reg);
518 bool isGPRPairNoX0()
const {
519 return Kind == KindTy::Register &&
520 RISCVMCRegisterClasses[RISCV::GPRPairNoX0RegClassID].contains(
524 bool isGPRF16()
const {
525 return Kind == KindTy::Register &&
526 RISCVMCRegisterClasses[RISCV::GPRF16RegClassID].contains(
Reg.Reg);
529 bool isGPRF32()
const {
530 return Kind == KindTy::Register &&
531 RISCVMCRegisterClasses[RISCV::GPRF32RegClassID].contains(
Reg.Reg);
534 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
535 bool isGPRAsFPR16()
const {
return isGPRF16() &&
Reg.IsGPRAsFPR; }
536 bool isGPRAsFPR32()
const {
return isGPRF32() &&
Reg.IsGPRAsFPR; }
537 bool isGPRPairAsFPR64()
const {
return isGPRPair() &&
Reg.IsGPRAsFPR; }
539 static bool evaluateConstantExpr(
const MCExpr *Expr, int64_t &Imm) {
541 Imm =
CE->getValue();
550 template <
int N>
bool isBareSimmNLsb0()
const {
555 if (evaluateConstantExpr(
getExpr(), Imm))
556 return isShiftedInt<
N - 1, 1>(fixImmediateForRV32(Imm, isRV64Expr()));
559 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
565 template <
int N>
bool isBareSimmN()
const {
570 if (evaluateConstantExpr(
getExpr(), Imm))
571 return isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
574 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
580 bool isBareSymbol()
const {
583 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
587 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
591 bool isCallSymbol()
const {
594 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
598 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
602 bool isPseudoJumpSymbol()
const {
605 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
609 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
613 bool isTPRelAddSymbol()
const {
616 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
620 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
621 VK == ELF::R_RISCV_TPREL_ADD;
624 bool isTLSDESCCallSymbol()
const {
627 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
631 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
632 VK == ELF::R_RISCV_TLSDESC_CALL;
635 bool isQCAccessSymbol()
const {
638 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
642 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
646 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
650 bool isVTypeI10()
const {
651 if (Kind == KindTy::VType)
655 bool isVTypeI11()
const {
656 if (Kind == KindTy::VType)
661 bool isXSfmmVType()
const {
665 bool isTileLambda()
const {
666 return isUImmPred([](int64_t Imm) {
return Imm &&
isUInt<3>(Imm); });
671 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
674 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
675 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
679 bool isLoadFPImm()
const {
682 if (Kind != KindTy::FPImmediate)
685 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
688 return Idx >= 0 && Idx != 1;
691 bool isImmXLenLI()
const {
697 if (evaluateConstantExpr(
getExpr(), Imm))
700 return RISCVAsmParser::isSymbolDiff(
getExpr());
703 bool isImmXLenLI_Restricted()
const {
707 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
709 return IsConstantImm &&
713 template <
unsigned N>
bool isUImm()
const {
717 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
721 template <
unsigned N,
unsigned S>
bool isUImmShifted()
const {
725 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
729 template <
class Pred>
bool isUImmPred(Pred p)
const {
733 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
734 return IsConstantImm &&
p(Imm);
737 bool isUImmLog2XLen()
const {
738 if (isExpr() && isRV64Expr())
743 bool isUImmLog2XLenNonZero()
const {
744 if (isExpr() && isRV64Expr())
745 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<6>(Imm); });
746 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<5>(Imm); });
749 bool isUImmLog2XLenHalf()
const {
750 if (isExpr() && isRV64Expr())
755 bool isUImm1()
const {
return isUImm<1>(); }
756 bool isUImm2()
const {
return isUImm<2>(); }
757 bool isUImm3()
const {
return isUImm<3>(); }
758 bool isUImm4()
const {
return isUImm<4>(); }
759 bool isUImm5()
const {
return isUImm<5>(); }
760 bool isUImm6()
const {
return isUImm<6>(); }
761 bool isUImm7()
const {
return isUImm<7>(); }
762 bool isUImm8()
const {
return isUImm<8>(); }
763 bool isUImm9()
const {
return isUImm<9>(); }
764 bool isUImm10()
const {
return isUImm<10>(); }
765 bool isUImm11()
const {
return isUImm<11>(); }
766 bool isUImm16()
const {
return isUImm<16>(); }
767 bool isUImm20()
const {
return isUImm<20>(); }
768 bool isUImm32()
const {
return isUImm<32>(); }
769 bool isUImm48()
const {
return isUImm<48>(); }
770 bool isUImm64()
const {
return isUImm<64>(); }
772 bool isUImm5NonZero()
const {
773 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<5>(Imm); });
776 bool isUImm5GT3()
const {
777 return isUImmPred([](int64_t Imm) {
return isUInt<5>(Imm) &&
Imm > 3; });
780 bool isUImm4Plus1()
const {
782 [](int64_t Imm) {
return Imm > 0 &&
isUInt<4>(Imm - 1); });
785 bool isUImm5Plus1()
const {
787 [](int64_t Imm) {
return Imm > 0 &&
isUInt<5>(Imm - 1); });
790 bool isUImm6Plus1()
const {
792 [](int64_t Imm) {
return Imm > 0 &&
isUInt<6>(Imm - 1); });
795 bool isUImm5GE6Plus1()
const {
797 [](int64_t Imm) {
return Imm >= 6 &&
isUInt<5>(Imm - 1); });
800 bool isUImm5Slist()
const {
801 return isUImmPred([](int64_t Imm) {
802 return (Imm == 0) || (
Imm == 1) || (Imm == 2) || (
Imm == 4) ||
803 (Imm == 8) || (
Imm == 16) || (Imm == 15) || (
Imm == 31);
807 bool isUImm7EqXLen()
const {
809 [
this](int64_t Imm) {
return isRV64Expr() ?
Imm == 64 :
Imm == 32; });
812 bool isUImm8GE32()
const {
813 return isUImmPred([](int64_t Imm) {
return isUInt<8>(Imm) &&
Imm >= 32; });
816 bool isRnumArg()
const {
818 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(10); });
821 bool isRnumArg_0_7()
const {
823 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(7); });
826 bool isRnumArg_1_10()
const {
828 [](int64_t Imm) {
return Imm >= INT64_C(1) &&
Imm <= INT64_C(10); });
831 bool isRnumArg_2_14()
const {
833 [](int64_t Imm) {
return Imm >= INT64_C(2) &&
Imm <= INT64_C(14); });
836 template <
unsigned N>
bool isSImm()
const {
840 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
841 return IsConstantImm &&
isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
844 bool isYBNDSWImm()
const {
849 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
853 template <
class Pred>
bool isSImmPred(Pred p)
const {
857 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
858 return IsConstantImm &&
p(fixImmediateForRV32(Imm, isRV64Expr()));
861 bool isSImm5()
const {
return isSImm<5>(); }
862 bool isSImm6()
const {
return isSImm<6>(); }
863 bool isSImm10()
const {
return isSImm<10>(); }
864 bool isSImm11()
const {
return isSImm<11>(); }
865 bool isSImm12()
const {
return isSImm<12>(); }
866 bool isSImm16()
const {
return isSImm<16>(); }
867 bool isSImm26()
const {
return isSImm<26>(); }
869 bool isSImm5NonZero()
const {
870 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<5>(Imm); });
873 bool isSImm6NonZero()
const {
874 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<6>(Imm); });
877 bool isCLUIImm()
const {
878 return isUImmPred([](int64_t Imm) {
879 return (
isUInt<5>(Imm) && Imm != 0) || (
Imm >= 0xfffe0 &&
Imm <= 0xfffff);
883 bool isUImm2Lsb0()
const {
return isUImmShifted<1, 1>(); }
885 bool isUImm5Lsb0()
const {
return isUImmShifted<4, 1>(); }
887 bool isUImm6Lsb0()
const {
return isUImmShifted<5, 1>(); }
889 bool isUImm7Lsb00()
const {
return isUImmShifted<5, 2>(); }
891 bool isUImm7Lsb000()
const {
return isUImmShifted<4, 3>(); }
893 bool isUImm8Lsb00()
const {
return isUImmShifted<6, 2>(); }
895 bool isUImm8Lsb000()
const {
return isUImmShifted<5, 3>(); }
897 bool isUImm9Lsb000()
const {
return isUImmShifted<6, 3>(); }
899 bool isUImm14Lsb00()
const {
return isUImmShifted<12, 2>(); }
901 bool isUImm10Lsb00NonZero()
const {
908 static int64_t fixImmediateForRV32(int64_t Imm,
bool IsRV64Imm) {
914 bool isSImm12LO()
const {
919 if (evaluateConstantExpr(
getExpr(), Imm))
920 return isInt<12>(fixImmediateForRV32(Imm, isRV64Expr()));
923 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
926 VK == ELF::R_RISCV_TLSDESC_ADD_LO12);
929 bool isSImm12Lsb00000()
const {
933 bool isSImm10Lsb0000NonZero()
const {
938 bool isSImm16NonZero()
const {
939 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<16>(Imm); });
942 bool isUImm16NonZero()
const {
943 return isUImmPred([](int64_t Imm) {
return isUInt<16>(Imm) &&
Imm != 0; });
946 bool isSImm20LI()
const {
951 if (evaluateConstantExpr(
getExpr(), Imm))
952 return isInt<20>(fixImmediateForRV32(Imm, isRV64Expr()));
955 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
959 bool isSImm8PLI_B()
const {
return isSImm<8>() || isUImm<8>(); }
960 bool isSImm10PLUI()
const {
return isSImm<10>() || isUImm<10>(); }
962 bool isSImm10PLI_H()
const {
963 return isSImm<10>() || isUImmPred([](int64_t Imm) {
967 bool isSImm10PLI_W()
const {
968 return isSImm<10>() || isUImmPred([](int64_t Imm) {
973 bool isUImm20LUI()
const {
978 if (evaluateConstantExpr(
getExpr(), Imm))
982 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
983 (VK == ELF::R_RISCV_HI20 || VK == ELF::R_RISCV_TPREL_HI20);
986 bool isUImm20AUIPC()
const {
991 if (evaluateConstantExpr(
getExpr(), Imm))
995 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
997 VK == ELF::R_RISCV_TLS_GOT_HI20 || VK == ELF::R_RISCV_TLS_GD_HI20 ||
998 VK == ELF::R_RISCV_TLSDESC_HI20);
1001 bool isImmZero()
const {
1002 return isUImmPred([](int64_t Imm) {
return 0 ==
Imm; });
1005 bool isImmThree()
const {
1006 return isUImmPred([](int64_t Imm) {
return 3 ==
Imm; });
1009 bool isImmFour()
const {
1010 return isUImmPred([](int64_t Imm) {
return 4 ==
Imm; });
1013 bool isImm5Zibi()
const {
1015 [](int64_t Imm) {
return (Imm != 0 &&
isUInt<5>(Imm)) ||
Imm == -1; });
1018 bool isSImm5Plus1()
const {
1023 bool isSImm18()
const {
1024 return isSImmPred([](int64_t Imm) {
return isInt<18>(Imm); });
1027 bool isSImm18Lsb0()
const {
1031 bool isSImm19Lsb00()
const {
1035 bool isSImm20Lsb000()
const {
1039 bool isSImm32Lsb0()
const {
1044 SMLoc getStartLoc()
const override {
return StartLoc; }
1046 SMLoc getEndLoc()
const override {
return EndLoc; }
1049 bool isRV64Expr()
const {
1050 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1054 MCRegister
getReg()
const override {
1055 assert(Kind == KindTy::Register &&
"Invalid type access!");
1059 StringRef getSysReg()
const {
1060 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
1061 return StringRef(SysReg.Data, SysReg.Length);
1064 const MCExpr *
getExpr()
const {
1065 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1069 uint64_t getFPConst()
const {
1070 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1075 assert(Kind == KindTy::Token &&
"Invalid type access!");
1079 unsigned getVType()
const {
1080 assert(Kind == KindTy::VType &&
"Invalid type access!");
1085 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1089 unsigned getFence()
const {
1090 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1094 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1103 case KindTy::Expression:
1106 OS <<
' ' << (Expr.IsRV64 ?
"rv64" :
"rv32") <<
'>';
1108 case KindTy::FPImmediate:
1109 OS <<
"<fpimm: " << FPImm.Val <<
">";
1111 case KindTy::Register:
1113 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1118 case KindTy::SystemRegister:
1119 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1128 OS << roundingModeToString(getFRM());
1136 case KindTy::RegList:
1141 case KindTy::StackAdj:
1142 OS <<
"<stackadj: ";
1146 case KindTy::RegReg:
1147 OS <<
"<RegReg: BaseReg " <<
RegName(
RegReg.BaseReg) <<
" OffsetReg "
1153 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1154 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1161 static std::unique_ptr<RISCVOperand>
1162 createReg(MCRegister
Reg, SMLoc S, SMLoc
E,
bool IsGPRAsFPR =
false) {
1163 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1165 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1171 static std::unique_ptr<RISCVOperand> createExpr(
const MCExpr *Val, SMLoc S,
1172 SMLoc
E,
bool IsRV64) {
1173 auto Op = std::make_unique<RISCVOperand>(KindTy::Expression);
1174 Op->Expr.Expr = Val;
1175 Op->Expr.IsRV64 = IsRV64;
1181 static std::unique_ptr<RISCVOperand> createFPImm(uint64_t Val, SMLoc S) {
1182 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1183 Op->FPImm.Val = Val;
1189 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1190 unsigned Encoding) {
1191 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1192 Op->SysReg.Data = Str.data();
1193 Op->SysReg.Length = Str.size();
1200 static std::unique_ptr<RISCVOperand>
1202 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1209 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val, SMLoc S) {
1210 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1211 Op->Fence.Val = Val;
1217 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI, SMLoc S) {
1218 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1219 Op->VType.Val = VTypeI;
1225 static std::unique_ptr<RISCVOperand> createRegList(
unsigned RlistEncode,
1227 auto Op = std::make_unique<RISCVOperand>(KindTy::RegList);
1233 static std::unique_ptr<RISCVOperand>
1234 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {
1235 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1237 Op->RegReg.OffsetReg = OffsetReg;
1243 static std::unique_ptr<RISCVOperand> createStackAdj(
unsigned StackAdj, SMLoc S) {
1244 auto Op = std::make_unique<RISCVOperand>(KindTy::StackAdj);
1245 Op->StackAdj.Val = StackAdj;
1250 static void addExpr(MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1251 assert(Expr &&
"Expr shouldn't be null!");
1253 bool IsConstant = evaluateConstantExpr(Expr, Imm);
1263 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1264 assert(
N == 1 &&
"Invalid number of operands!");
1268 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1269 assert(
N == 1 &&
"Invalid number of operands!");
1270 addExpr(Inst,
getExpr(), isRV64Expr());
1273 template <
unsigned Bits>
1274 void addSExtImmOperands(MCInst &Inst,
unsigned N)
const {
1275 assert(
N == 1 &&
"Invalid number of operands!");
1282 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
1283 assert(
N == 1 &&
"Invalid number of operands!");
1285 addExpr(Inst,
getExpr(), isRV64Expr());
1290 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1294 void addFenceArgOperands(MCInst &Inst,
unsigned N)
const {
1295 assert(
N == 1 &&
"Invalid number of operands!");
1299 void addCSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
1300 assert(
N == 1 &&
"Invalid number of operands!");
1307 void addVTypeIOperands(MCInst &Inst,
unsigned N)
const {
1308 assert(
N == 1 &&
"Invalid number of operands!");
1310 if (Kind == KindTy::Expression) {
1311 [[maybe_unused]]
bool IsConstantImm =
1312 evaluateConstantExpr(
getExpr(), Imm);
1313 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1320 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1321 assert(
N == 1 &&
"Invalid number of operands!");
1325 void addRegRegOperands(MCInst &Inst,
unsigned N)
const {
1326 assert(
N == 2 &&
"Invalid number of operands!");
1331 void addStackAdjOperands(MCInst &Inst,
unsigned N)
const {
1332 assert(
N == 1 &&
"Invalid number of operands!");
1336 void addFRMArgOperands(MCInst &Inst,
unsigned N)
const {
1337 assert(
N == 1 &&
"Invalid number of operands!");
1343#define GET_REGISTER_MATCHER
1344#define GET_SUBTARGET_FEATURE_NAME
1345#define GET_MATCHER_IMPLEMENTATION
1346#define GET_MNEMONIC_SPELL_CHECKER
1347#include "RISCVGenAsmMatcher.inc"
1350 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1351 return Reg - RISCV::F0_D + RISCV::F0_H;
1355 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1356 return Reg - RISCV::F0_D + RISCV::F0_F;
1360 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1361 return Reg - RISCV::F0_D + RISCV::F0_Q;
1365 assert(
Reg >= RISCV::X0 &&
Reg <= RISCV::X31 &&
"Invalid register");
1366 return Reg - RISCV::X0 + RISCV::X0_Y;
1371 unsigned RegClassID;
1372 if (Kind == MCK_VRM2)
1373 RegClassID = RISCV::VRM2RegClassID;
1374 else if (Kind == MCK_VRM4)
1375 RegClassID = RISCV::VRM4RegClassID;
1376 else if (Kind == MCK_VRM8)
1377 RegClassID = RISCV::VRM8RegClassID;
1381 &RISCVMCRegisterClasses[RegClassID]);
1385 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1386 return Reg - RISCV::F0_D + RISCV::F0_Q2;
1391 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1393 return Match_InvalidOperand;
1395 MCRegister
Reg =
Op.getReg();
1397 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg);
1399 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg);
1400 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg);
1402 if (
Op.isGPR() && Kind == MCK_YGPR) {
1405 return Match_Success;
1407 if (IsRegFPR64 && Kind == MCK_FPR256) {
1409 return Match_Success;
1411 if (IsRegFPR64 && Kind == MCK_FPR128) {
1413 return Match_Success;
1417 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1418 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1420 return Match_Success;
1424 if (IsRegFPR64 && Kind == MCK_FPR16) {
1426 return Match_Success;
1428 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1429 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_H;
1430 return Match_Success;
1432 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1433 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_W;
1434 return Match_Success;
1441 if (RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg) &&
1442 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1444 return Match_Success;
1448 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1451 return Match_InvalidOperand;
1452 return Match_Success;
1454 return Match_InvalidOperand;
1457bool RISCVAsmParser::generateImmOutOfRangeError(
1458 SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
1459 const Twine &Msg =
"immediate must be an integer in the range") {
1460 return Error(ErrorLoc, Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]");
1463bool RISCVAsmParser::generateImmOutOfRangeError(
1465 const Twine &Msg =
"immediate must be an integer in the range") {
1466 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1467 return generateImmOutOfRangeError(ErrorLoc,
Lower,
Upper, Msg);
1470bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1473 uint64_t &ErrorInfo,
1474 bool MatchingInlineAsm) {
1476 FeatureBitset MissingFeatures;
1478 auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
1484 if (validateInstruction(Inst, Operands))
1486 return processInstruction(Inst, IDLoc, Operands, Out);
1487 case Match_MissingFeature: {
1488 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1489 bool FirstFeature =
true;
1490 std::string Msg =
"instruction requires the following:";
1491 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1492 if (MissingFeatures[i]) {
1493 Msg += FirstFeature ?
" " :
", ";
1495 FirstFeature =
false;
1498 return Error(IDLoc, Msg);
1500 case Match_MnemonicFail: {
1501 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1502 std::string Suggestion = RISCVMnemonicSpellCheck(
1503 ((RISCVOperand &)*Operands[0]).
getToken(), FBS, 0);
1504 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1506 case Match_InvalidOperand: {
1507 SMLoc ErrorLoc = IDLoc;
1508 if (ErrorInfo != ~0ULL) {
1509 if (ErrorInfo >= Operands.
size())
1510 return Error(ErrorLoc,
"too few operands for instruction");
1512 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1513 if (ErrorLoc == SMLoc())
1516 return Error(ErrorLoc,
"invalid operand for instruction");
1523 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1524 SMLoc ErrorLoc = IDLoc;
1525 if (ErrorInfo != ~0ULL && ErrorInfo >= Operands.
size())
1526 return Error(ErrorLoc,
"too few operands for instruction");
1532 case Match_InvalidImmXLenLI:
1534 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1535 return Error(ErrorLoc,
"operand must be a constant 64-bit integer");
1537 return generateImmOutOfRangeError(Operands, ErrorInfo,
1538 std::numeric_limits<int32_t>::min(),
1539 std::numeric_limits<uint32_t>::max());
1540 case Match_InvalidImmXLenLI_Restricted:
1542 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1543 return Error(ErrorLoc,
"operand either must be a constant 64-bit integer "
1544 "or a bare symbol name");
1546 return generateImmOutOfRangeError(
1547 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1548 std::numeric_limits<uint32_t>::max(),
1549 "operand either must be a bare symbol name or an immediate integer in "
1551 case Match_InvalidUImmLog2XLen:
1553 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1554 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1555 case Match_InvalidUImmLog2XLenNonZero:
1557 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
1558 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1559 case Match_InvalidUImm1:
1560 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
1561 case Match_InvalidUImm2:
1562 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
1563 case Match_InvalidUImm2Lsb0:
1564 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 2,
1565 "immediate must be one of");
1566 case Match_InvalidUImm3:
1567 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
1568 case Match_InvalidUImm4:
1569 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
1570 case Match_InvalidUImm4Plus1:
1571 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4));
1572 case Match_InvalidUImm5:
1573 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1574 case Match_InvalidUImm5NonZero:
1575 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1576 case Match_InvalidUImm5GT3:
1577 return generateImmOutOfRangeError(Operands, ErrorInfo, 4, (1 << 5) - 1);
1578 case Match_InvalidUImm5Plus1:
1579 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));
1580 case Match_InvalidUImm5GE6Plus1:
1581 return generateImmOutOfRangeError(Operands, ErrorInfo, 6, (1 << 5));
1582 case Match_InvalidUImm5Slist: {
1583 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1584 return Error(ErrorLoc,
1585 "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31");
1587 case Match_InvalidUImm6:
1588 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1589 case Match_InvalidUImm6Plus1:
1590 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6));
1591 case Match_InvalidUImm7:
1592 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
1593 case Match_InvalidUImm8:
1594 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
1595 case Match_InvalidUImm8GE32:
1596 return generateImmOutOfRangeError(Operands, ErrorInfo, 32, (1 << 8) - 1);
1597 case Match_InvalidSImm5:
1598 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4),
1600 case Match_InvalidSImm5NonZero:
1601 return generateImmOutOfRangeError(
1602 Operands, ErrorInfo, -(1 << 4), (1 << 4) - 1,
1603 "immediate must be non-zero in the range");
1604 case Match_InvalidSImm6:
1605 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
1607 case Match_InvalidSImm6NonZero:
1608 return generateImmOutOfRangeError(
1609 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
1610 "immediate must be non-zero in the range");
1611 case Match_InvalidCLUIImm:
1612 return generateImmOutOfRangeError(
1613 Operands, ErrorInfo, 1, (1 << 5) - 1,
1614 "immediate must be in [0xfffe0, 0xfffff] or");
1615 case Match_InvalidUImm5Lsb0:
1616 return generateImmOutOfRangeError(
1617 Operands, ErrorInfo, 0, (1 << 5) - 2,
1618 "immediate must be a multiple of 2 bytes in the range");
1619 case Match_InvalidUImm6Lsb0:
1620 return generateImmOutOfRangeError(
1621 Operands, ErrorInfo, 0, (1 << 6) - 2,
1622 "immediate must be a multiple of 2 bytes in the range");
1623 case Match_InvalidUImm7Lsb00:
1624 return generateImmOutOfRangeError(
1625 Operands, ErrorInfo, 0, (1 << 7) - 4,
1626 "immediate must be a multiple of 4 bytes in the range");
1627 case Match_InvalidUImm8Lsb00:
1628 return generateImmOutOfRangeError(
1629 Operands, ErrorInfo, 0, (1 << 8) - 4,
1630 "immediate must be a multiple of 4 bytes in the range");
1631 case Match_InvalidUImm8Lsb000:
1632 return generateImmOutOfRangeError(
1633 Operands, ErrorInfo, 0, (1 << 8) - 8,
1634 "immediate must be a multiple of 8 bytes in the range");
1635 case Match_InvalidUImm9:
1636 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 9) - 1,
1637 "immediate offset must be in the range");
1638 case Match_InvalidBareSImm9Lsb0:
1639 return generateImmOutOfRangeError(
1640 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
1641 "immediate must be a multiple of 2 bytes in the range");
1642 case Match_InvalidUImm9Lsb000:
1643 return generateImmOutOfRangeError(
1644 Operands, ErrorInfo, 0, (1 << 9) - 8,
1645 "immediate must be a multiple of 8 bytes in the range");
1646 case Match_InvalidSImm8PLI_B:
1647 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
1649 case Match_InvalidSImm10:
1650 case Match_InvalidSImm10PLI_H:
1651 case Match_InvalidSImm10PLI_W:
1652 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
1654 case Match_InvalidSImm10PLUI:
1655 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
1657 case Match_InvalidUImm10Lsb00NonZero:
1658 return generateImmOutOfRangeError(
1659 Operands, ErrorInfo, 4, (1 << 10) - 4,
1660 "immediate must be a multiple of 4 bytes in the range");
1661 case Match_InvalidSImm10Lsb0000NonZero:
1662 return generateImmOutOfRangeError(
1663 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
1664 "immediate must be a multiple of 16 bytes and non-zero in the range");
1665 case Match_InvalidSImm11:
1666 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 10),
1668 case Match_InvalidBareSImm11Lsb0:
1669 return generateImmOutOfRangeError(
1670 Operands, ErrorInfo, -(1 << 10), (1 << 10) - 2,
1671 "immediate must be a multiple of 2 bytes in the range");
1672 case Match_InvalidUImm10:
1673 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 10) - 1);
1674 case Match_InvalidUImm11:
1675 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
1676 case Match_InvalidUImm14Lsb00:
1677 return generateImmOutOfRangeError(
1678 Operands, ErrorInfo, 0, (1 << 14) - 4,
1679 "immediate must be a multiple of 4 bytes in the range");
1680 case Match_InvalidUImm16NonZero:
1681 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16) - 1);
1682 case Match_InvalidSImm12:
1683 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11),
1685 case Match_InvalidSImm12LO:
1686 return generateImmOutOfRangeError(
1687 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
1688 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo specifier or an "
1689 "integer in the range");
1690 case Match_InvalidBareSImm12Lsb0:
1691 return generateImmOutOfRangeError(
1692 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
1693 "immediate must be a multiple of 2 bytes in the range");
1694 case Match_InvalidSImm12Lsb00000:
1695 return generateImmOutOfRangeError(
1696 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 32,
1697 "immediate must be a multiple of 32 bytes in the range");
1698 case Match_InvalidBareSImm13Lsb0:
1699 return generateImmOutOfRangeError(
1700 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
1701 "immediate must be a multiple of 2 bytes in the range");
1702 case Match_InvalidSImm16:
1703 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 15),
1705 case Match_InvalidSImm16NonZero:
1706 return generateImmOutOfRangeError(
1707 Operands, ErrorInfo, -(1 << 15), (1 << 15) - 1,
1708 "immediate must be non-zero in the range");
1709 case Match_InvalidSImm20LI:
1710 return generateImmOutOfRangeError(
1711 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 1,
1712 "operand must be a symbol with a %qc.abs20 specifier or an integer "
1714 case Match_InvalidUImm20LUI:
1715 return generateImmOutOfRangeError(
1716 Operands, ErrorInfo, 0, (1 << 20) - 1,
1717 "operand must be a symbol with "
1718 "%hi/%tprel_hi specifier or an integer in "
1720 case Match_InvalidUImm20:
1721 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1);
1722 case Match_InvalidUImm20AUIPC:
1723 return generateImmOutOfRangeError(
1724 Operands, ErrorInfo, 0, (1 << 20) - 1,
1725 "operand must be a symbol with a "
1726 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
1728 "an integer in the range");
1729 case Match_InvalidBareSImm21Lsb0:
1730 return generateImmOutOfRangeError(
1731 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
1732 "immediate must be a multiple of 2 bytes in the range");
1733 case Match_InvalidCSRSystemRegister: {
1734 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1,
1735 "operand must be a valid system register "
1736 "name or an integer in the range");
1738 case Match_InvalidImm5Zibi:
1739 return generateImmOutOfRangeError(
1740 Operands, ErrorInfo, -1, (1 << 5) - 1,
1741 "immediate must be non-zero in the range");
1742 case Match_InvalidVTypeI: {
1743 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1744 return generateVTypeError(ErrorLoc);
1746 case Match_InvalidSImm5Plus1: {
1747 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1,
1749 "immediate must be in the range");
1751 case Match_InvalidSImm18:
1752 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 17),
1754 case Match_InvalidSImm18Lsb0:
1755 return generateImmOutOfRangeError(
1756 Operands, ErrorInfo, -(1 << 17), (1 << 17) - 2,
1757 "immediate must be a multiple of 2 bytes in the range");
1758 case Match_InvalidSImm19Lsb00:
1759 return generateImmOutOfRangeError(
1760 Operands, ErrorInfo, -(1 << 18), (1 << 18) - 4,
1761 "immediate must be a multiple of 4 bytes in the range");
1762 case Match_InvalidSImm20Lsb000:
1763 return generateImmOutOfRangeError(
1764 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 8,
1765 "immediate must be a multiple of 8 bytes in the range");
1766 case Match_InvalidSImm26:
1767 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 25),
1770 case Match_InvalidBareSymbolQC_E_LI:
1773 case Match_InvalidBareSImm32:
1774 return generateImmOutOfRangeError(Operands, ErrorInfo,
1775 std::numeric_limits<int32_t>::min(),
1776 std::numeric_limits<uint32_t>::max());
1777 case Match_InvalidBareSImm32Lsb0:
1778 return generateImmOutOfRangeError(
1779 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1780 std::numeric_limits<int32_t>::max() - 1,
1781 "operand must be a multiple of 2 bytes in the range");
1782 case Match_InvalidRnumArg: {
1783 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10);
1785 case Match_InvalidStackAdj: {
1786 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1789 "stack adjustment is invalid for this instruction and register list");
1791 case Match_InvalidYBNDSWImm: {
1792 const SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1793 return Error(ErrorLoc,
"immediate must be an integer in the range "
1794 "[1, 255], a multiple of 8 in the range [256, 504], "
1795 "or a multiple of 16 in the range [512, 4096]");
1797 case Match_InvalidUImm7EqXLen: {
1798 const SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1799 return Error(ErrorLoc,
"immediate must be an integer equal to XLEN (" +
1800 Twine(isRV64() ?
"64" :
"32") +
")");
1804 if (
const char *MatchDiag = getMatchKindDiag((RISCVMatchResultTy)Result)) {
1805 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1806 return Error(ErrorLoc, MatchDiag);
1816MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name)
const {
1825 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1826 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1827 static_assert(RISCV::F0_D < RISCV::F0_Q,
"FPR matching must be updated");
1830 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1835bool RISCVAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1837 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1838 return Error(StartLoc,
"invalid register name");
1842ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1844 const AsmToken &Tok = getParser().getTok();
1847 StringRef
Name = getLexer().getTok().getIdentifier();
1857ParseStatus RISCVAsmParser::parseRegister(
OperandVector &Operands,
1859 SMLoc FirstS = getLoc();
1860 bool HadParens =
false;
1867 size_t ReadCount = getLexer().peekTokens(Buf);
1870 LParen = getParser().getTok();
1875 switch (getLexer().getKind()) {
1878 getLexer().UnLex(LParen);
1881 StringRef
Name = getLexer().getTok().getIdentifier();
1886 getLexer().UnLex(LParen);
1890 Operands.
push_back(RISCVOperand::createToken(
"(", FirstS));
1892 SMLoc
E = getTok().getEndLoc();
1899 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
1905ParseStatus RISCVAsmParser::parseInsnDirectiveOpcode(
OperandVector &Operands) {
1910 switch (getLexer().getKind()) {
1920 if (getParser().parseExpression(Res,
E))
1925 int64_t
Imm =
CE->getValue();
1927 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1936 if (getParser().parseIdentifier(Identifier))
1939 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1942 "Unexpected opcode");
1945 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1955 return generateImmOutOfRangeError(
1957 "opcode must be a valid opcode name or an immediate in the range");
1960ParseStatus RISCVAsmParser::parseInsnCDirectiveOpcode(
OperandVector &Operands) {
1965 switch (getLexer().getKind()) {
1975 if (getParser().parseExpression(Res,
E))
1980 int64_t
Imm =
CE->getValue();
1981 if (Imm >= 0 && Imm <= 2) {
1982 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1991 if (getParser().parseIdentifier(Identifier))
1995 if (Identifier ==
"C0")
1997 else if (Identifier ==
"C1")
1999 else if (Identifier ==
"C2")
2006 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2015 return generateImmOutOfRangeError(
2017 "opcode must be a valid opcode name or an immediate in the range");
2020ParseStatus RISCVAsmParser::parseCSRSystemRegister(
OperandVector &Operands) {
2024 auto SysRegFromConstantInt = [
this](
const MCExpr *
E, SMLoc S) {
2026 int64_t
Imm =
CE->getValue();
2028 auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
2032 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2035 return RISCVOperand::createSysReg(
Reg.Name, S, Imm);
2039 return RISCVOperand::createSysReg(
"", S, Imm);
2042 return std::unique_ptr<RISCVOperand>();
2045 switch (getLexer().getKind()) {
2055 if (getParser().parseExpression(Res))
2058 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
2063 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2067 if (getParser().parseIdentifier(Identifier))
2070 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
2073 if (SysReg->IsDeprecatedName) {
2075 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
2077 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2079 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
2085 const auto &FeatureBits = getSTI().getFeatureBits();
2086 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
2088 return SysReg->FeaturesRequired[Feature.Value];
2090 auto ErrorMsg = std::string(
"system register '") + SysReg->Name +
"' ";
2091 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
2092 ErrorMsg +=
"is RV32 only";
2094 ErrorMsg +=
" and ";
2098 "requires '" + std::string(Feature->Key) +
"' to be enabled";
2101 return Error(S, ErrorMsg);
2104 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
2119 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2120 "operand must be a valid system register "
2121 "name or an integer in the range");
2125 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2132ParseStatus RISCVAsmParser::parseFPImm(
OperandVector &Operands) {
2137 StringRef
Identifier = getTok().getIdentifier();
2138 if (
Identifier.compare_insensitive(
"inf") == 0) {
2141 getTok().getEndLoc(), isRV64()));
2142 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2145 getTok().getEndLoc(), isRV64()));
2146 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2149 getTok().getEndLoc(), isRV64()));
2151 return TokError(
"invalid floating point literal");
2162 const AsmToken &Tok = getTok();
2164 return TokError(
"invalid floating point immediate");
2167 APFloat RealVal(APFloat::IEEEdouble());
2169 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2171 return TokError(
"invalid floating point representation");
2174 RealVal.changeSign();
2176 Operands.
push_back(RISCVOperand::createFPImm(
2177 RealVal.bitcastToAPInt().getZExtValue(), S));
2184ParseStatus RISCVAsmParser::parseExpression(
OperandVector &Operands) {
2189 switch (getLexer().getKind()) {
2201 if (getParser().parseExpression(Res,
E))
2205 return parseOperandWithSpecifier(Operands);
2208 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2212ParseStatus RISCVAsmParser::parseOperandWithSpecifier(
OperandVector &Operands) {
2218 const MCExpr *Expr =
nullptr;
2219 bool Failed = parseExprWithSpecifier(Expr,
E);
2221 Operands.
push_back(RISCVOperand::createExpr(Expr, S,
E, isRV64()));
2225bool RISCVAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
2226 SMLoc Loc = getLoc();
2228 return TokError(
"expected '%' relocation specifier");
2229 StringRef
Identifier = getParser().getTok().getIdentifier();
2232 return TokError(
"invalid relocation specifier");
2238 const MCExpr *SubExpr;
2239 if (getParser().parseParenExpression(SubExpr,
E))
2246bool RISCVAsmParser::parseDataExpr(
const MCExpr *&Res) {
2249 return parseExprWithSpecifier(Res,
E);
2250 return getParser().parseExpression(Res);
2253ParseStatus RISCVAsmParser::parseBareSymbol(
OperandVector &Operands) {
2260 StringRef
Identifier = getTok().getIdentifier();
2270 if (getParser().parseExpression(Res,
E))
2273 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2277ParseStatus RISCVAsmParser::parseCallSymbol(
OperandVector &Operands) {
2283 std::string
Identifier(getTok().getIdentifier());
2289 SMLoc Loc = getLoc();
2290 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2291 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2305 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2309ParseStatus RISCVAsmParser::parsePseudoJumpSymbol(
OperandVector &Operands) {
2314 if (getParser().parseExpression(Res,
E))
2317 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef)
2318 return Error(S,
"operand must be a valid jump target");
2321 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2325ParseStatus RISCVAsmParser::parseJALOffset(
OperandVector &Operands) {
2339 return parseExpression(Operands);
2342bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2343 unsigned &Sew,
unsigned &Lmul,
2344 bool &Fractional,
bool &TailAgnostic,
2345 bool &MaskAgnostic,
bool &AltFmt) {
2350 if (State < VTypeState::SeenSew &&
Identifier.consume_front(
"e")) {
2352 if (Identifier ==
"16alt") {
2355 }
else if (Identifier ==
"8alt") {
2365 State = VTypeState::SeenSew;
2369 if (State < VTypeState::SeenLmul &&
Identifier.consume_front(
"m")) {
2372 if (Identifier ==
"a" || Identifier ==
"u") {
2374 State = VTypeState::SeenMaskPolicy;
2385 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2386 unsigned MinLMUL = ELEN / 8;
2389 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2390 Twine(MinLMUL) +
" is reserved");
2393 State = VTypeState::SeenLmul;
2397 if (State < VTypeState::SeenTailPolicy &&
Identifier.starts_with(
"t")) {
2398 if (Identifier ==
"ta")
2399 TailAgnostic =
true;
2400 else if (Identifier ==
"tu")
2401 TailAgnostic =
false;
2405 State = VTypeState::SeenTailPolicy;
2409 if (State < VTypeState::SeenMaskPolicy &&
Identifier.starts_with(
"m")) {
2410 if (Identifier ==
"ma")
2411 MaskAgnostic =
true;
2412 else if (Identifier ==
"mu")
2413 MaskAgnostic =
false;
2417 State = VTypeState::SeenMaskPolicy;
2424ParseStatus RISCVAsmParser::parseVTypeI(
OperandVector &Operands) {
2430 bool Fractional =
false;
2431 bool TailAgnostic =
false;
2432 bool MaskAgnostic =
false;
2435 VTypeState State = VTypeState::SeenNothingYet;
2437 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2438 MaskAgnostic, AltFmt)) {
2440 if (State == VTypeState::SeenNothingYet)
2449 State == VTypeState::SeenNothingYet)
2450 return generateVTypeError(S);
2454 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2455 unsigned MaxSEW = ELEN / Lmul;
2457 if (MaxSEW >= 8 && Sew > MaxSEW)
2458 Warning(S,
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2459 " and LMUL == mf" + Twine(Lmul) +
2460 " may not be compatible with all RVV implementations");
2465 Operands.
push_back(RISCVOperand::createVType(VTypeI, S));
2469bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2470 return Error(ErrorLoc,
2472 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2475ParseStatus RISCVAsmParser::parseXSfmmVType(
OperandVector &Operands) {
2492 if (Identifier !=
"16alt")
2521 Operands.
push_back(RISCVOperand::createVType(
2527 return generateXSfmmVTypeError(S);
2530bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
2531 return Error(ErrorLoc,
"operand must be e[8|16|16alt|32|64],w[1|2|4]");
2534ParseStatus RISCVAsmParser::parseMaskReg(
OperandVector &Operands) {
2538 StringRef
Name = getLexer().getTok().getIdentifier();
2539 if (!
Name.consume_back(
".t")) {
2543 return Error(getLoc(),
"expected '.t' suffix");
2550 if (
Reg != RISCV::V0)
2553 SMLoc
E = getTok().getEndLoc();
2559ParseStatus RISCVAsmParser::parseVScaleReg(
OperandVector &Operands) {
2563 StringRef
Name = getLexer().getTok().getIdentifier();
2564 if (!
Name.consume_back(
".scale"))
2565 return Error(getLoc(),
"expected '.scale' suffix");
2570 if (
Reg != RISCV::V0)
2573 SMLoc
E = getTok().getEndLoc();
2579ParseStatus RISCVAsmParser::parseTileLambda(
OperandVector &Operands) {
2584 StringRef
Name = getLexer().getTok().getIdentifier();
2585 if (!
Name.consume_front(
"L") && !
Name.consume_front(
"l"))
2590 return Error(S,
"operand must be L1, L2, L4, L8, L16, L32, or L64");
2592 unsigned EncodedLambda =
Log2_32(Lambda) + 1;
2594 SMLoc
E = getTok().getEndLoc();
2596 Operands.
push_back(RISCVOperand::createExpr(
2601ParseStatus RISCVAsmParser::parseGPRAsFPR64(
OperandVector &Operands) {
2602 if (!isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2605 return parseGPRAsFPR(Operands);
2608ParseStatus RISCVAsmParser::parseGPRAsFPR(
OperandVector &Operands) {
2612 StringRef
Name = getLexer().getTok().getIdentifier();
2618 SMLoc
E = getTok().getEndLoc();
2620 Operands.
push_back(RISCVOperand::createReg(
2621 Reg, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2625ParseStatus RISCVAsmParser::parseGPRPairAsFPR64(
OperandVector &Operands) {
2626 if (isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2632 StringRef
Name = getLexer().getTok().getIdentifier();
2638 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2641 if ((
Reg - RISCV::X0) & 1) {
2644 if (getSTI().hasFeature(RISCV::FeatureStdExtZfinx))
2645 return TokError(
"double precision floating point operands must use even "
2646 "numbered X register");
2651 SMLoc
E = getTok().getEndLoc();
2654 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2656 Reg, RISCV::sub_gpr_even,
2657 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2658 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2662template <
bool IsRV64>
2663ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands) {
2664 return parseGPRPair(Operands, IsRV64);
2667ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands,
2674 if (!IsRV64Inst && isRV64())
2680 StringRef
Name = getLexer().getTok().getIdentifier();
2686 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2689 if ((
Reg - RISCV::X0) & 1)
2690 return TokError(
"register must be even");
2693 SMLoc
E = getTok().getEndLoc();
2696 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2698 Reg, RISCV::sub_gpr_even,
2699 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2700 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E));
2704ParseStatus RISCVAsmParser::parseFRMArg(
OperandVector &Operands) {
2707 "operand must be a valid floating point rounding mode mnemonic");
2709 StringRef Str = getLexer().getTok().getIdentifier();
2714 "operand must be a valid floating point rounding mode mnemonic");
2716 Operands.
push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2721ParseStatus RISCVAsmParser::parseFenceArg(
OperandVector &Operands) {
2722 const AsmToken &Tok = getLexer().getTok();
2728 Operands.
push_back(RISCVOperand::createFenceArg(0, getLoc()));
2742 for (
char c : Str) {
2771 Operands.
push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2777 return TokError(
"operand must be formed of letters selected in-order from "
2781ParseStatus RISCVAsmParser::parseMemOpBaseReg(
OperandVector &Operands) {
2784 Operands.
push_back(RISCVOperand::createToken(
"(", getLoc()));
2786 if (!parseRegister(Operands).isSuccess())
2787 return Error(getLoc(),
"expected register");
2791 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
2796ParseStatus RISCVAsmParser::parseZeroOffsetMemOp(
OperandVector &Operands) {
2815 std::unique_ptr<RISCVOperand> OptionalImmOp;
2822 SMLoc ImmStart = getLoc();
2823 if (getParser().parseIntToken(ImmVal,
2824 "expected '(' or optional integer offset"))
2829 SMLoc ImmEnd = getLoc();
2832 ImmStart, ImmEnd, isRV64());
2836 OptionalImmOp ?
"expected '(' after optional integer offset"
2837 :
"expected '(' or optional integer offset"))
2840 if (!parseRegister(Operands).isSuccess())
2841 return Error(getLoc(),
"expected register");
2847 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2849 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2850 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2855ParseStatus RISCVAsmParser::parseRegReg(
OperandVector &Operands) {
2861 StringRef OffsetRegName = getLexer().getTok().getIdentifier();
2864 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(OffsetReg))
2865 return Error(getLoc(),
"expected GPR register");
2872 return Error(getLoc(),
"expected GPR register");
2874 StringRef BaseRegName = getLexer().getTok().getIdentifier();
2877 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(BaseReg))
2878 return Error(getLoc(),
"expected GPR register");
2884 Operands.
push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));
2896ParseStatus RISCVAsmParser::parseRegList(
OperandVector &Operands,
2897 bool MustIncludeS0) {
2909 return Error(getLoc(),
"invalid register");
2911 StringRef
RegName = getTok().getIdentifier();
2914 return Error(getLoc(),
"invalid register");
2917 UsesXRegs =
RegName[0] ==
'x';
2918 if (
Reg != RISCV::X1)
2919 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2920 }
else if (RegEnd == RISCV::X1) {
2921 if (
Reg != RISCV::X8 || (UsesXRegs != (
RegName[0] ==
'x')))
2922 return Error(getLoc(), Twine(
"register must be '") +
2923 (UsesXRegs ?
"x8" :
"s0") +
"'");
2924 }
else if (RegEnd == RISCV::X9 && UsesXRegs) {
2925 if (
Reg != RISCV::X18 || (
RegName[0] !=
'x'))
2926 return Error(getLoc(),
"register must be 'x18'");
2928 return Error(getLoc(),
"too many register ranges");
2935 SMLoc MinusLoc = getLoc();
2937 if (RegEnd == RISCV::X1)
2938 return Error(MinusLoc, Twine(
"register '") + (UsesXRegs ?
"x1" :
"ra") +
2939 "' cannot start a multiple register range");
2942 return Error(getLoc(),
"invalid register");
2944 StringRef
RegName = getTok().getIdentifier();
2947 return Error(getLoc(),
"invalid register");
2949 if (RegEnd == RISCV::X8) {
2950 if ((
Reg != RISCV::X9 &&
2952 (UsesXRegs != (
RegName[0] ==
'x'))) {
2954 return Error(getLoc(),
"register must be 'x9'");
2955 return Error(getLoc(),
"register must be in the range 's1' to 's11'");
2957 }
else if (RegEnd == RISCV::X18) {
2959 return Error(getLoc(),
2960 "register must be in the range 'x19' to 'x27'");
2973 if (RegEnd == RISCV::X26)
2974 return Error(S,
"invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "
2975 "x18-x26}' is not supported");
2981 return Error(S,
"register list must include 's0' or 'x8'");
2983 Operands.
push_back(RISCVOperand::createRegList(Encode, S));
2988ParseStatus RISCVAsmParser::parseZcmpStackAdj(
OperandVector &Operands,
2989 bool ExpectNegative) {
2998 auto *RegListOp =
static_cast<RISCVOperand *
>(Operands.
back().
get());
2999 if (!RegListOp->isRegList())
3002 unsigned RlistEncode = RegListOp->RegList.Encoding;
3006 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||
3007 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {
3008 int64_t
Lower = StackAdjBase;
3009 int64_t
Upper = StackAdjBase + 48;
3010 if (ExpectNegative) {
3015 return generateImmOutOfRangeError(S,
Lower,
Upper,
3016 "stack adjustment for register list must "
3017 "be a multiple of 16 bytes in the range");
3021 Operands.
push_back(RISCVOperand::createStackAdj(StackAdj, S));
3029bool RISCVAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
3033 MatchOperandParserImpl(Operands, Mnemonic,
true);
3040 if (parseRegister(Operands,
true).isSuccess())
3044 if (parseExpression(Operands).isSuccess()) {
3047 return !parseMemOpBaseReg(Operands).isSuccess();
3052 Error(getLoc(),
"unknown operand");
3056bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &Info,
3057 StringRef Name, SMLoc NameLoc,
3063 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
3067 Operands.
push_back(RISCVOperand::createToken(Name, NameLoc));
3076 if (parseOperand(Operands, Name))
3082 if (parseOperand(Operands, Name))
3086 if (getParser().parseEOL(
"unexpected token")) {
3087 getParser().eatToEndOfStatement();
3093bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
3097 Kind = RE->getSpecifier();
3098 Expr = RE->getSubExpr();
3107bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
3116ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
3117 StringRef IDVal = DirectiveID.
getString();
3119 if (IDVal ==
".option")
3120 return parseDirectiveOption();
3121 if (IDVal ==
".attribute")
3122 return parseDirectiveAttribute();
3123 if (IDVal ==
".insn")
3124 return parseDirectiveInsn(DirectiveID.
getLoc());
3125 if (IDVal ==
".variant_cc")
3126 return parseDirectiveVariantCC();
3131bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
3132 bool FromOptionDirective) {
3135 clearFeatureBits(Feature.Value, Feature.Key);
3142 raw_string_ostream OutputErrMsg(Buffer);
3143 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3144 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
3145 << ErrMsg.getMessage();
3148 return Error(Loc, OutputErrMsg.str());
3150 auto &ISAInfo = *ParseResult;
3153 if (ISAInfo->hasExtension(Feature.Key))
3154 setFeatureBits(Feature.Value, Feature.Key);
3156 if (FromOptionDirective) {
3157 if (ISAInfo->getXLen() == 32 && isRV64())
3158 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3159 else if (ISAInfo->getXLen() == 64 && !isRV64())
3160 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3163 if (ISAInfo->getXLen() == 32)
3164 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
3165 else if (ISAInfo->getXLen() == 64)
3166 setFeatureBits(RISCV::Feature64Bit,
"64bit");
3168 return Error(Loc,
"bad arch string " + Arch);
3170 Result = ISAInfo->toString();
3174bool RISCVAsmParser::parseDirectiveOption() {
3175 MCAsmParser &Parser = getParser();
3177 AsmToken Tok = Parser.
getTok();
3185 if (Option ==
"push") {
3189 getTargetStreamer().emitDirectiveOptionPush();
3194 if (Option ==
"pop") {
3199 getTargetStreamer().emitDirectiveOptionPop();
3200 if (popFeatureBits())
3201 return Error(StartLoc,
".option pop with no .option push");
3206 if (Option ==
"arch") {
3214 Type = RISCVOptionArchArgType::Plus;
3216 Type = RISCVOptionArchArgType::Minus;
3217 else if (!
Args.empty())
3219 "unexpected token, expected + or -");
3221 Type = RISCVOptionArchArgType::Full;
3225 "unexpected token, expected identifier");
3231 if (
Type == RISCVOptionArchArgType::Full) {
3233 if (resetToArch(Arch, Loc, Result,
true))
3242 Loc,
"extension version number parsing not currently implemented");
3245 if (!enableExperimentalExtension() &&
3247 return Error(Loc,
"unexpected experimental extensions");
3249 if (Ext == std::end(
RISCVFeatureKV) || StringRef(Ext->Key) != Feature)
3250 return Error(Loc,
"unknown extension feature");
3254 if (
Type == RISCVOptionArchArgType::Plus) {
3257 setFeatureBits(Ext->Value, Ext->Key);
3260 copySTI().setFeatureBits(OldFeatureBits);
3261 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3264 raw_string_ostream OutputErrMsg(Buffer);
3265 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3266 OutputErrMsg << ErrMsg.getMessage();
3269 return Error(Loc, OutputErrMsg.str());
3272 assert(
Type == RISCVOptionArchArgType::Minus);
3277 if (getSTI().hasFeature(Feature.Value) &&
3278 Feature.Implies.test(Ext->Value))
3279 return Error(Loc, Twine(
"can't disable ") + Ext->Key +
3280 " extension; " + Feature.Key +
3281 " extension requires " + Ext->Key +
3285 clearFeatureBits(Ext->Value, Ext->Key);
3292 getTargetStreamer().emitDirectiveOptionArch(Args);
3294 if (
auto ParseResult =
3296 getTargetStreamer().setArchString((*ParseResult)->toString());
3300 if (Option ==
"exact") {
3304 getTargetStreamer().emitDirectiveOptionExact();
3305 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3306 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3310 if (Option ==
"noexact") {
3314 getTargetStreamer().emitDirectiveOptionNoExact();
3315 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3316 setFeatureBits(RISCV::FeatureRelax,
"relax");
3320 if (Option ==
"rvc") {
3324 getTargetStreamer().emitDirectiveOptionRVC();
3325 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3326 if (
auto ParseResult =
3328 getTargetStreamer().setArchString((*ParseResult)->toString());
3332 if (Option ==
"norvc") {
3336 getTargetStreamer().emitDirectiveOptionNoRVC();
3337 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3338 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3339 if (
auto ParseResult =
3341 getTargetStreamer().setArchString((*ParseResult)->toString());
3345 if (Option ==
"pic") {
3349 getTargetStreamer().emitDirectiveOptionPIC();
3350 ParserOptions.IsPicEnabled =
true;
3354 if (Option ==
"nopic") {
3358 getTargetStreamer().emitDirectiveOptionNoPIC();
3359 ParserOptions.IsPicEnabled =
false;
3363 if (Option ==
"relax") {
3367 getTargetStreamer().emitDirectiveOptionRelax();
3368 setFeatureBits(RISCV::FeatureRelax,
"relax");
3372 if (Option ==
"norelax") {
3376 getTargetStreamer().emitDirectiveOptionNoRelax();
3377 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3383 "unknown option, expected 'push', 'pop', "
3384 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3385 "'exact', or 'noexact'");
3393bool RISCVAsmParser::parseDirectiveAttribute() {
3394 MCAsmParser &Parser = getParser();
3400 std::optional<unsigned> Ret =
3403 return Error(TagLoc,
"attribute name not recognised: " + Name);
3407 const MCExpr *AttrExpr;
3414 if (check(!CE, TagLoc,
"expected numeric constant"))
3417 Tag =
CE->getValue();
3423 StringRef StringValue;
3424 int64_t IntegerValue = 0;
3425 bool IsIntegerValue =
true;
3430 IsIntegerValue =
false;
3433 if (IsIntegerValue) {
3434 const MCExpr *ValueExpr;
3440 return Error(ValueExprLoc,
"expected numeric constant");
3441 IntegerValue =
CE->getValue();
3454 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3456 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3459 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3463 getTargetStreamer().emitTextAttribute(
Tag, Result);
3467 getTargetStreamer().setArchString(Result);
3475 .
Cases({
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s"},
true)
3476 .Cases({
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj"},
3478 .
Cases({
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es"},
3487bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3488 MCAsmParser &Parser = getParser();
3495 std::optional<int64_t>
Length;
3505 return Error(ErrorLoc,
3506 "instruction lengths must be a non-zero multiple of two");
3510 return Error(ErrorLoc,
3511 "instruction lengths over 64 bits are not supported");
3517 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3522 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3523 return Error(ErrorLoc,
3524 "instruction length does not match the encoding");
3527 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3530 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3533 if (!getSTI().hasFeature(RISCV::FeatureStdExtZca) &&
3534 (EncodingDerivedLength == 2))
3535 return Error(ErrorLoc,
"compressed instructions are not allowed");
3537 if (getParser().parseEOL(
"invalid operand for instruction")) {
3538 getParser().eatToEndOfStatement();
3546 Opcode = RISCV::Insn16;
3549 Opcode = RISCV::Insn32;
3552 Opcode = RISCV::Insn48;
3555 Opcode = RISCV::Insn64;
3561 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3563 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3568 return Error(ErrorLoc,
"invalid instruction format");
3570 std::string FormatName = (
".insn_" +
Format).str();
3572 ParseInstructionInfo
Info;
3575 if (parseInstruction(Info, FormatName, L, Operands))
3580 return matchAndEmitInstruction(L, Opcode, Operands, Parser.
getStreamer(),
3587bool RISCVAsmParser::parseDirectiveVariantCC() {
3589 if (getParser().parseIdentifier(Name))
3590 return TokError(
"expected symbol name");
3593 getTargetStreamer().emitDirectiveVariantCC(
3598void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3601 const MCSubtargetInfo &STI = getSTI();
3602 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3605 ++RISCVNumInstrsCompressed;
3609void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3614 for (MCInst &Inst : Seq) {
3615 emitToStreamer(Out, Inst);
3619void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3620 const MCExpr *Symbol,
3622 unsigned SecondOpcode, SMLoc IDLoc,
3634 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3639 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3642 .addExpr(RefToLinkTmpLabel));
3645void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3659void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3669 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3670 emitAuipcInstPair(DestReg, DestReg, Symbol,
RISCV::S_GOT_HI, SecondOpcode,
3674void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3683 if (ParserOptions.IsPicEnabled)
3684 emitLoadGlobalAddress(Inst, IDLoc, Out);
3686 emitLoadLocalAddress(Inst, IDLoc, Out);
3689void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3699 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3700 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3701 SecondOpcode, IDLoc, Out);
3704void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3714 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3715 RISCV::ADDI, IDLoc, Out);
3718void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3719 SMLoc IDLoc, MCStreamer &Out,
3728 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3730 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3734 if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].
contains(TmpReg)) {
3735 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3736 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3744void RISCVAsmParser::emitQCELILoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3745 SMLoc IDLoc, MCStreamer &Out,
3755 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3759 MCInstBuilder(RISCV::QC_E_LI).addReg(AddrReg).addExpr(Symbol));
3762 const MCExpr *AccessExpr =
3768 struct CompressedForm {
3772 std::optional<CompressedForm> Compressed;
3776 case RISCV::PseudoQCAccessLBU:
3777 Compressed = {RISCV::PseudoQCAccessC_LBU, RISCV::FeatureStdExtZcb};
3779 case RISCV::PseudoQCAccessLH:
3780 Compressed = {RISCV::PseudoQCAccessC_LH, RISCV::FeatureStdExtZcb};
3782 case RISCV::PseudoQCAccessLHU:
3783 Compressed = {RISCV::PseudoQCAccessC_LHU, RISCV::FeatureStdExtZcb};
3785 case RISCV::PseudoQCAccessLW:
3786 Compressed = {RISCV::PseudoQCAccessC_LW, RISCV::FeatureStdExtZca};
3788 case RISCV::PseudoQCAccessSB:
3789 Compressed = {RISCV::PseudoQCAccessC_SB, RISCV::FeatureStdExtZcb};
3791 case RISCV::PseudoQCAccessSH:
3792 Compressed = {RISCV::PseudoQCAccessC_SH, RISCV::FeatureStdExtZcb};
3794 case RISCV::PseudoQCAccessSW:
3795 Compressed = {RISCV::PseudoQCAccessC_SW, RISCV::FeatureStdExtZca};
3802 RISCVMCRegisterClasses[RISCV::GPRCRegClassID].contains(AddrReg);
3803 if (HasTmpReg && CanUseGPRC) {
3806 RISCVMCRegisterClasses[RISCV::GPRCRegClassID].contains(DataReg);
3809 bool UseCompressed =
3810 Compressed && getSTI().hasFeature(Compressed->Feature) && CanUseGPRC;
3812 unsigned ActualOpcode = UseCompressed ? Compressed->Opcode : Opcode;
3815 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3819 .addExpr(AccessExpr));
3821 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3825 .addExpr(AccessExpr));
3829void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3830 int64_t Width, SMLoc IDLoc,
3839 const MCOperand &DestReg = Inst.
getOperand(0);
3840 const MCOperand &SourceReg = Inst.
getOperand(1);
3842 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3843 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3845 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3847 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3852 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3858void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
3865 emitToStreamer(Out, MCInstBuilder(Opcode)
3869 .addReg(MCRegister())
3871 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
3882 "The destination register should not be V0.");
3883 emitToStreamer(Out, MCInstBuilder(Opcode)
3889 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
3901 "The destination register should be V0.");
3903 "The temporary vector register should not be V0.");
3904 emitToStreamer(Out, MCInstBuilder(Opcode)
3908 .addReg(MCRegister())
3910 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3922 "The temporary vector register should not be V0.");
3923 emitToStreamer(Out, MCInstBuilder(Opcode)
3927 .addReg(MCRegister())
3929 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3934 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3939 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
3947bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
3949 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3952 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
3953 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3954 "%tprel_add specifier");
3960bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
3962 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
3965 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
3966 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
3967 "%tlsdesc_call specifier");
3973std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3974 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
3977std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3978 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3982std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3983 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3991 case RISCV::VLOXSEG2EI8_V:
3992 case RISCV::VLOXSEG2EI16_V:
3993 case RISCV::VLOXSEG2EI32_V:
3994 case RISCV::VLOXSEG2EI64_V:
3995 case RISCV::VLUXSEG2EI8_V:
3996 case RISCV::VLUXSEG2EI16_V:
3997 case RISCV::VLUXSEG2EI32_V:
3998 case RISCV::VLUXSEG2EI64_V:
4000 case RISCV::VLOXSEG3EI8_V:
4001 case RISCV::VLOXSEG3EI16_V:
4002 case RISCV::VLOXSEG3EI32_V:
4003 case RISCV::VLOXSEG3EI64_V:
4004 case RISCV::VLUXSEG3EI8_V:
4005 case RISCV::VLUXSEG3EI16_V:
4006 case RISCV::VLUXSEG3EI32_V:
4007 case RISCV::VLUXSEG3EI64_V:
4009 case RISCV::VLOXSEG4EI8_V:
4010 case RISCV::VLOXSEG4EI16_V:
4011 case RISCV::VLOXSEG4EI32_V:
4012 case RISCV::VLOXSEG4EI64_V:
4013 case RISCV::VLUXSEG4EI8_V:
4014 case RISCV::VLUXSEG4EI16_V:
4015 case RISCV::VLUXSEG4EI32_V:
4016 case RISCV::VLUXSEG4EI64_V:
4018 case RISCV::VLOXSEG5EI8_V:
4019 case RISCV::VLOXSEG5EI16_V:
4020 case RISCV::VLOXSEG5EI32_V:
4021 case RISCV::VLOXSEG5EI64_V:
4022 case RISCV::VLUXSEG5EI8_V:
4023 case RISCV::VLUXSEG5EI16_V:
4024 case RISCV::VLUXSEG5EI32_V:
4025 case RISCV::VLUXSEG5EI64_V:
4027 case RISCV::VLOXSEG6EI8_V:
4028 case RISCV::VLOXSEG6EI16_V:
4029 case RISCV::VLOXSEG6EI32_V:
4030 case RISCV::VLOXSEG6EI64_V:
4031 case RISCV::VLUXSEG6EI8_V:
4032 case RISCV::VLUXSEG6EI16_V:
4033 case RISCV::VLUXSEG6EI32_V:
4034 case RISCV::VLUXSEG6EI64_V:
4036 case RISCV::VLOXSEG7EI8_V:
4037 case RISCV::VLOXSEG7EI16_V:
4038 case RISCV::VLOXSEG7EI32_V:
4039 case RISCV::VLOXSEG7EI64_V:
4040 case RISCV::VLUXSEG7EI8_V:
4041 case RISCV::VLUXSEG7EI16_V:
4042 case RISCV::VLUXSEG7EI32_V:
4043 case RISCV::VLUXSEG7EI64_V:
4045 case RISCV::VLOXSEG8EI8_V:
4046 case RISCV::VLOXSEG8EI16_V:
4047 case RISCV::VLOXSEG8EI32_V:
4048 case RISCV::VLOXSEG8EI64_V:
4049 case RISCV::VLUXSEG8EI8_V:
4050 case RISCV::VLUXSEG8EI16_V:
4051 case RISCV::VLUXSEG8EI32_V:
4052 case RISCV::VLUXSEG8EI64_V:
4058 if (RISCVMCRegisterClasses[RISCV::VRM2RegClassID].
contains(
Reg))
4060 if (RISCVMCRegisterClasses[RISCV::VRM4RegClassID].
contains(
Reg))
4062 if (RISCVMCRegisterClasses[RISCV::VRM8RegClassID].
contains(
Reg))
4069 case RISCV::VFWMMACC_VV_SCALE:
4070 case RISCV::VFQMMACC_VV_SCALE:
4071 case RISCV::VF8WMMACC_VV_SCALE:
4072 case RISCV::VFWIMMACC_VV:
4073 case RISCV::VFQIMMACC_VV:
4074 case RISCV::VF8WIMMACC_VV:
4081bool RISCVAsmParser::validateInstruction(MCInst &Inst,
4085 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
4086 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
4089 if (DestReg == TempReg) {
4090 SMLoc Loc = Operands.
back()->getStartLoc();
4091 return Error(Loc,
"the temporary vector register cannot be the same as "
4092 "the destination register");
4096 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
4097 Opcode == RISCV::TH_LWD) {
4102 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
4103 SMLoc Loc = Operands[1]->getStartLoc();
4104 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
4108 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
4112 SMLoc Loc = Operands[1]->getStartLoc();
4113 return Error(Loc,
"rs1 and rs2 must be different");
4118 auto CheckOperandDoesNotOverlapV0 = [&](
int OperandIdx,
4119 unsigned ParsedIdx) {
4121 return Error(Operands[ParsedIdx]->getStartLoc(),
4122 "vd, vs1, and vs2 cannot overlap v0.scale");
4127 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4129 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4131 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4132 assert(DestIdx >= 0 && VS1Idx >= 0 && VS2Idx >= 0 &&
4133 "Unexpected Zvvfmm scaled operand list");
4135 if (CheckOperandDoesNotOverlapV0(DestIdx, 1) ||
4136 CheckOperandDoesNotOverlapV0(VS1Idx, 2) ||
4137 CheckOperandDoesNotOverlapV0(VS2Idx, 3))
4141 const MCInstrDesc &MCID = MII.
get(Opcode);
4145 int DestIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4149 const MCParsedAsmOperand *ParsedOp = Operands[1].get();
4150 if (!ParsedOp->
isReg()) {
4153 ParsedOp = Operands[2].get();
4155 assert(ParsedOp->
getReg() == DestReg &&
"Can't find parsed dest operand");
4159 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4163 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4164 assert(VS2Idx >= 0 &&
"No vs2 operand?");
4165 unsigned CheckEncoding =
4168 for (
unsigned i = 0; i < std::max(NF, Lmul); i++) {
4169 if ((DestEncoding + i) == CheckEncoding)
4170 return Error(Loc,
"the destination vector register group cannot overlap"
4171 " the source vector register group");
4176 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4180 unsigned CheckEncoding =
4182 for (
unsigned i = 0; i < Lmul; i++) {
4183 if ((DestEncoding + i) == CheckEncoding)
4185 "the destination vector register group cannot overlap"
4186 " the source vector register group");
4192 int VMIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vm);
4193 assert(VMIdx >= 0 &&
"No vm operand?");
4195 if (DestReg == RISCV::V0) {
4198 return Error(Loc,
"the destination vector register group cannot be V0");
4206 "Unexpected mask operand register");
4208 return Error(Loc,
"the destination vector register group cannot overlap"
4209 " the mask register");
4216bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
4224 case RISCV::PseudoC_ADDI_NOP: {
4226 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
4236 if (getSTI().hasFeature(RISCV::Feature64Bit))
4238 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV32)
4243 case RISCV::PACKW: {
4247 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV64)
4252 case RISCV::PseudoLLAImm:
4253 case RISCV::PseudoLAImm:
4254 case RISCV::PseudoLI: {
4260 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
4272 emitLoadImm(
Reg, Imm, Out);
4275 case RISCV::PseudoLLA:
4276 emitLoadLocalAddress(Inst, IDLoc, Out);
4278 case RISCV::PseudoLGA:
4279 emitLoadGlobalAddress(Inst, IDLoc, Out);
4281 case RISCV::PseudoLA:
4282 emitLoadAddress(Inst, IDLoc, Out);
4284 case RISCV::PseudoLA_TLS_IE:
4285 emitLoadTLSIEAddress(Inst, IDLoc, Out);
4287 case RISCV::PseudoLA_TLS_GD:
4288 emitLoadTLSGDAddress(Inst, IDLoc, Out);
4290 case RISCV::PseudoLB:
4291 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
4293 case RISCV::PseudoLBU:
4294 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
4296 case RISCV::PseudoLH:
4297 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
4299 case RISCV::PseudoLHU:
4300 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
4302 case RISCV::PseudoLW:
4303 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
4305 case RISCV::PseudoLWU:
4306 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
4308 case RISCV::PseudoLD:
4309 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
4311 case RISCV::PseudoLD_RV32:
4312 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
4314 case RISCV::PseudoFLH:
4315 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
4317 case RISCV::PseudoFLW:
4318 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
4320 case RISCV::PseudoFLD:
4321 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
4323 case RISCV::PseudoFLQ:
4324 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
4326 case RISCV::PseudoSB:
4327 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
4329 case RISCV::PseudoSH:
4330 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
4332 case RISCV::PseudoSW:
4333 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
4335 case RISCV::PseudoSD:
4336 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
4338 case RISCV::PseudoSD_RV32:
4339 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
4341 case RISCV::PseudoQC_E_LB:
4342 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLB, IDLoc, Out,
4345 case RISCV::PseudoQC_E_LBU:
4346 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLBU, IDLoc, Out,
4349 case RISCV::PseudoQC_E_LH:
4350 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLH, IDLoc, Out,
4353 case RISCV::PseudoQC_E_LHU:
4354 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLHU, IDLoc, Out,
4357 case RISCV::PseudoQC_E_LW:
4358 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLW, IDLoc, Out,
4361 case RISCV::PseudoQC_E_SB:
4362 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSB, IDLoc, Out,
4365 case RISCV::PseudoQC_E_SH:
4366 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSH, IDLoc, Out,
4369 case RISCV::PseudoQC_E_SW:
4370 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSW, IDLoc, Out,
4373 case RISCV::PseudoFSH:
4374 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
4376 case RISCV::PseudoFSW:
4377 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
4379 case RISCV::PseudoFSD:
4380 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4382 case RISCV::PseudoFSQ:
4383 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4385 case RISCV::PseudoAddTPRel:
4386 if (checkPseudoAddTPRel(Inst, Operands))
4389 case RISCV::PseudoTLSDESCCall:
4390 if (checkPseudoTLSDESCCall(Inst, Operands))
4393 case RISCV::PseudoSEXT_B:
4394 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4396 case RISCV::PseudoSEXT_H:
4397 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4399 case RISCV::PseudoZEXT_H:
4400 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4402 case RISCV::PseudoZEXT_W:
4403 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4405 case RISCV::PseudoVMSGEU_VX:
4406 case RISCV::PseudoVMSGEU_VX_M:
4407 case RISCV::PseudoVMSGEU_VX_M_T:
4408 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4410 case RISCV::PseudoVMSGE_VX:
4411 case RISCV::PseudoVMSGE_VX_M:
4412 case RISCV::PseudoVMSGE_VX_M_T:
4413 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4415 case RISCV::PseudoVMSGE_VI:
4416 case RISCV::PseudoVMSLT_VI: {
4420 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4422 emitToStreamer(Out, MCInstBuilder(
Opc)
4430 case RISCV::PseudoVMSGEU_VI:
4431 case RISCV::PseudoVMSLTU_VI: {
4438 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4441 emitToStreamer(Out, MCInstBuilder(
Opc)
4449 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4452 emitToStreamer(Out, MCInstBuilder(
Opc)
4462 case RISCV::PseudoCV_ELW:
4463 emitLoadStoreSymbol(Inst, RISCV::CV_ELW, IDLoc, Out,
false);
4467 emitToStreamer(Out, Inst);
static MCRegister MatchRegisterName(StringRef Name)
static const char * getSubtargetFeatureName(uint64_t Val)
static SDValue Widen(SelectionDAG *CurDAG, SDValue N)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void applyMnemonicAliases(StringRef &Mnemonic, const FeatureBitset &Features, unsigned VariantID)
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 GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, MCRegister &Reg, StringRef Name)
#define LLVM_EXTERNAL_VISIBILITY
Promote Memory to Register
static MCRegister 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 MCRegister convertGPRToYGPR(MCRegister Reg)
bool isValidInsnFormat(StringRef Format, const MCSubtargetInfo &STI)
static bool isZvvfmmScaleOpcode(unsigned Opcode)
static MCRegister convertFPR64ToFPR128(MCRegister Reg)
static MCRegister convertFPR64ToFPR32(MCRegister Reg)
static cl::opt< bool > AddBuildAttributes("riscv-add-build-attributes", cl::init(false))
static MCRegister convertFPR64ToFPR16(MCRegister Reg)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser()
static MCRegister convertFPR64ToFPR256(MCRegister Reg)
static MCRegister convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg, unsigned Kind)
static unsigned getNFforLXSEG(unsigned Opcode)
unsigned getLMULFromVectorRegister(MCRegister Reg)
static bool isUImm2(const MachineOperand &MO)
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)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
LLVM_ABI SMLoc getLoc() const
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
LLVM_ABI SMLoc getEndLoc() const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
Encoding
Size and signedness of expression operations' operands.
constexpr size_t size() const
void printExpr(raw_ostream &, const MCExpr &) const
const AsmToken & getTok()
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
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.
MCStreamer & getStreamer()
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
const MCObjectFileInfo * getObjectFileInfo() const
LLVM_ABI MCSymbol * createNamedTempSymbol()
Create a temporary symbol with a unique name whose name cannot be omitted in the symbol table.
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
ArrayRef< MCOperandInfo > operands() const
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
bool isPositionIndependent() const
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.
virtual SMLoc getStartLoc() const =0
getStartLoc - Get the location of the first token of this operand.
virtual bool isReg() const =0
isReg - Is this a register operand?
virtual MCRegister getReg() const =0
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.
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Wrapper class representing physical registers. Should be passed by value.
constexpr bool isValid() const
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
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.
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
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, SMLoc Loc=SMLoc())
bool isVariable() const
isVariable - Check if this is a variable symbol.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCTargetAsmParser - Generic interface to target specific assembly parsers.
const MCSymbol * getAddSym() const
uint32_t getSpecifier() const
const MCSymbol * getSubSym() const
Ternary parse status returned by various parse* methods.
static constexpr StatusTy Failure
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
static LLVM_ABI bool isSupportedExtensionFeature(StringRef Ext)
static LLVM_ABI std::string getTargetFeatureForExtension(StringRef Ext)
static LLVM_ABI 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 SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
void push_back(const T &Elt)
Represent a constant reference to a string, i.e.
std::string str() const
Get the contents as an std::string.
char back() const
Get the last character in the string.
A switch()-like statement whose cases are string literals.
StringSwitch & Cases(std::initializer_list< StringLiteral > CaseStrings, T Value)
#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.
LLVM_ABI std::optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)
MCExpr const & getExpr(MCExpr const &Expr)
ABI computeTargetABI(const Triple &TT, const FeatureBitset &FeatureBits, StringRef ABIName)
LLVM_ABI 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 VLMUL encodeLMUL(unsigned LMUL, bool Fractional)
LLVM_ABI unsigned encodeXSfmmVType(unsigned SEW, unsigned Widen, bool AltFmt)
static bool isValidLMUL(unsigned LMUL, bool Fractional)
static bool isValidSEW(unsigned SEW)
LLVM_ABI void printVType(unsigned VType, raw_ostream &OS)
static bool isValidXSfmmVType(unsigned VTypeI)
LLVM_ABI unsigned encodeVTYPE(VLMUL VLMUL, unsigned SEW, bool TailAgnostic, bool MaskAgnostic, bool AltFmt=false)
unsigned encodeRegList(MCRegister EndReg, bool IsRVE=false)
static unsigned getStackAdjBase(unsigned RlistVal, bool IsRV64)
void printRegList(unsigned RlistEncode, raw_ostream &OS)
Specifier parseSpecifierName(StringRef name)
void updateCZceFeatureImplications(MCSubtargetInfo &STI)
bool isValidYBNDSWImm(int64_t Imm)
@ CE
Windows NT (Windows on ARM)
@ Valid
The data is already valid.
initializer< Ty > init(const Ty &Val)
std::function< llvm::json::Value()> Lambda
Context & getContext() const
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
FunctionAddr VTableAddr Value
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
static bool isMem(const MachineInstr &MI, unsigned Op)
LLVM_ABI std::pair< StringRef, StringRef > getToken(StringRef Source, StringRef Delimiters=" \t\n\v\f\r")
getToken - This function extracts one token from source, ignoring any leading characters that appear ...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
testing::Matcher< const detail::ErrorHolder & > Failed()
Target & getTheRISCV32Target()
constexpr bool isUIntN(unsigned N, uint64_t x)
Checks if an unsigned integer fits into the given (dynamic) bit width.
Target & getTheRISCV64beTarget()
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
bool isDigit(char C)
Checks if character C is one of the 10 decimal digits.
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI 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.
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
const SubtargetFeatureKV RISCVFeatureKV[RISCV::NumSubtargetFeatures]
constexpr bool isShiftedUInt(uint64_t x)
Checks if a unsigned integer is an N bit number shifted left by S.
Target & getTheRISCV32beTarget()
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
Used to provide key value pairs for feature and CPU bit flags.