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);
164 void emitPseudoExtend(MCInst &Inst,
bool SignExtend, int64_t Width,
165 SMLoc IDLoc, MCStreamer &Out);
168 void emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc, MCStreamer &Out);
174 bool checkPseudoAddTPRel(MCInst &Inst,
OperandVector &Operands);
180 bool checkPseudoTLSDESCCall(MCInst &Inst,
OperandVector &Operands);
183 bool validateInstruction(MCInst &Inst,
OperandVector &Operands);
189 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
OperandVector &Operands,
193#define GET_ASSEMBLER_HEADER
194#include "RISCVGenAsmMatcher.inc"
221 return parseRegList(Operands,
true);
227 bool ExpectNegative =
false);
229 return parseZcmpStackAdj(Operands,
true);
232 bool parseOperand(
OperandVector &Operands, StringRef Mnemonic);
233 bool parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
234 bool parseDataExpr(
const MCExpr *&Res)
override;
236 bool parseDirectiveOption();
237 bool parseDirectiveAttribute();
238 bool parseDirectiveInsn(SMLoc L);
239 bool parseDirectiveVariantCC();
244 bool resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
245 bool FromOptionDirective);
247 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
248 if (!(getSTI().hasFeature(Feature))) {
249 MCSubtargetInfo &STI = copySTI();
255 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
259 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
260 if (getSTI().hasFeature(Feature)) {
261 MCSubtargetInfo &STI = copySTI();
262 setAvailableFeatures(
267 void pushFeatureBits() {
268 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
269 "These two stacks must be kept synchronized");
270 FeatureBitStack.push_back(getSTI().getFeatureBits());
271 ParserOptionsStack.push_back(ParserOptions);
274 bool popFeatureBits() {
275 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
276 "These two stacks must be kept synchronized");
277 if (FeatureBitStack.empty())
280 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
281 copySTI().setFeatureBits(FeatureBits);
282 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
284 ParserOptions = ParserOptionsStack.pop_back_val();
289 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
290 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
291 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
294 enum RISCVMatchResultTy :
unsigned {
295 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
296#define GET_OPERAND_DIAGNOSTIC_TYPES
297#include "RISCVGenAsmMatcher.inc"
298#undef GET_OPERAND_DIAGNOSTIC_TYPES
302 static bool isSymbolDiff(
const MCExpr *Expr);
304 RISCVAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
305 const MCInstrInfo &MII)
306 : MCTargetAsmParser(STI, MII) {
313 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
315 auto ABIName = StringRef(getTargetOptions().ABIName);
316 if (ABIName.ends_with(
"f") && !getSTI().hasFeature(RISCV::FeatureStdExtF)) {
317 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
318 "doesn't support the F instruction set extension (ignoring "
320 }
else if (ABIName.ends_with(
"d") &&
321 !getSTI().hasFeature(RISCV::FeatureStdExtD)) {
322 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
323 "doesn't support the D instruction set extension (ignoring "
336 getTargetStreamer().emitTargetAttributes(STI,
false);
402 MCRegister OffsetReg;
405 SMLoc StartLoc, EndLoc;
420 RISCVOperand(KindTy K) : Kind(
K) {}
423 RISCVOperand(
const RISCVOperand &o) : MCParsedAsmOperand() {
425 StartLoc =
o.StartLoc;
428 case KindTy::Register:
431 case KindTy::Expression:
434 case KindTy::FPImmediate:
440 case KindTy::SystemRegister:
452 case KindTy::RegList:
455 case KindTy::StackAdj:
456 StackAdj =
o.StackAdj;
464 bool isToken()
const override {
return Kind == KindTy::Token; }
465 bool isReg()
const override {
return Kind == KindTy::Register; }
466 bool isExpr()
const {
return Kind == KindTy::Expression; }
467 bool isV0Reg()
const {
468 return Kind == KindTy::Register &&
Reg.Reg == RISCV::V0;
470 bool isAnyReg()
const {
471 return Kind == KindTy::Register &&
472 (RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.Reg) ||
473 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg.Reg) ||
474 RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg.Reg));
476 bool isAnyRegC()
const {
477 return Kind == KindTy::Register &&
478 (RISCVMCRegisterClasses[RISCV::GPRCRegClassID].contains(
Reg.Reg) ||
479 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg.Reg));
481 bool isImm()
const override {
return isExpr(); }
482 bool isMem()
const override {
return false; }
483 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
484 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
485 bool isRegList()
const {
return Kind == KindTy::RegList; }
486 bool isRegListS0()
const {
487 return Kind == KindTy::RegList && RegList.Encoding !=
RISCVZC::RA;
489 bool isStackAdj()
const {
return Kind == KindTy::StackAdj; }
492 return Kind == KindTy::Register &&
493 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.Reg);
496 bool isYGPR()
const {
497 return Kind == KindTy::Register &&
498 RISCVMCRegisterClasses[RISCV::YGPRRegClassID].contains(
Reg.Reg);
501 bool isGPRPair()
const {
502 return Kind == KindTy::Register &&
503 RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(
Reg.Reg);
506 bool isGPRPairC()
const {
507 return Kind == KindTy::Register &&
508 RISCVMCRegisterClasses[RISCV::GPRPairCRegClassID].contains(
Reg.Reg);
511 bool isGPRPairNoX0()
const {
512 return Kind == KindTy::Register &&
513 RISCVMCRegisterClasses[RISCV::GPRPairNoX0RegClassID].contains(
517 bool isGPRF16()
const {
518 return Kind == KindTy::Register &&
519 RISCVMCRegisterClasses[RISCV::GPRF16RegClassID].contains(
Reg.Reg);
522 bool isGPRF32()
const {
523 return Kind == KindTy::Register &&
524 RISCVMCRegisterClasses[RISCV::GPRF32RegClassID].contains(
Reg.Reg);
527 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
528 bool isGPRAsFPR16()
const {
return isGPRF16() &&
Reg.IsGPRAsFPR; }
529 bool isGPRAsFPR32()
const {
return isGPRF32() &&
Reg.IsGPRAsFPR; }
530 bool isGPRPairAsFPR64()
const {
return isGPRPair() &&
Reg.IsGPRAsFPR; }
532 static bool evaluateConstantExpr(
const MCExpr *Expr, int64_t &Imm) {
534 Imm =
CE->getValue();
543 template <
int N>
bool isBareSimmNLsb0()
const {
548 if (evaluateConstantExpr(
getExpr(), Imm))
549 return isShiftedInt<
N - 1, 1>(fixImmediateForRV32(Imm, isRV64Expr()));
552 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
558 template <
int N>
bool isBareSimmN()
const {
563 if (evaluateConstantExpr(
getExpr(), Imm))
564 return isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
567 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
573 bool isBareSymbol()
const {
576 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
580 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
584 bool isCallSymbol()
const {
587 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
591 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
595 bool isPseudoJumpSymbol()
const {
598 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
602 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
606 bool isTPRelAddSymbol()
const {
609 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
613 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
614 VK == ELF::R_RISCV_TPREL_ADD;
617 bool isTLSDESCCallSymbol()
const {
620 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
624 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
625 VK == ELF::R_RISCV_TLSDESC_CALL;
628 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
632 bool isVTypeI10()
const {
633 if (Kind == KindTy::VType)
637 bool isVTypeI11()
const {
638 if (Kind == KindTy::VType)
643 bool isXSfmmVType()
const {
649 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
652 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
653 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
657 bool isLoadFPImm()
const {
660 if (Kind != KindTy::FPImmediate)
663 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
666 return Idx >= 0 && Idx != 1;
669 bool isImmXLenLI()
const {
675 if (evaluateConstantExpr(
getExpr(), Imm))
678 return RISCVAsmParser::isSymbolDiff(
getExpr());
681 bool isImmXLenLI_Restricted()
const {
685 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
687 return IsConstantImm &&
691 template <
unsigned N>
bool isUImm()
const {
695 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
699 template <
unsigned N,
unsigned S>
bool isUImmShifted()
const {
703 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
707 template <
class Pred>
bool isUImmPred(Pred p)
const {
711 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
712 return IsConstantImm &&
p(Imm);
715 bool isUImmLog2XLen()
const {
716 if (isExpr() && isRV64Expr())
721 bool isUImmLog2XLenNonZero()
const {
722 if (isExpr() && isRV64Expr())
723 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<6>(Imm); });
724 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<5>(Imm); });
727 bool isUImmLog2XLenHalf()
const {
728 if (isExpr() && isRV64Expr())
733 bool isUImm1()
const {
return isUImm<1>(); }
734 bool isUImm2()
const {
return isUImm<2>(); }
735 bool isUImm3()
const {
return isUImm<3>(); }
736 bool isUImm4()
const {
return isUImm<4>(); }
737 bool isUImm5()
const {
return isUImm<5>(); }
738 bool isUImm6()
const {
return isUImm<6>(); }
739 bool isUImm7()
const {
return isUImm<7>(); }
740 bool isUImm8()
const {
return isUImm<8>(); }
741 bool isUImm9()
const {
return isUImm<9>(); }
742 bool isUImm10()
const {
return isUImm<10>(); }
743 bool isUImm11()
const {
return isUImm<11>(); }
744 bool isUImm16()
const {
return isUImm<16>(); }
745 bool isUImm20()
const {
return isUImm<20>(); }
746 bool isUImm32()
const {
return isUImm<32>(); }
747 bool isUImm48()
const {
return isUImm<48>(); }
748 bool isUImm64()
const {
return isUImm<64>(); }
750 bool isUImm5NonZero()
const {
751 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<5>(Imm); });
754 bool isUImm5GT3()
const {
755 return isUImmPred([](int64_t Imm) {
return isUInt<5>(Imm) &&
Imm > 3; });
758 bool isUImm4Plus1()
const {
760 [](int64_t Imm) {
return Imm > 0 &&
isUInt<4>(Imm - 1); });
763 bool isUImm5Plus1()
const {
765 [](int64_t Imm) {
return Imm > 0 &&
isUInt<5>(Imm - 1); });
768 bool isUImm6Plus1()
const {
770 [](int64_t Imm) {
return Imm > 0 &&
isUInt<6>(Imm - 1); });
773 bool isUImm5GE6Plus1()
const {
775 [](int64_t Imm) {
return Imm >= 6 &&
isUInt<5>(Imm - 1); });
778 bool isUImm5Slist()
const {
779 return isUImmPred([](int64_t Imm) {
780 return (Imm == 0) || (
Imm == 1) || (Imm == 2) || (
Imm == 4) ||
781 (Imm == 8) || (
Imm == 16) || (Imm == 15) || (
Imm == 31);
785 bool isUImm7EqXLen()
const {
787 [
this](int64_t Imm) {
return isRV64Expr() ?
Imm == 64 :
Imm == 32; });
790 bool isUImm8GE32()
const {
791 return isUImmPred([](int64_t Imm) {
return isUInt<8>(Imm) &&
Imm >= 32; });
794 bool isRnumArg()
const {
796 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(10); });
799 bool isRnumArg_0_7()
const {
801 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(7); });
804 bool isRnumArg_1_10()
const {
806 [](int64_t Imm) {
return Imm >= INT64_C(1) &&
Imm <= INT64_C(10); });
809 bool isRnumArg_2_14()
const {
811 [](int64_t Imm) {
return Imm >= INT64_C(2) &&
Imm <= INT64_C(14); });
814 template <
unsigned N>
bool isSImm()
const {
818 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
819 return IsConstantImm &&
isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
822 bool isYBNDSWImm()
const {
827 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
831 template <
class Pred>
bool isSImmPred(Pred p)
const {
835 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
836 return IsConstantImm &&
p(fixImmediateForRV32(Imm, isRV64Expr()));
839 bool isSImm5()
const {
return isSImm<5>(); }
840 bool isSImm6()
const {
return isSImm<6>(); }
841 bool isSImm10()
const {
return isSImm<10>(); }
842 bool isSImm11()
const {
return isSImm<11>(); }
843 bool isSImm12()
const {
return isSImm<12>(); }
844 bool isSImm16()
const {
return isSImm<16>(); }
845 bool isSImm26()
const {
return isSImm<26>(); }
847 bool isSImm5NonZero()
const {
848 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<5>(Imm); });
851 bool isSImm6NonZero()
const {
852 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<6>(Imm); });
855 bool isCLUIImm()
const {
856 return isUImmPred([](int64_t Imm) {
857 return (
isUInt<5>(Imm) && Imm != 0) || (
Imm >= 0xfffe0 &&
Imm <= 0xfffff);
861 bool isUImm2Lsb0()
const {
return isUImmShifted<1, 1>(); }
863 bool isUImm5Lsb0()
const {
return isUImmShifted<4, 1>(); }
865 bool isUImm6Lsb0()
const {
return isUImmShifted<5, 1>(); }
867 bool isUImm7Lsb00()
const {
return isUImmShifted<5, 2>(); }
869 bool isUImm7Lsb000()
const {
return isUImmShifted<4, 3>(); }
871 bool isUImm8Lsb00()
const {
return isUImmShifted<6, 2>(); }
873 bool isUImm8Lsb000()
const {
return isUImmShifted<5, 3>(); }
875 bool isUImm9Lsb000()
const {
return isUImmShifted<6, 3>(); }
877 bool isUImm14Lsb00()
const {
return isUImmShifted<12, 2>(); }
879 bool isUImm10Lsb00NonZero()
const {
886 static int64_t fixImmediateForRV32(int64_t Imm,
bool IsRV64Imm) {
892 bool isSImm12LO()
const {
897 if (evaluateConstantExpr(
getExpr(), Imm))
898 return isInt<12>(fixImmediateForRV32(Imm, isRV64Expr()));
901 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
904 VK == ELF::R_RISCV_TLSDESC_ADD_LO12);
907 bool isSImm12Lsb00000()
const {
911 bool isSImm10Lsb0000NonZero()
const {
916 bool isSImm16NonZero()
const {
917 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<16>(Imm); });
920 bool isUImm16NonZero()
const {
921 return isUImmPred([](int64_t Imm) {
return isUInt<16>(Imm) &&
Imm != 0; });
924 bool isSImm20LI()
const {
929 if (evaluateConstantExpr(
getExpr(), Imm))
930 return isInt<20>(fixImmediateForRV32(Imm, isRV64Expr()));
933 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
937 bool isSImm8PLI_B()
const {
return isSImm<8>() || isUImm<8>(); }
938 bool isSImm10PLUI()
const {
return isSImm<10>() || isUImm<10>(); }
940 bool isSImm10PLI_H()
const {
941 return isSImm<10>() || isUImmPred([](int64_t Imm) {
945 bool isSImm10PLI_W()
const {
946 return isSImm<10>() || isUImmPred([](int64_t Imm) {
951 bool isUImm20LUI()
const {
956 if (evaluateConstantExpr(
getExpr(), Imm))
960 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
961 (VK == ELF::R_RISCV_HI20 || VK == ELF::R_RISCV_TPREL_HI20);
964 bool isUImm20AUIPC()
const {
969 if (evaluateConstantExpr(
getExpr(), Imm))
973 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
975 VK == ELF::R_RISCV_TLS_GOT_HI20 || VK == ELF::R_RISCV_TLS_GD_HI20 ||
976 VK == ELF::R_RISCV_TLSDESC_HI20);
979 bool isImmZero()
const {
980 return isUImmPred([](int64_t Imm) {
return 0 ==
Imm; });
983 bool isImmThree()
const {
984 return isUImmPred([](int64_t Imm) {
return 3 ==
Imm; });
987 bool isImmFour()
const {
988 return isUImmPred([](int64_t Imm) {
return 4 ==
Imm; });
991 bool isImm5Zibi()
const {
993 [](int64_t Imm) {
return (Imm != 0 &&
isUInt<5>(Imm)) ||
Imm == -1; });
996 bool isSImm5Plus1()
const {
1001 bool isSImm18()
const {
1002 return isSImmPred([](int64_t Imm) {
return isInt<18>(Imm); });
1005 bool isSImm18Lsb0()
const {
1009 bool isSImm19Lsb00()
const {
1013 bool isSImm20Lsb000()
const {
1017 bool isSImm32Lsb0()
const {
1022 SMLoc getStartLoc()
const override {
return StartLoc; }
1024 SMLoc getEndLoc()
const override {
return EndLoc; }
1027 bool isRV64Expr()
const {
1028 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1032 MCRegister
getReg()
const override {
1033 assert(Kind == KindTy::Register &&
"Invalid type access!");
1037 StringRef getSysReg()
const {
1038 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
1039 return StringRef(SysReg.Data, SysReg.Length);
1042 const MCExpr *
getExpr()
const {
1043 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1047 uint64_t getFPConst()
const {
1048 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1053 assert(Kind == KindTy::Token &&
"Invalid type access!");
1057 unsigned getVType()
const {
1058 assert(Kind == KindTy::VType &&
"Invalid type access!");
1063 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1067 unsigned getFence()
const {
1068 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1072 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1081 case KindTy::Expression:
1084 OS <<
' ' << (Expr.IsRV64 ?
"rv64" :
"rv32") <<
'>';
1086 case KindTy::FPImmediate:
1087 OS <<
"<fpimm: " << FPImm.Val <<
">";
1089 case KindTy::Register:
1091 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1096 case KindTy::SystemRegister:
1097 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1106 OS << roundingModeToString(getFRM());
1114 case KindTy::RegList:
1119 case KindTy::StackAdj:
1120 OS <<
"<stackadj: ";
1124 case KindTy::RegReg:
1125 OS <<
"<RegReg: BaseReg " <<
RegName(
RegReg.BaseReg) <<
" OffsetReg "
1131 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1132 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1139 static std::unique_ptr<RISCVOperand>
1140 createReg(MCRegister
Reg, SMLoc S, SMLoc
E,
bool IsGPRAsFPR =
false) {
1141 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1143 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1149 static std::unique_ptr<RISCVOperand> createExpr(
const MCExpr *Val, SMLoc S,
1150 SMLoc
E,
bool IsRV64) {
1151 auto Op = std::make_unique<RISCVOperand>(KindTy::Expression);
1152 Op->Expr.Expr = Val;
1153 Op->Expr.IsRV64 = IsRV64;
1159 static std::unique_ptr<RISCVOperand> createFPImm(uint64_t Val, SMLoc S) {
1160 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1161 Op->FPImm.Val = Val;
1167 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1168 unsigned Encoding) {
1169 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1170 Op->SysReg.Data = Str.data();
1171 Op->SysReg.Length = Str.size();
1178 static std::unique_ptr<RISCVOperand>
1180 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1187 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val, SMLoc S) {
1188 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1189 Op->Fence.Val = Val;
1195 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI, SMLoc S) {
1196 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1197 Op->VType.Val = VTypeI;
1203 static std::unique_ptr<RISCVOperand> createRegList(
unsigned RlistEncode,
1205 auto Op = std::make_unique<RISCVOperand>(KindTy::RegList);
1211 static std::unique_ptr<RISCVOperand>
1212 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {
1213 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1215 Op->RegReg.OffsetReg = OffsetReg;
1221 static std::unique_ptr<RISCVOperand> createStackAdj(
unsigned StackAdj, SMLoc S) {
1222 auto Op = std::make_unique<RISCVOperand>(KindTy::StackAdj);
1223 Op->StackAdj.Val = StackAdj;
1228 static void addExpr(MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1229 assert(Expr &&
"Expr shouldn't be null!");
1231 bool IsConstant = evaluateConstantExpr(Expr, Imm);
1241 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1242 assert(
N == 1 &&
"Invalid number of operands!");
1246 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1247 assert(
N == 1 &&
"Invalid number of operands!");
1248 addExpr(Inst,
getExpr(), isRV64Expr());
1251 template <
unsigned Bits>
1252 void addSExtImmOperands(MCInst &Inst,
unsigned N)
const {
1253 assert(
N == 1 &&
"Invalid number of operands!");
1260 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
1261 assert(
N == 1 &&
"Invalid number of operands!");
1263 addExpr(Inst,
getExpr(), isRV64Expr());
1268 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1272 void addFenceArgOperands(MCInst &Inst,
unsigned N)
const {
1273 assert(
N == 1 &&
"Invalid number of operands!");
1277 void addCSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
1278 assert(
N == 1 &&
"Invalid number of operands!");
1285 void addVTypeIOperands(MCInst &Inst,
unsigned N)
const {
1286 assert(
N == 1 &&
"Invalid number of operands!");
1288 if (Kind == KindTy::Expression) {
1289 [[maybe_unused]]
bool IsConstantImm =
1290 evaluateConstantExpr(
getExpr(), Imm);
1291 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1298 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1299 assert(
N == 1 &&
"Invalid number of operands!");
1303 void addRegRegOperands(MCInst &Inst,
unsigned N)
const {
1304 assert(
N == 2 &&
"Invalid number of operands!");
1309 void addStackAdjOperands(MCInst &Inst,
unsigned N)
const {
1310 assert(
N == 1 &&
"Invalid number of operands!");
1314 void addFRMArgOperands(MCInst &Inst,
unsigned N)
const {
1315 assert(
N == 1 &&
"Invalid number of operands!");
1321#define GET_REGISTER_MATCHER
1322#define GET_SUBTARGET_FEATURE_NAME
1323#define GET_MATCHER_IMPLEMENTATION
1324#define GET_MNEMONIC_SPELL_CHECKER
1325#include "RISCVGenAsmMatcher.inc"
1328 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1329 return Reg - RISCV::F0_D + RISCV::F0_H;
1333 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1334 return Reg - RISCV::F0_D + RISCV::F0_F;
1338 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1339 return Reg - RISCV::F0_D + RISCV::F0_Q;
1343 assert(
Reg >= RISCV::X0 &&
Reg <= RISCV::X31 &&
"Invalid register");
1344 return Reg - RISCV::X0 + RISCV::X0_Y;
1349 unsigned RegClassID;
1350 if (Kind == MCK_VRM2)
1351 RegClassID = RISCV::VRM2RegClassID;
1352 else if (Kind == MCK_VRM4)
1353 RegClassID = RISCV::VRM4RegClassID;
1354 else if (Kind == MCK_VRM8)
1355 RegClassID = RISCV::VRM8RegClassID;
1359 &RISCVMCRegisterClasses[RegClassID]);
1363 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1364 return Reg - RISCV::F0_D + RISCV::F0_Q2;
1369 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1371 return Match_InvalidOperand;
1373 MCRegister
Reg =
Op.getReg();
1375 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg);
1377 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg);
1378 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg);
1380 if (
Op.isGPR() && Kind == MCK_YGPR) {
1383 return Match_Success;
1385 if (IsRegFPR64 && Kind == MCK_FPR256) {
1387 return Match_Success;
1389 if (IsRegFPR64 && Kind == MCK_FPR128) {
1391 return Match_Success;
1395 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1396 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1398 return Match_Success;
1402 if (IsRegFPR64 && Kind == MCK_FPR16) {
1404 return Match_Success;
1406 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1407 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_H;
1408 return Match_Success;
1410 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1411 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_W;
1412 return Match_Success;
1419 if (RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg) &&
1420 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1422 return Match_Success;
1426 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1429 return Match_InvalidOperand;
1430 return Match_Success;
1432 return Match_InvalidOperand;
1435bool RISCVAsmParser::generateImmOutOfRangeError(
1436 SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
1437 const Twine &Msg =
"immediate must be an integer in the range") {
1438 return Error(ErrorLoc, Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]");
1441bool RISCVAsmParser::generateImmOutOfRangeError(
1443 const Twine &Msg =
"immediate must be an integer in the range") {
1444 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1445 return generateImmOutOfRangeError(ErrorLoc,
Lower,
Upper, Msg);
1448bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1451 uint64_t &ErrorInfo,
1452 bool MatchingInlineAsm) {
1454 FeatureBitset MissingFeatures;
1456 auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
1462 if (validateInstruction(Inst, Operands))
1464 return processInstruction(Inst, IDLoc, Operands, Out);
1465 case Match_MissingFeature: {
1466 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1467 bool FirstFeature =
true;
1468 std::string Msg =
"instruction requires the following:";
1469 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1470 if (MissingFeatures[i]) {
1471 Msg += FirstFeature ?
" " :
", ";
1473 FirstFeature =
false;
1476 return Error(IDLoc, Msg);
1478 case Match_MnemonicFail: {
1479 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1480 std::string Suggestion = RISCVMnemonicSpellCheck(
1481 ((RISCVOperand &)*Operands[0]).
getToken(), FBS, 0);
1482 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1484 case Match_InvalidOperand: {
1485 SMLoc ErrorLoc = IDLoc;
1486 if (ErrorInfo != ~0ULL) {
1487 if (ErrorInfo >= Operands.
size())
1488 return Error(ErrorLoc,
"too few operands for instruction");
1490 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1491 if (ErrorLoc == SMLoc())
1494 return Error(ErrorLoc,
"invalid operand for instruction");
1501 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1502 SMLoc ErrorLoc = IDLoc;
1503 if (ErrorInfo != ~0ULL && ErrorInfo >= Operands.
size())
1504 return Error(ErrorLoc,
"too few operands for instruction");
1510 case Match_InvalidImmXLenLI:
1512 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1513 return Error(ErrorLoc,
"operand must be a constant 64-bit integer");
1515 return generateImmOutOfRangeError(Operands, ErrorInfo,
1516 std::numeric_limits<int32_t>::min(),
1517 std::numeric_limits<uint32_t>::max());
1518 case Match_InvalidImmXLenLI_Restricted:
1520 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1521 return Error(ErrorLoc,
"operand either must be a constant 64-bit integer "
1522 "or a bare symbol name");
1524 return generateImmOutOfRangeError(
1525 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1526 std::numeric_limits<uint32_t>::max(),
1527 "operand either must be a bare symbol name or an immediate integer in "
1529 case Match_InvalidUImmLog2XLen:
1531 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1532 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1533 case Match_InvalidUImmLog2XLenNonZero:
1535 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
1536 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1537 case Match_InvalidUImm1:
1538 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
1539 case Match_InvalidUImm2:
1540 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
1541 case Match_InvalidUImm2Lsb0:
1542 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 2,
1543 "immediate must be one of");
1544 case Match_InvalidUImm3:
1545 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
1546 case Match_InvalidUImm4:
1547 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
1548 case Match_InvalidUImm4Plus1:
1549 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4));
1550 case Match_InvalidUImm5:
1551 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1552 case Match_InvalidUImm5NonZero:
1553 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1554 case Match_InvalidUImm5GT3:
1555 return generateImmOutOfRangeError(Operands, ErrorInfo, 4, (1 << 5) - 1);
1556 case Match_InvalidUImm5Plus1:
1557 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));
1558 case Match_InvalidUImm5GE6Plus1:
1559 return generateImmOutOfRangeError(Operands, ErrorInfo, 6, (1 << 5));
1560 case Match_InvalidUImm5Slist: {
1561 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1562 return Error(ErrorLoc,
1563 "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31");
1565 case Match_InvalidUImm6:
1566 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1567 case Match_InvalidUImm6Plus1:
1568 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6));
1569 case Match_InvalidUImm7:
1570 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
1571 case Match_InvalidUImm8:
1572 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
1573 case Match_InvalidUImm8GE32:
1574 return generateImmOutOfRangeError(Operands, ErrorInfo, 32, (1 << 8) - 1);
1575 case Match_InvalidSImm5:
1576 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4),
1578 case Match_InvalidSImm5NonZero:
1579 return generateImmOutOfRangeError(
1580 Operands, ErrorInfo, -(1 << 4), (1 << 4) - 1,
1581 "immediate must be non-zero in the range");
1582 case Match_InvalidSImm6:
1583 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
1585 case Match_InvalidSImm6NonZero:
1586 return generateImmOutOfRangeError(
1587 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
1588 "immediate must be non-zero in the range");
1589 case Match_InvalidCLUIImm:
1590 return generateImmOutOfRangeError(
1591 Operands, ErrorInfo, 1, (1 << 5) - 1,
1592 "immediate must be in [0xfffe0, 0xfffff] or");
1593 case Match_InvalidUImm5Lsb0:
1594 return generateImmOutOfRangeError(
1595 Operands, ErrorInfo, 0, (1 << 5) - 2,
1596 "immediate must be a multiple of 2 bytes in the range");
1597 case Match_InvalidUImm6Lsb0:
1598 return generateImmOutOfRangeError(
1599 Operands, ErrorInfo, 0, (1 << 6) - 2,
1600 "immediate must be a multiple of 2 bytes in the range");
1601 case Match_InvalidUImm7Lsb00:
1602 return generateImmOutOfRangeError(
1603 Operands, ErrorInfo, 0, (1 << 7) - 4,
1604 "immediate must be a multiple of 4 bytes in the range");
1605 case Match_InvalidUImm8Lsb00:
1606 return generateImmOutOfRangeError(
1607 Operands, ErrorInfo, 0, (1 << 8) - 4,
1608 "immediate must be a multiple of 4 bytes in the range");
1609 case Match_InvalidUImm8Lsb000:
1610 return generateImmOutOfRangeError(
1611 Operands, ErrorInfo, 0, (1 << 8) - 8,
1612 "immediate must be a multiple of 8 bytes in the range");
1613 case Match_InvalidUImm9:
1614 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 9) - 1,
1615 "immediate offset must be in the range");
1616 case Match_InvalidBareSImm9Lsb0:
1617 return generateImmOutOfRangeError(
1618 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
1619 "immediate must be a multiple of 2 bytes in the range");
1620 case Match_InvalidUImm9Lsb000:
1621 return generateImmOutOfRangeError(
1622 Operands, ErrorInfo, 0, (1 << 9) - 8,
1623 "immediate must be a multiple of 8 bytes in the range");
1624 case Match_InvalidSImm8PLI_B:
1625 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
1627 case Match_InvalidSImm10:
1628 case Match_InvalidSImm10PLI_H:
1629 case Match_InvalidSImm10PLI_W:
1630 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
1632 case Match_InvalidSImm10PLUI:
1633 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
1635 case Match_InvalidUImm10Lsb00NonZero:
1636 return generateImmOutOfRangeError(
1637 Operands, ErrorInfo, 4, (1 << 10) - 4,
1638 "immediate must be a multiple of 4 bytes in the range");
1639 case Match_InvalidSImm10Lsb0000NonZero:
1640 return generateImmOutOfRangeError(
1641 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
1642 "immediate must be a multiple of 16 bytes and non-zero in the range");
1643 case Match_InvalidSImm11:
1644 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 10),
1646 case Match_InvalidBareSImm11Lsb0:
1647 return generateImmOutOfRangeError(
1648 Operands, ErrorInfo, -(1 << 10), (1 << 10) - 2,
1649 "immediate must be a multiple of 2 bytes in the range");
1650 case Match_InvalidUImm10:
1651 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 10) - 1);
1652 case Match_InvalidUImm11:
1653 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
1654 case Match_InvalidUImm14Lsb00:
1655 return generateImmOutOfRangeError(
1656 Operands, ErrorInfo, 0, (1 << 14) - 4,
1657 "immediate must be a multiple of 4 bytes in the range");
1658 case Match_InvalidUImm16NonZero:
1659 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16) - 1);
1660 case Match_InvalidSImm12:
1661 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11),
1663 case Match_InvalidSImm12LO:
1664 return generateImmOutOfRangeError(
1665 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
1666 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo specifier or an "
1667 "integer in the range");
1668 case Match_InvalidBareSImm12Lsb0:
1669 return generateImmOutOfRangeError(
1670 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
1671 "immediate must be a multiple of 2 bytes in the range");
1672 case Match_InvalidSImm12Lsb00000:
1673 return generateImmOutOfRangeError(
1674 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 32,
1675 "immediate must be a multiple of 32 bytes in the range");
1676 case Match_InvalidBareSImm13Lsb0:
1677 return generateImmOutOfRangeError(
1678 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
1679 "immediate must be a multiple of 2 bytes in the range");
1680 case Match_InvalidSImm16:
1681 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 15),
1683 case Match_InvalidSImm16NonZero:
1684 return generateImmOutOfRangeError(
1685 Operands, ErrorInfo, -(1 << 15), (1 << 15) - 1,
1686 "immediate must be non-zero in the range");
1687 case Match_InvalidSImm20LI:
1688 return generateImmOutOfRangeError(
1689 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 1,
1690 "operand must be a symbol with a %qc.abs20 specifier or an integer "
1692 case Match_InvalidUImm20LUI:
1693 return generateImmOutOfRangeError(
1694 Operands, ErrorInfo, 0, (1 << 20) - 1,
1695 "operand must be a symbol with "
1696 "%hi/%tprel_hi specifier or an integer in "
1698 case Match_InvalidUImm20:
1699 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1);
1700 case Match_InvalidUImm20AUIPC:
1701 return generateImmOutOfRangeError(
1702 Operands, ErrorInfo, 0, (1 << 20) - 1,
1703 "operand must be a symbol with a "
1704 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
1706 "an integer in the range");
1707 case Match_InvalidBareSImm21Lsb0:
1708 return generateImmOutOfRangeError(
1709 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
1710 "immediate must be a multiple of 2 bytes in the range");
1711 case Match_InvalidCSRSystemRegister: {
1712 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1,
1713 "operand must be a valid system register "
1714 "name or an integer in the range");
1716 case Match_InvalidImm5Zibi:
1717 return generateImmOutOfRangeError(
1718 Operands, ErrorInfo, -1, (1 << 5) - 1,
1719 "immediate must be non-zero in the range");
1720 case Match_InvalidVTypeI: {
1721 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1722 return generateVTypeError(ErrorLoc);
1724 case Match_InvalidSImm5Plus1: {
1725 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1,
1727 "immediate must be in the range");
1729 case Match_InvalidSImm18:
1730 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 17),
1732 case Match_InvalidSImm18Lsb0:
1733 return generateImmOutOfRangeError(
1734 Operands, ErrorInfo, -(1 << 17), (1 << 17) - 2,
1735 "immediate must be a multiple of 2 bytes in the range");
1736 case Match_InvalidSImm19Lsb00:
1737 return generateImmOutOfRangeError(
1738 Operands, ErrorInfo, -(1 << 18), (1 << 18) - 4,
1739 "immediate must be a multiple of 4 bytes in the range");
1740 case Match_InvalidSImm20Lsb000:
1741 return generateImmOutOfRangeError(
1742 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 8,
1743 "immediate must be a multiple of 8 bytes in the range");
1744 case Match_InvalidSImm26:
1745 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 25),
1748 case Match_InvalidBareSymbolQC_E_LI:
1751 case Match_InvalidBareSImm32:
1752 return generateImmOutOfRangeError(Operands, ErrorInfo,
1753 std::numeric_limits<int32_t>::min(),
1754 std::numeric_limits<uint32_t>::max());
1755 case Match_InvalidBareSImm32Lsb0:
1756 return generateImmOutOfRangeError(
1757 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1758 std::numeric_limits<int32_t>::max() - 1,
1759 "operand must be a multiple of 2 bytes in the range");
1760 case Match_InvalidRnumArg: {
1761 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10);
1763 case Match_InvalidStackAdj: {
1764 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1767 "stack adjustment is invalid for this instruction and register list");
1769 case Match_InvalidYBNDSWImm: {
1770 const SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1771 return Error(ErrorLoc,
"immediate must be an integer in the range "
1772 "[1, 255], a multiple of 8 in the range [256, 504], "
1773 "or a multiple of 16 in the range [512, 4096]");
1775 case Match_InvalidUImm7EqXLen: {
1776 const SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1777 return Error(ErrorLoc,
"immediate must be an integer equal to XLEN (" +
1778 Twine(isRV64() ?
"64" :
"32") +
")");
1782 if (
const char *MatchDiag = getMatchKindDiag((RISCVMatchResultTy)Result)) {
1783 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1784 return Error(ErrorLoc, MatchDiag);
1794MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name)
const {
1803 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1804 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1805 static_assert(RISCV::F0_D < RISCV::F0_Q,
"FPR matching must be updated");
1808 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1813bool RISCVAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1815 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1816 return Error(StartLoc,
"invalid register name");
1820ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1822 const AsmToken &Tok = getParser().getTok();
1825 StringRef
Name = getLexer().getTok().getIdentifier();
1835ParseStatus RISCVAsmParser::parseRegister(
OperandVector &Operands,
1837 SMLoc FirstS = getLoc();
1838 bool HadParens =
false;
1845 size_t ReadCount = getLexer().peekTokens(Buf);
1848 LParen = getParser().getTok();
1853 switch (getLexer().getKind()) {
1856 getLexer().UnLex(LParen);
1859 StringRef
Name = getLexer().getTok().getIdentifier();
1864 getLexer().UnLex(LParen);
1868 Operands.
push_back(RISCVOperand::createToken(
"(", FirstS));
1870 SMLoc
E = getTok().getEndLoc();
1877 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
1883ParseStatus RISCVAsmParser::parseInsnDirectiveOpcode(
OperandVector &Operands) {
1888 switch (getLexer().getKind()) {
1898 if (getParser().parseExpression(Res,
E))
1903 int64_t
Imm =
CE->getValue();
1905 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1914 if (getParser().parseIdentifier(Identifier))
1917 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1920 "Unexpected opcode");
1923 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1933 return generateImmOutOfRangeError(
1935 "opcode must be a valid opcode name or an immediate in the range");
1938ParseStatus RISCVAsmParser::parseInsnCDirectiveOpcode(
OperandVector &Operands) {
1943 switch (getLexer().getKind()) {
1953 if (getParser().parseExpression(Res,
E))
1958 int64_t
Imm =
CE->getValue();
1959 if (Imm >= 0 && Imm <= 2) {
1960 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1969 if (getParser().parseIdentifier(Identifier))
1973 if (Identifier ==
"C0")
1975 else if (Identifier ==
"C1")
1977 else if (Identifier ==
"C2")
1984 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1993 return generateImmOutOfRangeError(
1995 "opcode must be a valid opcode name or an immediate in the range");
1998ParseStatus RISCVAsmParser::parseCSRSystemRegister(
OperandVector &Operands) {
2002 auto SysRegFromConstantInt = [
this](
const MCExpr *
E, SMLoc S) {
2004 int64_t
Imm =
CE->getValue();
2006 auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
2010 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2013 return RISCVOperand::createSysReg(
Reg.Name, S, Imm);
2017 return RISCVOperand::createSysReg(
"", S, Imm);
2020 return std::unique_ptr<RISCVOperand>();
2023 switch (getLexer().getKind()) {
2033 if (getParser().parseExpression(Res))
2036 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
2041 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2045 if (getParser().parseIdentifier(Identifier))
2048 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
2051 if (SysReg->IsDeprecatedName) {
2053 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
2055 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2057 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
2063 const auto &FeatureBits = getSTI().getFeatureBits();
2064 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
2066 return SysReg->FeaturesRequired[Feature.Value];
2068 auto ErrorMsg = std::string(
"system register '") + SysReg->Name +
"' ";
2069 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
2070 ErrorMsg +=
"is RV32 only";
2072 ErrorMsg +=
" and ";
2076 "requires '" + std::string(Feature->Key) +
"' to be enabled";
2079 return Error(S, ErrorMsg);
2082 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
2097 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2098 "operand must be a valid system register "
2099 "name or an integer in the range");
2103 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2110ParseStatus RISCVAsmParser::parseFPImm(
OperandVector &Operands) {
2115 StringRef
Identifier = getTok().getIdentifier();
2116 if (
Identifier.compare_insensitive(
"inf") == 0) {
2119 getTok().getEndLoc(), isRV64()));
2120 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2123 getTok().getEndLoc(), isRV64()));
2124 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2127 getTok().getEndLoc(), isRV64()));
2129 return TokError(
"invalid floating point literal");
2140 const AsmToken &Tok = getTok();
2142 return TokError(
"invalid floating point immediate");
2145 APFloat RealVal(APFloat::IEEEdouble());
2147 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2149 return TokError(
"invalid floating point representation");
2152 RealVal.changeSign();
2154 Operands.
push_back(RISCVOperand::createFPImm(
2155 RealVal.bitcastToAPInt().getZExtValue(), S));
2162ParseStatus RISCVAsmParser::parseExpression(
OperandVector &Operands) {
2167 switch (getLexer().getKind()) {
2179 if (getParser().parseExpression(Res,
E))
2183 return parseOperandWithSpecifier(Operands);
2186 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2190ParseStatus RISCVAsmParser::parseOperandWithSpecifier(
OperandVector &Operands) {
2196 const MCExpr *Expr =
nullptr;
2197 bool Failed = parseExprWithSpecifier(Expr,
E);
2199 Operands.
push_back(RISCVOperand::createExpr(Expr, S,
E, isRV64()));
2203bool RISCVAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
2204 SMLoc Loc = getLoc();
2206 return TokError(
"expected '%' relocation specifier");
2207 StringRef
Identifier = getParser().getTok().getIdentifier();
2210 return TokError(
"invalid relocation specifier");
2216 const MCExpr *SubExpr;
2217 if (getParser().parseParenExpression(SubExpr,
E))
2224bool RISCVAsmParser::parseDataExpr(
const MCExpr *&Res) {
2227 return parseExprWithSpecifier(Res,
E);
2228 return getParser().parseExpression(Res);
2231ParseStatus RISCVAsmParser::parseBareSymbol(
OperandVector &Operands) {
2238 StringRef
Identifier = getTok().getIdentifier();
2248 if (getParser().parseExpression(Res,
E))
2251 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2255ParseStatus RISCVAsmParser::parseCallSymbol(
OperandVector &Operands) {
2261 std::string
Identifier(getTok().getIdentifier());
2267 SMLoc Loc = getLoc();
2268 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2269 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2283 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2287ParseStatus RISCVAsmParser::parsePseudoJumpSymbol(
OperandVector &Operands) {
2292 if (getParser().parseExpression(Res,
E))
2295 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef)
2296 return Error(S,
"operand must be a valid jump target");
2299 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2303ParseStatus RISCVAsmParser::parseJALOffset(
OperandVector &Operands) {
2317 return parseExpression(Operands);
2320bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2321 unsigned &Sew,
unsigned &Lmul,
2322 bool &Fractional,
bool &TailAgnostic,
2323 bool &MaskAgnostic,
bool &AltFmt) {
2328 if (State < VTypeState::SeenSew &&
Identifier.consume_front(
"e")) {
2330 if (Identifier ==
"16alt") {
2333 }
else if (Identifier ==
"8alt") {
2343 State = VTypeState::SeenSew;
2347 if (State < VTypeState::SeenLmul &&
Identifier.consume_front(
"m")) {
2350 if (Identifier ==
"a" || Identifier ==
"u") {
2352 State = VTypeState::SeenMaskPolicy;
2363 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2364 unsigned MinLMUL = ELEN / 8;
2367 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2368 Twine(MinLMUL) +
" is reserved");
2371 State = VTypeState::SeenLmul;
2375 if (State < VTypeState::SeenTailPolicy &&
Identifier.starts_with(
"t")) {
2376 if (Identifier ==
"ta")
2377 TailAgnostic =
true;
2378 else if (Identifier ==
"tu")
2379 TailAgnostic =
false;
2383 State = VTypeState::SeenTailPolicy;
2387 if (State < VTypeState::SeenMaskPolicy &&
Identifier.starts_with(
"m")) {
2388 if (Identifier ==
"ma")
2389 MaskAgnostic =
true;
2390 else if (Identifier ==
"mu")
2391 MaskAgnostic =
false;
2395 State = VTypeState::SeenMaskPolicy;
2402ParseStatus RISCVAsmParser::parseVTypeI(
OperandVector &Operands) {
2408 bool Fractional =
false;
2409 bool TailAgnostic =
false;
2410 bool MaskAgnostic =
false;
2413 VTypeState State = VTypeState::SeenNothingYet;
2415 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2416 MaskAgnostic, AltFmt)) {
2418 if (State == VTypeState::SeenNothingYet)
2427 State == VTypeState::SeenNothingYet)
2428 return generateVTypeError(S);
2432 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2433 unsigned MaxSEW = ELEN / Lmul;
2435 if (MaxSEW >= 8 && Sew > MaxSEW)
2436 Warning(S,
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2437 " and LMUL == mf" + Twine(Lmul) +
2438 " may not be compatible with all RVV implementations");
2443 Operands.
push_back(RISCVOperand::createVType(VTypeI, S));
2447bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2448 if (STI->
hasFeature(RISCV::FeatureStdExtZvfbfa) ||
2449 STI->
hasFeature(RISCV::FeatureStdExtZvfofp8min) ||
2450 STI->
hasFeature(RISCV::FeatureVendorXSfvfbfexp16e) ||
2451 STI->
hasFeature(RISCV::FeatureStdExtZvqwbdota8i) ||
2452 STI->
hasFeature(RISCV::FeatureStdExtZvqwbdota16i) ||
2453 STI->
hasFeature(RISCV::FeatureStdExtZvfqwbdota8f) ||
2454 STI->
hasFeature(RISCV::FeatureStdExtZvfwbdota16bf))
2458 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2462 "e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2465ParseStatus RISCVAsmParser::parseXSfmmVType(
OperandVector &Operands) {
2482 if (Identifier !=
"16alt")
2511 Operands.
push_back(RISCVOperand::createVType(
2517 return generateXSfmmVTypeError(S);
2520bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
2521 return Error(ErrorLoc,
"operand must be e[8|16|16alt|32|64],w[1|2|4]");
2524ParseStatus RISCVAsmParser::parseMaskReg(
OperandVector &Operands) {
2528 StringRef
Name = getLexer().getTok().getIdentifier();
2529 if (!
Name.consume_back(
".t"))
2530 return Error(getLoc(),
"expected '.t' suffix");
2535 if (
Reg != RISCV::V0)
2538 SMLoc
E = getTok().getEndLoc();
2544ParseStatus RISCVAsmParser::parseVScaleReg(
OperandVector &Operands) {
2548 StringRef
Name = getLexer().getTok().getIdentifier();
2549 if (!
Name.consume_back(
".scale"))
2550 return Error(getLoc(),
"expected '.scale' suffix");
2555 if (
Reg != RISCV::V0)
2558 SMLoc
E = getTok().getEndLoc();
2564ParseStatus RISCVAsmParser::parseGPRAsFPR64(
OperandVector &Operands) {
2565 if (!isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2568 return parseGPRAsFPR(Operands);
2571ParseStatus RISCVAsmParser::parseGPRAsFPR(
OperandVector &Operands) {
2575 StringRef
Name = getLexer().getTok().getIdentifier();
2581 SMLoc
E = getTok().getEndLoc();
2583 Operands.
push_back(RISCVOperand::createReg(
2584 Reg, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2588ParseStatus RISCVAsmParser::parseGPRPairAsFPR64(
OperandVector &Operands) {
2589 if (isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2595 StringRef
Name = getLexer().getTok().getIdentifier();
2601 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2604 if ((
Reg - RISCV::X0) & 1) {
2607 if (getSTI().hasFeature(RISCV::FeatureStdExtZfinx))
2608 return TokError(
"double precision floating point operands must use even "
2609 "numbered X register");
2614 SMLoc
E = getTok().getEndLoc();
2617 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2619 Reg, RISCV::sub_gpr_even,
2620 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2621 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2625template <
bool IsRV64>
2626ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands) {
2627 return parseGPRPair(Operands, IsRV64);
2630ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands,
2637 if (!IsRV64Inst && isRV64())
2643 StringRef
Name = getLexer().getTok().getIdentifier();
2649 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2652 if ((
Reg - RISCV::X0) & 1)
2653 return TokError(
"register must be even");
2656 SMLoc
E = getTok().getEndLoc();
2659 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2661 Reg, RISCV::sub_gpr_even,
2662 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2663 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E));
2667ParseStatus RISCVAsmParser::parseFRMArg(
OperandVector &Operands) {
2670 "operand must be a valid floating point rounding mode mnemonic");
2672 StringRef Str = getLexer().getTok().getIdentifier();
2677 "operand must be a valid floating point rounding mode mnemonic");
2679 Operands.
push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2684ParseStatus RISCVAsmParser::parseFenceArg(
OperandVector &Operands) {
2685 const AsmToken &Tok = getLexer().getTok();
2691 Operands.
push_back(RISCVOperand::createFenceArg(0, getLoc()));
2705 for (
char c : Str) {
2734 Operands.
push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2740 return TokError(
"operand must be formed of letters selected in-order from "
2744ParseStatus RISCVAsmParser::parseMemOpBaseReg(
OperandVector &Operands) {
2747 Operands.
push_back(RISCVOperand::createToken(
"(", getLoc()));
2749 if (!parseRegister(Operands).isSuccess())
2750 return Error(getLoc(),
"expected register");
2754 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
2759ParseStatus RISCVAsmParser::parseZeroOffsetMemOp(
OperandVector &Operands) {
2778 std::unique_ptr<RISCVOperand> OptionalImmOp;
2785 SMLoc ImmStart = getLoc();
2786 if (getParser().parseIntToken(ImmVal,
2787 "expected '(' or optional integer offset"))
2792 SMLoc ImmEnd = getLoc();
2795 ImmStart, ImmEnd, isRV64());
2799 OptionalImmOp ?
"expected '(' after optional integer offset"
2800 :
"expected '(' or optional integer offset"))
2803 if (!parseRegister(Operands).isSuccess())
2804 return Error(getLoc(),
"expected register");
2810 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2812 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2813 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2818ParseStatus RISCVAsmParser::parseRegReg(
OperandVector &Operands) {
2824 StringRef OffsetRegName = getLexer().getTok().getIdentifier();
2827 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(OffsetReg))
2828 return Error(getLoc(),
"expected GPR register");
2835 return Error(getLoc(),
"expected GPR register");
2837 StringRef BaseRegName = getLexer().getTok().getIdentifier();
2840 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(BaseReg))
2841 return Error(getLoc(),
"expected GPR register");
2847 Operands.
push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));
2859ParseStatus RISCVAsmParser::parseRegList(
OperandVector &Operands,
2860 bool MustIncludeS0) {
2872 return Error(getLoc(),
"invalid register");
2874 StringRef
RegName = getTok().getIdentifier();
2877 return Error(getLoc(),
"invalid register");
2880 UsesXRegs =
RegName[0] ==
'x';
2881 if (
Reg != RISCV::X1)
2882 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2883 }
else if (RegEnd == RISCV::X1) {
2884 if (
Reg != RISCV::X8 || (UsesXRegs != (
RegName[0] ==
'x')))
2885 return Error(getLoc(), Twine(
"register must be '") +
2886 (UsesXRegs ?
"x8" :
"s0") +
"'");
2887 }
else if (RegEnd == RISCV::X9 && UsesXRegs) {
2888 if (
Reg != RISCV::X18 || (
RegName[0] !=
'x'))
2889 return Error(getLoc(),
"register must be 'x18'");
2891 return Error(getLoc(),
"too many register ranges");
2898 SMLoc MinusLoc = getLoc();
2900 if (RegEnd == RISCV::X1)
2901 return Error(MinusLoc, Twine(
"register '") + (UsesXRegs ?
"x1" :
"ra") +
2902 "' cannot start a multiple register range");
2905 return Error(getLoc(),
"invalid register");
2907 StringRef
RegName = getTok().getIdentifier();
2910 return Error(getLoc(),
"invalid register");
2912 if (RegEnd == RISCV::X8) {
2913 if ((
Reg != RISCV::X9 &&
2915 (UsesXRegs != (
RegName[0] ==
'x'))) {
2917 return Error(getLoc(),
"register must be 'x9'");
2918 return Error(getLoc(),
"register must be in the range 's1' to 's11'");
2920 }
else if (RegEnd == RISCV::X18) {
2922 return Error(getLoc(),
2923 "register must be in the range 'x19' to 'x27'");
2936 if (RegEnd == RISCV::X26)
2937 return Error(S,
"invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "
2938 "x18-x26}' is not supported");
2944 return Error(S,
"register list must include 's0' or 'x8'");
2946 Operands.
push_back(RISCVOperand::createRegList(Encode, S));
2951ParseStatus RISCVAsmParser::parseZcmpStackAdj(
OperandVector &Operands,
2952 bool ExpectNegative) {
2961 auto *RegListOp =
static_cast<RISCVOperand *
>(Operands.
back().
get());
2962 if (!RegListOp->isRegList())
2965 unsigned RlistEncode = RegListOp->RegList.Encoding;
2969 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||
2970 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {
2971 int64_t
Lower = StackAdjBase;
2972 int64_t
Upper = StackAdjBase + 48;
2973 if (ExpectNegative) {
2978 return generateImmOutOfRangeError(S,
Lower,
Upper,
2979 "stack adjustment for register list must "
2980 "be a multiple of 16 bytes in the range");
2984 Operands.
push_back(RISCVOperand::createStackAdj(StackAdj, S));
2992bool RISCVAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
2996 MatchOperandParserImpl(Operands, Mnemonic,
true);
3003 if (parseRegister(Operands,
true).isSuccess())
3007 if (parseExpression(Operands).isSuccess()) {
3010 return !parseMemOpBaseReg(Operands).isSuccess();
3015 Error(getLoc(),
"unknown operand");
3019bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &Info,
3020 StringRef Name, SMLoc NameLoc,
3026 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
3030 Operands.
push_back(RISCVOperand::createToken(Name, NameLoc));
3039 if (parseOperand(Operands, Name))
3045 if (parseOperand(Operands, Name))
3049 if (getParser().parseEOL(
"unexpected token")) {
3050 getParser().eatToEndOfStatement();
3056bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
3060 Kind = RE->getSpecifier();
3061 Expr = RE->getSubExpr();
3070bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
3079ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
3080 StringRef IDVal = DirectiveID.
getString();
3082 if (IDVal ==
".option")
3083 return parseDirectiveOption();
3084 if (IDVal ==
".attribute")
3085 return parseDirectiveAttribute();
3086 if (IDVal ==
".insn")
3087 return parseDirectiveInsn(DirectiveID.
getLoc());
3088 if (IDVal ==
".variant_cc")
3089 return parseDirectiveVariantCC();
3094bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
3095 bool FromOptionDirective) {
3098 clearFeatureBits(Feature.Value, Feature.Key);
3105 raw_string_ostream OutputErrMsg(Buffer);
3106 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3107 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
3108 << ErrMsg.getMessage();
3111 return Error(Loc, OutputErrMsg.str());
3113 auto &ISAInfo = *ParseResult;
3116 if (ISAInfo->hasExtension(Feature.Key))
3117 setFeatureBits(Feature.Value, Feature.Key);
3119 if (FromOptionDirective) {
3120 if (ISAInfo->getXLen() == 32 && isRV64())
3121 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3122 else if (ISAInfo->getXLen() == 64 && !isRV64())
3123 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3126 if (ISAInfo->getXLen() == 32)
3127 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
3128 else if (ISAInfo->getXLen() == 64)
3129 setFeatureBits(RISCV::Feature64Bit,
"64bit");
3131 return Error(Loc,
"bad arch string " + Arch);
3133 Result = ISAInfo->toString();
3137bool RISCVAsmParser::parseDirectiveOption() {
3138 MCAsmParser &Parser = getParser();
3140 AsmToken Tok = Parser.
getTok();
3148 if (Option ==
"push") {
3152 getTargetStreamer().emitDirectiveOptionPush();
3157 if (Option ==
"pop") {
3162 getTargetStreamer().emitDirectiveOptionPop();
3163 if (popFeatureBits())
3164 return Error(StartLoc,
".option pop with no .option push");
3169 if (Option ==
"arch") {
3177 Type = RISCVOptionArchArgType::Plus;
3179 Type = RISCVOptionArchArgType::Minus;
3180 else if (!
Args.empty())
3182 "unexpected token, expected + or -");
3184 Type = RISCVOptionArchArgType::Full;
3188 "unexpected token, expected identifier");
3194 if (
Type == RISCVOptionArchArgType::Full) {
3196 if (resetToArch(Arch, Loc, Result,
true))
3205 Loc,
"extension version number parsing not currently implemented");
3208 if (!enableExperimentalExtension() &&
3210 return Error(Loc,
"unexpected experimental extensions");
3212 if (Ext == std::end(
RISCVFeatureKV) || StringRef(Ext->Key) != Feature)
3213 return Error(Loc,
"unknown extension feature");
3217 if (
Type == RISCVOptionArchArgType::Plus) {
3220 setFeatureBits(Ext->Value, Ext->Key);
3223 copySTI().setFeatureBits(OldFeatureBits);
3224 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3227 raw_string_ostream OutputErrMsg(Buffer);
3228 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3229 OutputErrMsg << ErrMsg.getMessage();
3232 return Error(Loc, OutputErrMsg.str());
3235 assert(
Type == RISCVOptionArchArgType::Minus);
3240 if (getSTI().hasFeature(Feature.Value) &&
3241 Feature.Implies.test(Ext->Value))
3242 return Error(Loc, Twine(
"can't disable ") + Ext->Key +
3243 " extension; " + Feature.Key +
3244 " extension requires " + Ext->Key +
3248 clearFeatureBits(Ext->Value, Ext->Key);
3255 getTargetStreamer().emitDirectiveOptionArch(Args);
3257 if (
auto ParseResult =
3259 getTargetStreamer().setArchString((*ParseResult)->toString());
3263 if (Option ==
"exact") {
3267 getTargetStreamer().emitDirectiveOptionExact();
3268 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3269 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3273 if (Option ==
"noexact") {
3277 getTargetStreamer().emitDirectiveOptionNoExact();
3278 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3279 setFeatureBits(RISCV::FeatureRelax,
"relax");
3283 if (Option ==
"rvc") {
3287 getTargetStreamer().emitDirectiveOptionRVC();
3288 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3289 if (
auto ParseResult =
3291 getTargetStreamer().setArchString((*ParseResult)->toString());
3295 if (Option ==
"norvc") {
3299 getTargetStreamer().emitDirectiveOptionNoRVC();
3300 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3301 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3302 if (
auto ParseResult =
3304 getTargetStreamer().setArchString((*ParseResult)->toString());
3308 if (Option ==
"pic") {
3312 getTargetStreamer().emitDirectiveOptionPIC();
3313 ParserOptions.IsPicEnabled =
true;
3317 if (Option ==
"nopic") {
3321 getTargetStreamer().emitDirectiveOptionNoPIC();
3322 ParserOptions.IsPicEnabled =
false;
3326 if (Option ==
"relax") {
3330 getTargetStreamer().emitDirectiveOptionRelax();
3331 setFeatureBits(RISCV::FeatureRelax,
"relax");
3335 if (Option ==
"norelax") {
3339 getTargetStreamer().emitDirectiveOptionNoRelax();
3340 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3346 "unknown option, expected 'push', 'pop', "
3347 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3348 "'exact', or 'noexact'");
3356bool RISCVAsmParser::parseDirectiveAttribute() {
3357 MCAsmParser &Parser = getParser();
3363 std::optional<unsigned> Ret =
3366 return Error(TagLoc,
"attribute name not recognised: " + Name);
3370 const MCExpr *AttrExpr;
3377 if (check(!CE, TagLoc,
"expected numeric constant"))
3380 Tag =
CE->getValue();
3386 StringRef StringValue;
3387 int64_t IntegerValue = 0;
3388 bool IsIntegerValue =
true;
3393 IsIntegerValue =
false;
3396 if (IsIntegerValue) {
3397 const MCExpr *ValueExpr;
3403 return Error(ValueExprLoc,
"expected numeric constant");
3404 IntegerValue =
CE->getValue();
3417 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3419 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3422 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3426 getTargetStreamer().emitTextAttribute(
Tag, Result);
3430 getTargetStreamer().setArchString(Result);
3438 .
Cases({
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s"},
true)
3439 .Cases({
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj"},
3441 .
Cases({
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es"},
3450bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3451 MCAsmParser &Parser = getParser();
3458 std::optional<int64_t>
Length;
3468 return Error(ErrorLoc,
3469 "instruction lengths must be a non-zero multiple of two");
3473 return Error(ErrorLoc,
3474 "instruction lengths over 64 bits are not supported");
3480 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3485 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3486 return Error(ErrorLoc,
3487 "instruction length does not match the encoding");
3490 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3493 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3496 if (!getSTI().hasFeature(RISCV::FeatureStdExtZca) &&
3497 (EncodingDerivedLength == 2))
3498 return Error(ErrorLoc,
"compressed instructions are not allowed");
3500 if (getParser().parseEOL(
"invalid operand for instruction")) {
3501 getParser().eatToEndOfStatement();
3509 Opcode = RISCV::Insn16;
3512 Opcode = RISCV::Insn32;
3515 Opcode = RISCV::Insn48;
3518 Opcode = RISCV::Insn64;
3524 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3526 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3531 return Error(ErrorLoc,
"invalid instruction format");
3533 std::string FormatName = (
".insn_" +
Format).str();
3535 ParseInstructionInfo
Info;
3538 if (parseInstruction(Info, FormatName, L, Operands))
3543 return matchAndEmitInstruction(L, Opcode, Operands, Parser.
getStreamer(),
3550bool RISCVAsmParser::parseDirectiveVariantCC() {
3552 if (getParser().parseIdentifier(Name))
3553 return TokError(
"expected symbol name");
3556 getTargetStreamer().emitDirectiveVariantCC(
3561void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3564 const MCSubtargetInfo &STI = getSTI();
3565 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3568 ++RISCVNumInstrsCompressed;
3572void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3577 for (MCInst &Inst : Seq) {
3578 emitToStreamer(Out, Inst);
3582void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3583 const MCExpr *Symbol,
3585 unsigned SecondOpcode, SMLoc IDLoc,
3597 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3602 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3605 .addExpr(RefToLinkTmpLabel));
3608void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3622void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3632 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3633 emitAuipcInstPair(DestReg, DestReg, Symbol,
RISCV::S_GOT_HI, SecondOpcode,
3637void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3646 if (ParserOptions.IsPicEnabled)
3647 emitLoadGlobalAddress(Inst, IDLoc, Out);
3649 emitLoadLocalAddress(Inst, IDLoc, Out);
3652void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3662 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3663 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3664 SecondOpcode, IDLoc, Out);
3667void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3677 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3678 RISCV::ADDI, IDLoc, Out);
3681void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3682 SMLoc IDLoc, MCStreamer &Out,
3691 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3693 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3697 if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].
contains(TmpReg)) {
3698 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3699 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3707void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3708 int64_t Width, SMLoc IDLoc,
3717 const MCOperand &DestReg = Inst.
getOperand(0);
3718 const MCOperand &SourceReg = Inst.
getOperand(1);
3720 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3721 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3723 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3725 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3730 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3736void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
3743 emitToStreamer(Out, MCInstBuilder(Opcode)
3747 .addReg(MCRegister())
3749 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
3760 "The destination register should not be V0.");
3761 emitToStreamer(Out, MCInstBuilder(Opcode)
3767 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
3779 "The destination register should be V0.");
3781 "The temporary vector register should not be V0.");
3782 emitToStreamer(Out, MCInstBuilder(Opcode)
3786 .addReg(MCRegister())
3788 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3800 "The temporary vector register should not be V0.");
3801 emitToStreamer(Out, MCInstBuilder(Opcode)
3805 .addReg(MCRegister())
3807 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3812 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3817 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
3825bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
3827 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3830 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
3831 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3832 "%tprel_add specifier");
3838bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
3840 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
3843 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
3844 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
3845 "%tlsdesc_call specifier");
3851std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3852 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
3855std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3856 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3860std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3861 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3869 case RISCV::VLOXSEG2EI8_V:
3870 case RISCV::VLOXSEG2EI16_V:
3871 case RISCV::VLOXSEG2EI32_V:
3872 case RISCV::VLOXSEG2EI64_V:
3873 case RISCV::VLUXSEG2EI8_V:
3874 case RISCV::VLUXSEG2EI16_V:
3875 case RISCV::VLUXSEG2EI32_V:
3876 case RISCV::VLUXSEG2EI64_V:
3878 case RISCV::VLOXSEG3EI8_V:
3879 case RISCV::VLOXSEG3EI16_V:
3880 case RISCV::VLOXSEG3EI32_V:
3881 case RISCV::VLOXSEG3EI64_V:
3882 case RISCV::VLUXSEG3EI8_V:
3883 case RISCV::VLUXSEG3EI16_V:
3884 case RISCV::VLUXSEG3EI32_V:
3885 case RISCV::VLUXSEG3EI64_V:
3887 case RISCV::VLOXSEG4EI8_V:
3888 case RISCV::VLOXSEG4EI16_V:
3889 case RISCV::VLOXSEG4EI32_V:
3890 case RISCV::VLOXSEG4EI64_V:
3891 case RISCV::VLUXSEG4EI8_V:
3892 case RISCV::VLUXSEG4EI16_V:
3893 case RISCV::VLUXSEG4EI32_V:
3894 case RISCV::VLUXSEG4EI64_V:
3896 case RISCV::VLOXSEG5EI8_V:
3897 case RISCV::VLOXSEG5EI16_V:
3898 case RISCV::VLOXSEG5EI32_V:
3899 case RISCV::VLOXSEG5EI64_V:
3900 case RISCV::VLUXSEG5EI8_V:
3901 case RISCV::VLUXSEG5EI16_V:
3902 case RISCV::VLUXSEG5EI32_V:
3903 case RISCV::VLUXSEG5EI64_V:
3905 case RISCV::VLOXSEG6EI8_V:
3906 case RISCV::VLOXSEG6EI16_V:
3907 case RISCV::VLOXSEG6EI32_V:
3908 case RISCV::VLOXSEG6EI64_V:
3909 case RISCV::VLUXSEG6EI8_V:
3910 case RISCV::VLUXSEG6EI16_V:
3911 case RISCV::VLUXSEG6EI32_V:
3912 case RISCV::VLUXSEG6EI64_V:
3914 case RISCV::VLOXSEG7EI8_V:
3915 case RISCV::VLOXSEG7EI16_V:
3916 case RISCV::VLOXSEG7EI32_V:
3917 case RISCV::VLOXSEG7EI64_V:
3918 case RISCV::VLUXSEG7EI8_V:
3919 case RISCV::VLUXSEG7EI16_V:
3920 case RISCV::VLUXSEG7EI32_V:
3921 case RISCV::VLUXSEG7EI64_V:
3923 case RISCV::VLOXSEG8EI8_V:
3924 case RISCV::VLOXSEG8EI16_V:
3925 case RISCV::VLOXSEG8EI32_V:
3926 case RISCV::VLOXSEG8EI64_V:
3927 case RISCV::VLUXSEG8EI8_V:
3928 case RISCV::VLUXSEG8EI16_V:
3929 case RISCV::VLUXSEG8EI32_V:
3930 case RISCV::VLUXSEG8EI64_V:
3936 if (RISCVMCRegisterClasses[RISCV::VRM2RegClassID].
contains(
Reg))
3938 if (RISCVMCRegisterClasses[RISCV::VRM4RegClassID].
contains(
Reg))
3940 if (RISCVMCRegisterClasses[RISCV::VRM8RegClassID].
contains(
Reg))
3947 case RISCV::VFWMMACC_VV_SCALE:
3948 case RISCV::VFQMMACC_VV_SCALE:
3949 case RISCV::VF8WMMACC_VV_SCALE:
3950 case RISCV::VFWIMMACC_VV:
3951 case RISCV::VFQIMMACC_VV:
3952 case RISCV::VF8WIMMACC_VV:
3959bool RISCVAsmParser::validateInstruction(MCInst &Inst,
3963 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3964 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3967 if (DestReg == TempReg) {
3968 SMLoc Loc = Operands.
back()->getStartLoc();
3969 return Error(Loc,
"the temporary vector register cannot be the same as "
3970 "the destination register");
3974 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3975 Opcode == RISCV::TH_LWD) {
3980 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
3981 SMLoc Loc = Operands[1]->getStartLoc();
3982 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
3986 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
3990 SMLoc Loc = Operands[1]->getStartLoc();
3991 return Error(Loc,
"rs1 and rs2 must be different");
3996 auto CheckOperandDoesNotOverlapV0 = [&](
int OperandIdx,
3997 unsigned ParsedIdx) {
3999 return Error(Operands[ParsedIdx]->getStartLoc(),
4000 "vd, vs1, and vs2 cannot overlap v0.scale");
4005 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4007 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4009 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4010 assert(DestIdx >= 0 && VS1Idx >= 0 && VS2Idx >= 0 &&
4011 "Unexpected Zvvfmm scaled operand list");
4013 if (CheckOperandDoesNotOverlapV0(DestIdx, 1) ||
4014 CheckOperandDoesNotOverlapV0(VS1Idx, 2) ||
4015 CheckOperandDoesNotOverlapV0(VS2Idx, 3))
4019 const MCInstrDesc &MCID = MII.
get(Opcode);
4023 int DestIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4027 const MCParsedAsmOperand *ParsedOp = Operands[1].get();
4028 if (!ParsedOp->
isReg()) {
4031 ParsedOp = Operands[2].get();
4033 assert(ParsedOp->
getReg() == DestReg &&
"Can't find parsed dest operand");
4037 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4041 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4042 assert(VS2Idx >= 0 &&
"No vs2 operand?");
4043 unsigned CheckEncoding =
4046 for (
unsigned i = 0; i < std::max(NF, Lmul); i++) {
4047 if ((DestEncoding + i) == CheckEncoding)
4048 return Error(Loc,
"the destination vector register group cannot overlap"
4049 " the source vector register group");
4054 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4058 unsigned CheckEncoding =
4060 for (
unsigned i = 0; i < Lmul; i++) {
4061 if ((DestEncoding + i) == CheckEncoding)
4063 "the destination vector register group cannot overlap"
4064 " the source vector register group");
4070 int VMIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vm);
4071 assert(VMIdx >= 0 &&
"No vm operand?");
4073 if (DestReg == RISCV::V0) {
4076 return Error(Loc,
"the destination vector register group cannot be V0");
4084 "Unexpected mask operand register");
4086 return Error(Loc,
"the destination vector register group cannot overlap"
4087 " the mask register");
4094bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
4102 case RISCV::PseudoC_ADDI_NOP: {
4104 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
4114 if (getSTI().hasFeature(RISCV::Feature64Bit))
4116 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV32)
4121 case RISCV::PACKW: {
4125 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV64)
4130 case RISCV::PseudoLLAImm:
4131 case RISCV::PseudoLAImm:
4132 case RISCV::PseudoLI: {
4138 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
4150 emitLoadImm(
Reg, Imm, Out);
4153 case RISCV::PseudoLLA:
4154 emitLoadLocalAddress(Inst, IDLoc, Out);
4156 case RISCV::PseudoLGA:
4157 emitLoadGlobalAddress(Inst, IDLoc, Out);
4159 case RISCV::PseudoLA:
4160 emitLoadAddress(Inst, IDLoc, Out);
4162 case RISCV::PseudoLA_TLS_IE:
4163 emitLoadTLSIEAddress(Inst, IDLoc, Out);
4165 case RISCV::PseudoLA_TLS_GD:
4166 emitLoadTLSGDAddress(Inst, IDLoc, Out);
4168 case RISCV::PseudoLB:
4169 case RISCV::PseudoQC_E_LB:
4170 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
4172 case RISCV::PseudoLBU:
4173 case RISCV::PseudoQC_E_LBU:
4174 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
4176 case RISCV::PseudoLH:
4177 case RISCV::PseudoQC_E_LH:
4178 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
4180 case RISCV::PseudoLHU:
4181 case RISCV::PseudoQC_E_LHU:
4182 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
4184 case RISCV::PseudoLW:
4185 case RISCV::PseudoQC_E_LW:
4186 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
4188 case RISCV::PseudoLWU:
4189 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
4191 case RISCV::PseudoLD:
4192 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
4194 case RISCV::PseudoLD_RV32:
4195 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
4197 case RISCV::PseudoFLH:
4198 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
4200 case RISCV::PseudoFLW:
4201 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
4203 case RISCV::PseudoFLD:
4204 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
4206 case RISCV::PseudoFLQ:
4207 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
4209 case RISCV::PseudoSB:
4210 case RISCV::PseudoQC_E_SB:
4211 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
4213 case RISCV::PseudoSH:
4214 case RISCV::PseudoQC_E_SH:
4215 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
4217 case RISCV::PseudoSW:
4218 case RISCV::PseudoQC_E_SW:
4219 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
4221 case RISCV::PseudoSD:
4222 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
4224 case RISCV::PseudoSD_RV32:
4225 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
4227 case RISCV::PseudoFSH:
4228 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
4230 case RISCV::PseudoFSW:
4231 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
4233 case RISCV::PseudoFSD:
4234 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4236 case RISCV::PseudoFSQ:
4237 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4239 case RISCV::PseudoAddTPRel:
4240 if (checkPseudoAddTPRel(Inst, Operands))
4243 case RISCV::PseudoTLSDESCCall:
4244 if (checkPseudoTLSDESCCall(Inst, Operands))
4247 case RISCV::PseudoSEXT_B:
4248 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4250 case RISCV::PseudoSEXT_H:
4251 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4253 case RISCV::PseudoZEXT_H:
4254 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4256 case RISCV::PseudoZEXT_W:
4257 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4259 case RISCV::PseudoVMSGEU_VX:
4260 case RISCV::PseudoVMSGEU_VX_M:
4261 case RISCV::PseudoVMSGEU_VX_M_T:
4262 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4264 case RISCV::PseudoVMSGE_VX:
4265 case RISCV::PseudoVMSGE_VX_M:
4266 case RISCV::PseudoVMSGE_VX_M_T:
4267 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4269 case RISCV::PseudoVMSGE_VI:
4270 case RISCV::PseudoVMSLT_VI: {
4274 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4276 emitToStreamer(Out, MCInstBuilder(
Opc)
4284 case RISCV::PseudoVMSGEU_VI:
4285 case RISCV::PseudoVMSLTU_VI: {
4292 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4295 emitToStreamer(Out, MCInstBuilder(
Opc)
4303 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4306 emitToStreamer(Out, MCInstBuilder(
Opc)
4316 case RISCV::PseudoCV_ELW:
4317 emitLoadStoreSymbol(Inst, RISCV::CV_ELW, IDLoc, Out,
false);
4321 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 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)
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
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.