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 isGPRPair()
const {
497 return Kind == KindTy::Register &&
498 RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(
Reg.Reg);
501 bool isGPRPairC()
const {
502 return Kind == KindTy::Register &&
503 RISCVMCRegisterClasses[RISCV::GPRPairCRegClassID].contains(
Reg.Reg);
506 bool isGPRPairNoX0()
const {
507 return Kind == KindTy::Register &&
508 RISCVMCRegisterClasses[RISCV::GPRPairNoX0RegClassID].contains(
512 bool isGPRF16()
const {
513 return Kind == KindTy::Register &&
514 RISCVMCRegisterClasses[RISCV::GPRF16RegClassID].contains(
Reg.Reg);
517 bool isGPRF32()
const {
518 return Kind == KindTy::Register &&
519 RISCVMCRegisterClasses[RISCV::GPRF32RegClassID].contains(
Reg.Reg);
522 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
523 bool isGPRAsFPR16()
const {
return isGPRF16() &&
Reg.IsGPRAsFPR; }
524 bool isGPRAsFPR32()
const {
return isGPRF32() &&
Reg.IsGPRAsFPR; }
525 bool isGPRPairAsFPR64()
const {
return isGPRPair() &&
Reg.IsGPRAsFPR; }
527 static bool evaluateConstantExpr(
const MCExpr *Expr, int64_t &Imm) {
529 Imm =
CE->getValue();
538 template <
int N>
bool isBareSimmNLsb0()
const {
543 if (evaluateConstantExpr(
getExpr(), Imm))
544 return isShiftedInt<
N - 1, 1>(fixImmediateForRV32(Imm, isRV64Expr()));
547 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
553 template <
int N>
bool isBareSimmN()
const {
558 if (evaluateConstantExpr(
getExpr(), Imm))
559 return isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
562 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
568 bool isBareSymbol()
const {
571 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
575 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
579 bool isCallSymbol()
const {
582 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
586 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
590 bool isPseudoJumpSymbol()
const {
593 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
597 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
601 bool isTPRelAddSymbol()
const {
604 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
608 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
609 VK == ELF::R_RISCV_TPREL_ADD;
612 bool isTLSDESCCallSymbol()
const {
615 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
619 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
620 VK == ELF::R_RISCV_TLSDESC_CALL;
623 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
627 bool isVTypeI10()
const {
628 if (Kind == KindTy::VType)
632 bool isVTypeI11()
const {
633 if (Kind == KindTy::VType)
638 bool isXSfmmVType()
const {
644 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
647 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
648 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
652 bool isLoadFPImm()
const {
655 if (Kind != KindTy::FPImmediate)
658 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
661 return Idx >= 0 && Idx != 1;
664 bool isImmXLenLI()
const {
670 if (evaluateConstantExpr(
getExpr(), Imm))
673 return RISCVAsmParser::isSymbolDiff(
getExpr());
676 bool isImmXLenLI_Restricted()
const {
680 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
682 return IsConstantImm &&
686 template <
unsigned N>
bool isUImm()
const {
690 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
694 template <
unsigned N,
unsigned S>
bool isUImmShifted()
const {
698 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
702 template <
class Pred>
bool isUImmPred(Pred p)
const {
706 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
707 return IsConstantImm &&
p(Imm);
710 bool isUImmLog2XLen()
const {
711 if (isExpr() && isRV64Expr())
716 bool isUImmLog2XLenNonZero()
const {
717 if (isExpr() && isRV64Expr())
718 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<6>(Imm); });
719 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<5>(Imm); });
722 bool isUImmLog2XLenHalf()
const {
723 if (isExpr() && isRV64Expr())
728 bool isUImm1()
const {
return isUImm<1>(); }
729 bool isUImm2()
const {
return isUImm<2>(); }
730 bool isUImm3()
const {
return isUImm<3>(); }
731 bool isUImm4()
const {
return isUImm<4>(); }
732 bool isUImm5()
const {
return isUImm<5>(); }
733 bool isUImm6()
const {
return isUImm<6>(); }
734 bool isUImm7()
const {
return isUImm<7>(); }
735 bool isUImm8()
const {
return isUImm<8>(); }
736 bool isUImm9()
const {
return isUImm<9>(); }
737 bool isUImm10()
const {
return isUImm<10>(); }
738 bool isUImm11()
const {
return isUImm<11>(); }
739 bool isUImm16()
const {
return isUImm<16>(); }
740 bool isUImm20()
const {
return isUImm<20>(); }
741 bool isUImm32()
const {
return isUImm<32>(); }
742 bool isUImm48()
const {
return isUImm<48>(); }
743 bool isUImm64()
const {
return isUImm<64>(); }
745 bool isUImm5NonZero()
const {
746 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<5>(Imm); });
749 bool isUImm5GT3()
const {
750 return isUImmPred([](int64_t Imm) {
return isUInt<5>(Imm) &&
Imm > 3; });
753 bool isUImm4Plus1()
const {
755 [](int64_t Imm) {
return Imm > 0 &&
isUInt<4>(Imm - 1); });
758 bool isUImm5Plus1()
const {
760 [](int64_t Imm) {
return Imm > 0 &&
isUInt<5>(Imm - 1); });
763 bool isUImm6Plus1()
const {
765 [](int64_t Imm) {
return Imm > 0 &&
isUInt<6>(Imm - 1); });
768 bool isUImm5GE6Plus1()
const {
770 [](int64_t Imm) {
return Imm >= 6 &&
isUInt<5>(Imm - 1); });
773 bool isUImm5Slist()
const {
774 return isUImmPred([](int64_t Imm) {
775 return (Imm == 0) || (
Imm == 1) || (Imm == 2) || (
Imm == 4) ||
776 (Imm == 8) || (
Imm == 16) || (Imm == 15) || (
Imm == 31);
780 bool isUImm8GE32()
const {
781 return isUImmPred([](int64_t Imm) {
return isUInt<8>(Imm) &&
Imm >= 32; });
784 bool isRnumArg()
const {
786 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(10); });
789 bool isRnumArg_0_7()
const {
791 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(7); });
794 bool isRnumArg_1_10()
const {
796 [](int64_t Imm) {
return Imm >= INT64_C(1) &&
Imm <= INT64_C(10); });
799 bool isRnumArg_2_14()
const {
801 [](int64_t Imm) {
return Imm >= INT64_C(2) &&
Imm <= INT64_C(14); });
804 template <
unsigned N>
bool isSImm()
const {
808 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
809 return IsConstantImm &&
isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
812 template <
class Pred>
bool isSImmPred(Pred p)
const {
816 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
817 return IsConstantImm &&
p(fixImmediateForRV32(Imm, isRV64Expr()));
820 bool isSImm5()
const {
return isSImm<5>(); }
821 bool isSImm6()
const {
return isSImm<6>(); }
822 bool isSImm10()
const {
return isSImm<10>(); }
823 bool isSImm11()
const {
return isSImm<11>(); }
824 bool isSImm12()
const {
return isSImm<12>(); }
825 bool isSImm16()
const {
return isSImm<16>(); }
826 bool isSImm26()
const {
return isSImm<26>(); }
828 bool isSImm5NonZero()
const {
829 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<5>(Imm); });
832 bool isSImm6NonZero()
const {
833 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<6>(Imm); });
836 bool isCLUIImm()
const {
837 return isUImmPred([](int64_t Imm) {
838 return (
isUInt<5>(Imm) && Imm != 0) || (
Imm >= 0xfffe0 &&
Imm <= 0xfffff);
842 bool isUImm2Lsb0()
const {
return isUImmShifted<1, 1>(); }
844 bool isUImm5Lsb0()
const {
return isUImmShifted<4, 1>(); }
846 bool isUImm6Lsb0()
const {
return isUImmShifted<5, 1>(); }
848 bool isUImm7Lsb00()
const {
return isUImmShifted<5, 2>(); }
850 bool isUImm7Lsb000()
const {
return isUImmShifted<4, 3>(); }
852 bool isUImm8Lsb00()
const {
return isUImmShifted<6, 2>(); }
854 bool isUImm8Lsb000()
const {
return isUImmShifted<5, 3>(); }
856 bool isUImm9Lsb000()
const {
return isUImmShifted<6, 3>(); }
858 bool isUImm14Lsb00()
const {
return isUImmShifted<12, 2>(); }
860 bool isUImm10Lsb00NonZero()
const {
867 static int64_t fixImmediateForRV32(int64_t Imm,
bool IsRV64Imm) {
873 bool isSImm12LO()
const {
878 if (evaluateConstantExpr(
getExpr(), Imm))
879 return isInt<12>(fixImmediateForRV32(Imm, isRV64Expr()));
882 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
885 VK == ELF::R_RISCV_TLSDESC_ADD_LO12);
888 bool isSImm12Lsb00000()
const {
892 bool isSImm10Lsb0000NonZero()
const {
897 bool isSImm16NonZero()
const {
898 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<16>(Imm); });
901 bool isUImm16NonZero()
const {
902 return isUImmPred([](int64_t Imm) {
return isUInt<16>(Imm) &&
Imm != 0; });
905 bool isSImm20LI()
const {
910 if (evaluateConstantExpr(
getExpr(), Imm))
911 return isInt<20>(fixImmediateForRV32(Imm, isRV64Expr()));
914 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
918 bool isSImm8PLI_B()
const {
return isSImm<8>() || isUImm<8>(); }
919 bool isSImm10PLUI()
const {
return isSImm<10>() || isUImm<10>(); }
921 bool isSImm10PLI_H()
const {
922 return isSImm<10>() || isUImmPred([](int64_t Imm) {
926 bool isSImm10PLI_W()
const {
927 return isSImm<10>() || isUImmPred([](int64_t Imm) {
932 bool isUImm20LUI()
const {
937 if (evaluateConstantExpr(
getExpr(), Imm))
941 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
942 (VK == ELF::R_RISCV_HI20 || VK == ELF::R_RISCV_TPREL_HI20);
945 bool isUImm20AUIPC()
const {
950 if (evaluateConstantExpr(
getExpr(), Imm))
954 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
956 VK == ELF::R_RISCV_TLS_GOT_HI20 || VK == ELF::R_RISCV_TLS_GD_HI20 ||
957 VK == ELF::R_RISCV_TLSDESC_HI20);
960 bool isImmZero()
const {
961 return isUImmPred([](int64_t Imm) {
return 0 ==
Imm; });
964 bool isImmThree()
const {
965 return isUImmPred([](int64_t Imm) {
return 3 ==
Imm; });
968 bool isImmFour()
const {
969 return isUImmPred([](int64_t Imm) {
return 4 ==
Imm; });
972 bool isImm5Zibi()
const {
974 [](int64_t Imm) {
return (Imm != 0 &&
isUInt<5>(Imm)) ||
Imm == -1; });
977 bool isSImm5Plus1()
const {
982 bool isSImm18()
const {
983 return isSImmPred([](int64_t Imm) {
return isInt<18>(Imm); });
986 bool isSImm18Lsb0()
const {
990 bool isSImm19Lsb00()
const {
994 bool isSImm20Lsb000()
const {
998 bool isSImm32Lsb0()
const {
1003 SMLoc getStartLoc()
const override {
return StartLoc; }
1005 SMLoc getEndLoc()
const override {
return EndLoc; }
1008 bool isRV64Expr()
const {
1009 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1013 MCRegister
getReg()
const override {
1014 assert(Kind == KindTy::Register &&
"Invalid type access!");
1018 StringRef getSysReg()
const {
1019 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
1020 return StringRef(SysReg.Data, SysReg.Length);
1023 const MCExpr *
getExpr()
const {
1024 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1028 uint64_t getFPConst()
const {
1029 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1034 assert(Kind == KindTy::Token &&
"Invalid type access!");
1038 unsigned getVType()
const {
1039 assert(Kind == KindTy::VType &&
"Invalid type access!");
1044 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1048 unsigned getFence()
const {
1049 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1053 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1062 case KindTy::Expression:
1065 OS <<
' ' << (Expr.IsRV64 ?
"rv64" :
"rv32") <<
'>';
1067 case KindTy::FPImmediate:
1068 OS <<
"<fpimm: " << FPImm.Val <<
">";
1070 case KindTy::Register:
1072 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1077 case KindTy::SystemRegister:
1078 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1087 OS << roundingModeToString(getFRM());
1095 case KindTy::RegList:
1100 case KindTy::StackAdj:
1101 OS <<
"<stackadj: ";
1105 case KindTy::RegReg:
1106 OS <<
"<RegReg: BaseReg " <<
RegName(
RegReg.BaseReg) <<
" OffsetReg "
1112 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1113 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1120 static std::unique_ptr<RISCVOperand>
1121 createReg(MCRegister
Reg, SMLoc S, SMLoc
E,
bool IsGPRAsFPR =
false) {
1122 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1124 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1130 static std::unique_ptr<RISCVOperand> createExpr(
const MCExpr *Val, SMLoc S,
1131 SMLoc
E,
bool IsRV64) {
1132 auto Op = std::make_unique<RISCVOperand>(KindTy::Expression);
1133 Op->Expr.Expr = Val;
1134 Op->Expr.IsRV64 = IsRV64;
1140 static std::unique_ptr<RISCVOperand> createFPImm(uint64_t Val, SMLoc S) {
1141 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1142 Op->FPImm.Val = Val;
1148 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1149 unsigned Encoding) {
1150 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1151 Op->SysReg.Data = Str.data();
1152 Op->SysReg.Length = Str.size();
1159 static std::unique_ptr<RISCVOperand>
1161 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1168 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val, SMLoc S) {
1169 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1170 Op->Fence.Val = Val;
1176 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI, SMLoc S) {
1177 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1178 Op->VType.Val = VTypeI;
1184 static std::unique_ptr<RISCVOperand> createRegList(
unsigned RlistEncode,
1186 auto Op = std::make_unique<RISCVOperand>(KindTy::RegList);
1192 static std::unique_ptr<RISCVOperand>
1193 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {
1194 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1196 Op->RegReg.OffsetReg = OffsetReg;
1202 static std::unique_ptr<RISCVOperand> createStackAdj(
unsigned StackAdj, SMLoc S) {
1203 auto Op = std::make_unique<RISCVOperand>(KindTy::StackAdj);
1204 Op->StackAdj.Val = StackAdj;
1209 static void addExpr(MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1210 assert(Expr &&
"Expr shouldn't be null!");
1212 bool IsConstant = evaluateConstantExpr(Expr, Imm);
1222 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1223 assert(
N == 1 &&
"Invalid number of operands!");
1227 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1228 assert(
N == 1 &&
"Invalid number of operands!");
1229 addExpr(Inst,
getExpr(), isRV64Expr());
1232 template <
unsigned Bits>
1233 void addSExtImmOperands(MCInst &Inst,
unsigned N)
const {
1234 assert(
N == 1 &&
"Invalid number of operands!");
1241 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
1242 assert(
N == 1 &&
"Invalid number of operands!");
1244 addExpr(Inst,
getExpr(), isRV64Expr());
1249 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1253 void addFenceArgOperands(MCInst &Inst,
unsigned N)
const {
1254 assert(
N == 1 &&
"Invalid number of operands!");
1258 void addCSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
1259 assert(
N == 1 &&
"Invalid number of operands!");
1266 void addVTypeIOperands(MCInst &Inst,
unsigned N)
const {
1267 assert(
N == 1 &&
"Invalid number of operands!");
1269 if (Kind == KindTy::Expression) {
1270 [[maybe_unused]]
bool IsConstantImm =
1271 evaluateConstantExpr(
getExpr(), Imm);
1272 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1279 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1280 assert(
N == 1 &&
"Invalid number of operands!");
1284 void addRegRegOperands(MCInst &Inst,
unsigned N)
const {
1285 assert(
N == 2 &&
"Invalid number of operands!");
1290 void addStackAdjOperands(MCInst &Inst,
unsigned N)
const {
1291 assert(
N == 1 &&
"Invalid number of operands!");
1295 void addFRMArgOperands(MCInst &Inst,
unsigned N)
const {
1296 assert(
N == 1 &&
"Invalid number of operands!");
1302#define GET_REGISTER_MATCHER
1303#define GET_SUBTARGET_FEATURE_NAME
1304#define GET_MATCHER_IMPLEMENTATION
1305#define GET_MNEMONIC_SPELL_CHECKER
1306#include "RISCVGenAsmMatcher.inc"
1309 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1310 return Reg - RISCV::F0_D + RISCV::F0_H;
1314 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1315 return Reg - RISCV::F0_D + RISCV::F0_F;
1319 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1320 return Reg - RISCV::F0_D + RISCV::F0_Q;
1325 unsigned RegClassID;
1326 if (Kind == MCK_VRM2)
1327 RegClassID = RISCV::VRM2RegClassID;
1328 else if (Kind == MCK_VRM4)
1329 RegClassID = RISCV::VRM4RegClassID;
1330 else if (Kind == MCK_VRM8)
1331 RegClassID = RISCV::VRM8RegClassID;
1335 &RISCVMCRegisterClasses[RegClassID]);
1339 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1340 return Reg - RISCV::F0_D + RISCV::F0_Q2;
1345 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1347 return Match_InvalidOperand;
1349 MCRegister
Reg =
Op.getReg();
1351 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg);
1353 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg);
1354 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg);
1356 if (IsRegFPR64 && Kind == MCK_FPR256) {
1358 return Match_Success;
1360 if (IsRegFPR64 && Kind == MCK_FPR128) {
1362 return Match_Success;
1366 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1367 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1369 return Match_Success;
1373 if (IsRegFPR64 && Kind == MCK_FPR16) {
1375 return Match_Success;
1377 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1378 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_H;
1379 return Match_Success;
1381 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1382 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_W;
1383 return Match_Success;
1390 if (RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg) &&
1391 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1393 return Match_Success;
1397 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1400 return Match_InvalidOperand;
1401 return Match_Success;
1403 return Match_InvalidOperand;
1406bool RISCVAsmParser::generateImmOutOfRangeError(
1407 SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
1408 const Twine &Msg =
"immediate must be an integer in the range") {
1409 return Error(ErrorLoc, Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]");
1412bool RISCVAsmParser::generateImmOutOfRangeError(
1414 const Twine &Msg =
"immediate must be an integer in the range") {
1415 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1416 return generateImmOutOfRangeError(ErrorLoc,
Lower,
Upper, Msg);
1419bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1422 uint64_t &ErrorInfo,
1423 bool MatchingInlineAsm) {
1425 FeatureBitset MissingFeatures;
1427 auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
1433 if (validateInstruction(Inst, Operands))
1435 return processInstruction(Inst, IDLoc, Operands, Out);
1436 case Match_MissingFeature: {
1437 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1438 bool FirstFeature =
true;
1439 std::string Msg =
"instruction requires the following:";
1440 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1441 if (MissingFeatures[i]) {
1442 Msg += FirstFeature ?
" " :
", ";
1444 FirstFeature =
false;
1447 return Error(IDLoc, Msg);
1449 case Match_MnemonicFail: {
1450 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1451 std::string Suggestion = RISCVMnemonicSpellCheck(
1452 ((RISCVOperand &)*Operands[0]).
getToken(), FBS, 0);
1453 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1455 case Match_InvalidOperand: {
1456 SMLoc ErrorLoc = IDLoc;
1457 if (ErrorInfo != ~0ULL) {
1458 if (ErrorInfo >= Operands.
size())
1459 return Error(ErrorLoc,
"too few operands for instruction");
1461 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1462 if (ErrorLoc == SMLoc())
1465 return Error(ErrorLoc,
"invalid operand for instruction");
1472 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1473 SMLoc ErrorLoc = IDLoc;
1474 if (ErrorInfo != ~0ULL && ErrorInfo >= Operands.
size())
1475 return Error(ErrorLoc,
"too few operands for instruction");
1481 case Match_InvalidImmXLenLI:
1483 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1484 return Error(ErrorLoc,
"operand must be a constant 64-bit integer");
1486 return generateImmOutOfRangeError(Operands, ErrorInfo,
1487 std::numeric_limits<int32_t>::min(),
1488 std::numeric_limits<uint32_t>::max());
1489 case Match_InvalidImmXLenLI_Restricted:
1491 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1492 return Error(ErrorLoc,
"operand either must be a constant 64-bit integer "
1493 "or a bare symbol name");
1495 return generateImmOutOfRangeError(
1496 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1497 std::numeric_limits<uint32_t>::max(),
1498 "operand either must be a bare symbol name or an immediate integer in "
1500 case Match_InvalidUImmLog2XLen:
1502 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1503 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1504 case Match_InvalidUImmLog2XLenNonZero:
1506 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
1507 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1508 case Match_InvalidUImm1:
1509 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
1510 case Match_InvalidUImm2:
1511 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
1512 case Match_InvalidUImm2Lsb0:
1513 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 2,
1514 "immediate must be one of");
1515 case Match_InvalidUImm3:
1516 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
1517 case Match_InvalidUImm4:
1518 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
1519 case Match_InvalidUImm4Plus1:
1520 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4));
1521 case Match_InvalidUImm5:
1522 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1523 case Match_InvalidUImm5NonZero:
1524 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1525 case Match_InvalidUImm5GT3:
1526 return generateImmOutOfRangeError(Operands, ErrorInfo, 4, (1 << 5) - 1);
1527 case Match_InvalidUImm5Plus1:
1528 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));
1529 case Match_InvalidUImm5GE6Plus1:
1530 return generateImmOutOfRangeError(Operands, ErrorInfo, 6, (1 << 5));
1531 case Match_InvalidUImm5Slist: {
1532 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1533 return Error(ErrorLoc,
1534 "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31");
1536 case Match_InvalidUImm6:
1537 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1538 case Match_InvalidUImm6Plus1:
1539 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6));
1540 case Match_InvalidUImm7:
1541 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
1542 case Match_InvalidUImm8:
1543 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
1544 case Match_InvalidUImm8GE32:
1545 return generateImmOutOfRangeError(Operands, ErrorInfo, 32, (1 << 8) - 1);
1546 case Match_InvalidSImm5:
1547 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4),
1549 case Match_InvalidSImm5NonZero:
1550 return generateImmOutOfRangeError(
1551 Operands, ErrorInfo, -(1 << 4), (1 << 4) - 1,
1552 "immediate must be non-zero in the range");
1553 case Match_InvalidSImm6:
1554 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
1556 case Match_InvalidSImm6NonZero:
1557 return generateImmOutOfRangeError(
1558 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
1559 "immediate must be non-zero in the range");
1560 case Match_InvalidCLUIImm:
1561 return generateImmOutOfRangeError(
1562 Operands, ErrorInfo, 1, (1 << 5) - 1,
1563 "immediate must be in [0xfffe0, 0xfffff] or");
1564 case Match_InvalidUImm5Lsb0:
1565 return generateImmOutOfRangeError(
1566 Operands, ErrorInfo, 0, (1 << 5) - 2,
1567 "immediate must be a multiple of 2 bytes in the range");
1568 case Match_InvalidUImm6Lsb0:
1569 return generateImmOutOfRangeError(
1570 Operands, ErrorInfo, 0, (1 << 6) - 2,
1571 "immediate must be a multiple of 2 bytes in the range");
1572 case Match_InvalidUImm7Lsb00:
1573 return generateImmOutOfRangeError(
1574 Operands, ErrorInfo, 0, (1 << 7) - 4,
1575 "immediate must be a multiple of 4 bytes in the range");
1576 case Match_InvalidUImm8Lsb00:
1577 return generateImmOutOfRangeError(
1578 Operands, ErrorInfo, 0, (1 << 8) - 4,
1579 "immediate must be a multiple of 4 bytes in the range");
1580 case Match_InvalidUImm8Lsb000:
1581 return generateImmOutOfRangeError(
1582 Operands, ErrorInfo, 0, (1 << 8) - 8,
1583 "immediate must be a multiple of 8 bytes in the range");
1584 case Match_InvalidUImm9:
1585 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 9) - 1,
1586 "immediate offset must be in the range");
1587 case Match_InvalidBareSImm9Lsb0:
1588 return generateImmOutOfRangeError(
1589 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
1590 "immediate must be a multiple of 2 bytes in the range");
1591 case Match_InvalidUImm9Lsb000:
1592 return generateImmOutOfRangeError(
1593 Operands, ErrorInfo, 0, (1 << 9) - 8,
1594 "immediate must be a multiple of 8 bytes in the range");
1595 case Match_InvalidSImm8PLI_B:
1596 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
1598 case Match_InvalidSImm10:
1599 case Match_InvalidSImm10PLI_H:
1600 case Match_InvalidSImm10PLI_W:
1601 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
1603 case Match_InvalidSImm10PLUI:
1604 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
1606 case Match_InvalidUImm10Lsb00NonZero:
1607 return generateImmOutOfRangeError(
1608 Operands, ErrorInfo, 4, (1 << 10) - 4,
1609 "immediate must be a multiple of 4 bytes in the range");
1610 case Match_InvalidSImm10Lsb0000NonZero:
1611 return generateImmOutOfRangeError(
1612 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
1613 "immediate must be a multiple of 16 bytes and non-zero in the range");
1614 case Match_InvalidSImm11:
1615 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 10),
1617 case Match_InvalidBareSImm11Lsb0:
1618 return generateImmOutOfRangeError(
1619 Operands, ErrorInfo, -(1 << 10), (1 << 10) - 2,
1620 "immediate must be a multiple of 2 bytes in the range");
1621 case Match_InvalidUImm10:
1622 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 10) - 1);
1623 case Match_InvalidUImm11:
1624 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
1625 case Match_InvalidUImm14Lsb00:
1626 return generateImmOutOfRangeError(
1627 Operands, ErrorInfo, 0, (1 << 14) - 4,
1628 "immediate must be a multiple of 4 bytes in the range");
1629 case Match_InvalidUImm16NonZero:
1630 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16) - 1);
1631 case Match_InvalidSImm12:
1632 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11),
1634 case Match_InvalidSImm12LO:
1635 return generateImmOutOfRangeError(
1636 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
1637 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo specifier or an "
1638 "integer in the range");
1639 case Match_InvalidBareSImm12Lsb0:
1640 return generateImmOutOfRangeError(
1641 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
1642 "immediate must be a multiple of 2 bytes in the range");
1643 case Match_InvalidSImm12Lsb00000:
1644 return generateImmOutOfRangeError(
1645 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 32,
1646 "immediate must be a multiple of 32 bytes in the range");
1647 case Match_InvalidBareSImm13Lsb0:
1648 return generateImmOutOfRangeError(
1649 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
1650 "immediate must be a multiple of 2 bytes in the range");
1651 case Match_InvalidSImm16:
1652 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 15),
1654 case Match_InvalidSImm16NonZero:
1655 return generateImmOutOfRangeError(
1656 Operands, ErrorInfo, -(1 << 15), (1 << 15) - 1,
1657 "immediate must be non-zero in the range");
1658 case Match_InvalidSImm20LI:
1659 return generateImmOutOfRangeError(
1660 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 1,
1661 "operand must be a symbol with a %qc.abs20 specifier or an integer "
1663 case Match_InvalidUImm20LUI:
1664 return generateImmOutOfRangeError(
1665 Operands, ErrorInfo, 0, (1 << 20) - 1,
1666 "operand must be a symbol with "
1667 "%hi/%tprel_hi specifier or an integer in "
1669 case Match_InvalidUImm20:
1670 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1);
1671 case Match_InvalidUImm20AUIPC:
1672 return generateImmOutOfRangeError(
1673 Operands, ErrorInfo, 0, (1 << 20) - 1,
1674 "operand must be a symbol with a "
1675 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
1677 "an integer in the range");
1678 case Match_InvalidBareSImm21Lsb0:
1679 return generateImmOutOfRangeError(
1680 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
1681 "immediate must be a multiple of 2 bytes in the range");
1682 case Match_InvalidCSRSystemRegister: {
1683 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1,
1684 "operand must be a valid system register "
1685 "name or an integer in the range");
1687 case Match_InvalidImm5Zibi:
1688 return generateImmOutOfRangeError(
1689 Operands, ErrorInfo, -1, (1 << 5) - 1,
1690 "immediate must be non-zero in the range");
1691 case Match_InvalidVTypeI: {
1692 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1693 return generateVTypeError(ErrorLoc);
1695 case Match_InvalidSImm5Plus1: {
1696 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1,
1698 "immediate must be in the range");
1700 case Match_InvalidSImm18:
1701 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 17),
1703 case Match_InvalidSImm18Lsb0:
1704 return generateImmOutOfRangeError(
1705 Operands, ErrorInfo, -(1 << 17), (1 << 17) - 2,
1706 "immediate must be a multiple of 2 bytes in the range");
1707 case Match_InvalidSImm19Lsb00:
1708 return generateImmOutOfRangeError(
1709 Operands, ErrorInfo, -(1 << 18), (1 << 18) - 4,
1710 "immediate must be a multiple of 4 bytes in the range");
1711 case Match_InvalidSImm20Lsb000:
1712 return generateImmOutOfRangeError(
1713 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 8,
1714 "immediate must be a multiple of 8 bytes in the range");
1715 case Match_InvalidSImm26:
1716 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 25),
1719 case Match_InvalidBareSymbolQC_E_LI:
1722 case Match_InvalidBareSImm32:
1723 return generateImmOutOfRangeError(Operands, ErrorInfo,
1724 std::numeric_limits<int32_t>::min(),
1725 std::numeric_limits<uint32_t>::max());
1726 case Match_InvalidBareSImm32Lsb0:
1727 return generateImmOutOfRangeError(
1728 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1729 std::numeric_limits<int32_t>::max() - 1,
1730 "operand must be a multiple of 2 bytes in the range");
1731 case Match_InvalidRnumArg: {
1732 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10);
1734 case Match_InvalidStackAdj: {
1735 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1738 "stack adjustment is invalid for this instruction and register list");
1742 if (
const char *MatchDiag = getMatchKindDiag((RISCVMatchResultTy)Result)) {
1743 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1744 return Error(ErrorLoc, MatchDiag);
1754MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name)
const {
1763 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1764 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1765 static_assert(RISCV::F0_D < RISCV::F0_Q,
"FPR matching must be updated");
1768 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1773bool RISCVAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1775 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1776 return Error(StartLoc,
"invalid register name");
1780ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1782 const AsmToken &Tok = getParser().getTok();
1785 StringRef
Name = getLexer().getTok().getIdentifier();
1795ParseStatus RISCVAsmParser::parseRegister(
OperandVector &Operands,
1797 SMLoc FirstS = getLoc();
1798 bool HadParens =
false;
1805 size_t ReadCount = getLexer().peekTokens(Buf);
1808 LParen = getParser().getTok();
1813 switch (getLexer().getKind()) {
1816 getLexer().UnLex(LParen);
1819 StringRef
Name = getLexer().getTok().getIdentifier();
1824 getLexer().UnLex(LParen);
1828 Operands.
push_back(RISCVOperand::createToken(
"(", FirstS));
1830 SMLoc
E = getTok().getEndLoc();
1837 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
1843ParseStatus RISCVAsmParser::parseInsnDirectiveOpcode(
OperandVector &Operands) {
1848 switch (getLexer().getKind()) {
1858 if (getParser().parseExpression(Res,
E))
1863 int64_t
Imm =
CE->getValue();
1865 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1874 if (getParser().parseIdentifier(Identifier))
1877 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1880 "Unexpected opcode");
1883 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1893 return generateImmOutOfRangeError(
1895 "opcode must be a valid opcode name or an immediate in the range");
1898ParseStatus RISCVAsmParser::parseInsnCDirectiveOpcode(
OperandVector &Operands) {
1903 switch (getLexer().getKind()) {
1913 if (getParser().parseExpression(Res,
E))
1918 int64_t
Imm =
CE->getValue();
1919 if (Imm >= 0 && Imm <= 2) {
1920 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1929 if (getParser().parseIdentifier(Identifier))
1933 if (Identifier ==
"C0")
1935 else if (Identifier ==
"C1")
1937 else if (Identifier ==
"C2")
1944 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1953 return generateImmOutOfRangeError(
1955 "opcode must be a valid opcode name or an immediate in the range");
1958ParseStatus RISCVAsmParser::parseCSRSystemRegister(
OperandVector &Operands) {
1962 auto SysRegFromConstantInt = [
this](
const MCExpr *
E, SMLoc S) {
1964 int64_t
Imm =
CE->getValue();
1966 auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
1970 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
1973 return RISCVOperand::createSysReg(
Reg.Name, S, Imm);
1977 return RISCVOperand::createSysReg(
"", S, Imm);
1980 return std::unique_ptr<RISCVOperand>();
1983 switch (getLexer().getKind()) {
1993 if (getParser().parseExpression(Res))
1996 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
2001 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2005 if (getParser().parseIdentifier(Identifier))
2008 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
2011 if (SysReg->IsDeprecatedName) {
2013 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
2015 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2017 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
2023 const auto &FeatureBits = getSTI().getFeatureBits();
2024 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
2026 return SysReg->FeaturesRequired[Feature.Value];
2028 auto ErrorMsg = std::string(
"system register '") + SysReg->Name +
"' ";
2029 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
2030 ErrorMsg +=
"is RV32 only";
2032 ErrorMsg +=
" and ";
2036 "requires '" + std::string(Feature->Key) +
"' to be enabled";
2039 return Error(S, ErrorMsg);
2042 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
2057 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2058 "operand must be a valid system register "
2059 "name or an integer in the range");
2063 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2070ParseStatus RISCVAsmParser::parseFPImm(
OperandVector &Operands) {
2075 StringRef
Identifier = getTok().getIdentifier();
2076 if (
Identifier.compare_insensitive(
"inf") == 0) {
2079 getTok().getEndLoc(), isRV64()));
2080 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2083 getTok().getEndLoc(), isRV64()));
2084 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2087 getTok().getEndLoc(), isRV64()));
2089 return TokError(
"invalid floating point literal");
2100 const AsmToken &Tok = getTok();
2102 return TokError(
"invalid floating point immediate");
2105 APFloat RealVal(APFloat::IEEEdouble());
2107 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2109 return TokError(
"invalid floating point representation");
2112 RealVal.changeSign();
2114 Operands.
push_back(RISCVOperand::createFPImm(
2115 RealVal.bitcastToAPInt().getZExtValue(), S));
2122ParseStatus RISCVAsmParser::parseExpression(
OperandVector &Operands) {
2127 switch (getLexer().getKind()) {
2139 if (getParser().parseExpression(Res,
E))
2143 return parseOperandWithSpecifier(Operands);
2146 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2150ParseStatus RISCVAsmParser::parseOperandWithSpecifier(
OperandVector &Operands) {
2156 const MCExpr *Expr =
nullptr;
2157 bool Failed = parseExprWithSpecifier(Expr,
E);
2159 Operands.
push_back(RISCVOperand::createExpr(Expr, S,
E, isRV64()));
2163bool RISCVAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
2164 SMLoc Loc = getLoc();
2166 return TokError(
"expected '%' relocation specifier");
2167 StringRef
Identifier = getParser().getTok().getIdentifier();
2170 return TokError(
"invalid relocation specifier");
2176 const MCExpr *SubExpr;
2177 if (getParser().parseParenExpression(SubExpr,
E))
2184bool RISCVAsmParser::parseDataExpr(
const MCExpr *&Res) {
2187 return parseExprWithSpecifier(Res,
E);
2188 return getParser().parseExpression(Res);
2191ParseStatus RISCVAsmParser::parseBareSymbol(
OperandVector &Operands) {
2199 AsmToken Tok = getLexer().getTok();
2201 if (getParser().parseIdentifier(Identifier))
2211 getLexer().UnLex(Tok);
2219 switch (getLexer().getKind()) {
2221 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2234 if (getParser().parseExpression(Expr,
E))
2237 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2241ParseStatus RISCVAsmParser::parseCallSymbol(
OperandVector &Operands) {
2247 std::string
Identifier(getTok().getIdentifier());
2253 SMLoc Loc = getLoc();
2254 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2255 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2269 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2273ParseStatus RISCVAsmParser::parsePseudoJumpSymbol(
OperandVector &Operands) {
2278 if (getParser().parseExpression(Res,
E))
2281 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef)
2282 return Error(S,
"operand must be a valid jump target");
2285 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2289ParseStatus RISCVAsmParser::parseJALOffset(
OperandVector &Operands) {
2303 return parseExpression(Operands);
2306bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2307 unsigned &Sew,
unsigned &Lmul,
2308 bool &Fractional,
bool &TailAgnostic,
2309 bool &MaskAgnostic,
bool &AltFmt) {
2314 if (State < VTypeState::SeenSew &&
Identifier.consume_front(
"e")) {
2316 if (Identifier ==
"16alt") {
2319 }
else if (Identifier ==
"8alt") {
2329 State = VTypeState::SeenSew;
2333 if (State < VTypeState::SeenLmul &&
Identifier.consume_front(
"m")) {
2336 if (Identifier ==
"a" || Identifier ==
"u") {
2338 State = VTypeState::SeenMaskPolicy;
2349 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2350 unsigned MinLMUL = ELEN / 8;
2353 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2354 Twine(MinLMUL) +
" is reserved");
2357 State = VTypeState::SeenLmul;
2361 if (State < VTypeState::SeenTailPolicy &&
Identifier.starts_with(
"t")) {
2362 if (Identifier ==
"ta")
2363 TailAgnostic =
true;
2364 else if (Identifier ==
"tu")
2365 TailAgnostic =
false;
2369 State = VTypeState::SeenTailPolicy;
2373 if (State < VTypeState::SeenMaskPolicy &&
Identifier.starts_with(
"m")) {
2374 if (Identifier ==
"ma")
2375 MaskAgnostic =
true;
2376 else if (Identifier ==
"mu")
2377 MaskAgnostic =
false;
2381 State = VTypeState::SeenMaskPolicy;
2388ParseStatus RISCVAsmParser::parseVTypeI(
OperandVector &Operands) {
2394 bool Fractional =
false;
2395 bool TailAgnostic =
false;
2396 bool MaskAgnostic =
false;
2399 VTypeState State = VTypeState::SeenNothingYet;
2401 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2402 MaskAgnostic, AltFmt)) {
2404 if (State == VTypeState::SeenNothingYet)
2413 State == VTypeState::SeenNothingYet)
2414 return generateVTypeError(S);
2418 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2419 unsigned MaxSEW = ELEN / Lmul;
2421 if (MaxSEW >= 8 && Sew > MaxSEW)
2422 Warning(S,
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2423 " and LMUL == mf" + Twine(Lmul) +
2424 " may not be compatible with all RVV implementations");
2429 Operands.
push_back(RISCVOperand::createVType(VTypeI, S));
2433bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2434 if (STI->
hasFeature(RISCV::FeatureStdExtZvfbfa) ||
2435 STI->
hasFeature(RISCV::FeatureStdExtZvfofp8min) ||
2436 STI->
hasFeature(RISCV::FeatureVendorXSfvfbfexp16e))
2440 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2444 "e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2447ParseStatus RISCVAsmParser::parseXSfmmVType(
OperandVector &Operands) {
2464 if (Identifier !=
"16alt")
2493 Operands.
push_back(RISCVOperand::createVType(
2499 return generateXSfmmVTypeError(S);
2502bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
2503 return Error(ErrorLoc,
"operand must be e[8|16|16alt|32|64],w[1|2|4]");
2506ParseStatus RISCVAsmParser::parseMaskReg(
OperandVector &Operands) {
2510 StringRef
Name = getLexer().getTok().getIdentifier();
2511 if (!
Name.consume_back(
".t"))
2512 return Error(getLoc(),
"expected '.t' suffix");
2517 if (
Reg != RISCV::V0)
2520 SMLoc
E = getTok().getEndLoc();
2526ParseStatus RISCVAsmParser::parseVScaleReg(
OperandVector &Operands) {
2530 StringRef
Name = getLexer().getTok().getIdentifier();
2531 if (!
Name.consume_back(
".scale"))
2532 return Error(getLoc(),
"expected '.scale' suffix");
2537 if (
Reg != RISCV::V0)
2540 SMLoc
E = getTok().getEndLoc();
2546ParseStatus RISCVAsmParser::parseGPRAsFPR64(
OperandVector &Operands) {
2547 if (!isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2550 return parseGPRAsFPR(Operands);
2553ParseStatus RISCVAsmParser::parseGPRAsFPR(
OperandVector &Operands) {
2557 StringRef
Name = getLexer().getTok().getIdentifier();
2563 SMLoc
E = getTok().getEndLoc();
2565 Operands.
push_back(RISCVOperand::createReg(
2566 Reg, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2570ParseStatus RISCVAsmParser::parseGPRPairAsFPR64(
OperandVector &Operands) {
2571 if (isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2577 StringRef
Name = getLexer().getTok().getIdentifier();
2583 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2586 if ((
Reg - RISCV::X0) & 1) {
2589 if (getSTI().hasFeature(RISCV::FeatureStdExtZfinx))
2590 return TokError(
"double precision floating point operands must use even "
2591 "numbered X register");
2596 SMLoc
E = getTok().getEndLoc();
2599 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2601 Reg, RISCV::sub_gpr_even,
2602 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2603 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2607template <
bool IsRV64>
2608ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands) {
2609 return parseGPRPair(Operands, IsRV64);
2612ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands,
2619 if (!IsRV64Inst && isRV64())
2625 StringRef
Name = getLexer().getTok().getIdentifier();
2631 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2634 if ((
Reg - RISCV::X0) & 1)
2635 return TokError(
"register must be even");
2638 SMLoc
E = getTok().getEndLoc();
2641 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2643 Reg, RISCV::sub_gpr_even,
2644 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2645 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E));
2649ParseStatus RISCVAsmParser::parseFRMArg(
OperandVector &Operands) {
2652 "operand must be a valid floating point rounding mode mnemonic");
2654 StringRef Str = getLexer().getTok().getIdentifier();
2659 "operand must be a valid floating point rounding mode mnemonic");
2661 Operands.
push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2666ParseStatus RISCVAsmParser::parseFenceArg(
OperandVector &Operands) {
2667 const AsmToken &Tok = getLexer().getTok();
2673 Operands.
push_back(RISCVOperand::createFenceArg(0, getLoc()));
2687 for (
char c : Str) {
2716 Operands.
push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2722 return TokError(
"operand must be formed of letters selected in-order from "
2726ParseStatus RISCVAsmParser::parseMemOpBaseReg(
OperandVector &Operands) {
2729 Operands.
push_back(RISCVOperand::createToken(
"(", getLoc()));
2731 if (!parseRegister(Operands).isSuccess())
2732 return Error(getLoc(),
"expected register");
2736 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
2741ParseStatus RISCVAsmParser::parseZeroOffsetMemOp(
OperandVector &Operands) {
2760 std::unique_ptr<RISCVOperand> OptionalImmOp;
2767 SMLoc ImmStart = getLoc();
2768 if (getParser().parseIntToken(ImmVal,
2769 "expected '(' or optional integer offset"))
2774 SMLoc ImmEnd = getLoc();
2777 ImmStart, ImmEnd, isRV64());
2781 OptionalImmOp ?
"expected '(' after optional integer offset"
2782 :
"expected '(' or optional integer offset"))
2785 if (!parseRegister(Operands).isSuccess())
2786 return Error(getLoc(),
"expected register");
2792 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2794 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2795 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2800ParseStatus RISCVAsmParser::parseRegReg(
OperandVector &Operands) {
2806 StringRef OffsetRegName = getLexer().getTok().getIdentifier();
2809 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(OffsetReg))
2810 return Error(getLoc(),
"expected GPR register");
2817 return Error(getLoc(),
"expected GPR register");
2819 StringRef BaseRegName = getLexer().getTok().getIdentifier();
2822 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(BaseReg))
2823 return Error(getLoc(),
"expected GPR register");
2829 Operands.
push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));
2841ParseStatus RISCVAsmParser::parseRegList(
OperandVector &Operands,
2842 bool MustIncludeS0) {
2854 return Error(getLoc(),
"invalid register");
2856 StringRef
RegName = getTok().getIdentifier();
2859 return Error(getLoc(),
"invalid register");
2862 UsesXRegs =
RegName[0] ==
'x';
2863 if (
Reg != RISCV::X1)
2864 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2865 }
else if (RegEnd == RISCV::X1) {
2866 if (
Reg != RISCV::X8 || (UsesXRegs != (
RegName[0] ==
'x')))
2867 return Error(getLoc(), Twine(
"register must be '") +
2868 (UsesXRegs ?
"x8" :
"s0") +
"'");
2869 }
else if (RegEnd == RISCV::X9 && UsesXRegs) {
2870 if (
Reg != RISCV::X18 || (
RegName[0] !=
'x'))
2871 return Error(getLoc(),
"register must be 'x18'");
2873 return Error(getLoc(),
"too many register ranges");
2880 SMLoc MinusLoc = getLoc();
2882 if (RegEnd == RISCV::X1)
2883 return Error(MinusLoc, Twine(
"register '") + (UsesXRegs ?
"x1" :
"ra") +
2884 "' cannot start a multiple register range");
2887 return Error(getLoc(),
"invalid register");
2889 StringRef
RegName = getTok().getIdentifier();
2892 return Error(getLoc(),
"invalid register");
2894 if (RegEnd == RISCV::X8) {
2895 if ((
Reg != RISCV::X9 &&
2897 (UsesXRegs != (
RegName[0] ==
'x'))) {
2899 return Error(getLoc(),
"register must be 'x9'");
2900 return Error(getLoc(),
"register must be in the range 's1' to 's11'");
2902 }
else if (RegEnd == RISCV::X18) {
2904 return Error(getLoc(),
2905 "register must be in the range 'x19' to 'x27'");
2918 if (RegEnd == RISCV::X26)
2919 return Error(S,
"invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "
2920 "x18-x26}' is not supported");
2926 return Error(S,
"register list must include 's0' or 'x8'");
2928 Operands.
push_back(RISCVOperand::createRegList(Encode, S));
2933ParseStatus RISCVAsmParser::parseZcmpStackAdj(
OperandVector &Operands,
2934 bool ExpectNegative) {
2943 auto *RegListOp =
static_cast<RISCVOperand *
>(Operands.
back().
get());
2944 if (!RegListOp->isRegList())
2947 unsigned RlistEncode = RegListOp->RegList.Encoding;
2951 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||
2952 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {
2953 int64_t
Lower = StackAdjBase;
2954 int64_t
Upper = StackAdjBase + 48;
2955 if (ExpectNegative) {
2960 return generateImmOutOfRangeError(S,
Lower,
Upper,
2961 "stack adjustment for register list must "
2962 "be a multiple of 16 bytes in the range");
2966 Operands.
push_back(RISCVOperand::createStackAdj(StackAdj, S));
2974bool RISCVAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
2978 MatchOperandParserImpl(Operands, Mnemonic,
true);
2985 if (parseRegister(Operands,
true).isSuccess())
2989 if (parseExpression(Operands).isSuccess()) {
2992 return !parseMemOpBaseReg(Operands).isSuccess();
2997 Error(getLoc(),
"unknown operand");
3001bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &Info,
3002 StringRef Name, SMLoc NameLoc,
3008 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
3012 Operands.
push_back(RISCVOperand::createToken(Name, NameLoc));
3021 if (parseOperand(Operands, Name))
3027 if (parseOperand(Operands, Name))
3031 if (getParser().parseEOL(
"unexpected token")) {
3032 getParser().eatToEndOfStatement();
3038bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
3042 Kind = RE->getSpecifier();
3043 Expr = RE->getSubExpr();
3052bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
3061ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
3062 StringRef IDVal = DirectiveID.
getString();
3064 if (IDVal ==
".option")
3065 return parseDirectiveOption();
3066 if (IDVal ==
".attribute")
3067 return parseDirectiveAttribute();
3068 if (IDVal ==
".insn")
3069 return parseDirectiveInsn(DirectiveID.
getLoc());
3070 if (IDVal ==
".variant_cc")
3071 return parseDirectiveVariantCC();
3076bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
3077 bool FromOptionDirective) {
3080 clearFeatureBits(Feature.Value, Feature.Key);
3087 raw_string_ostream OutputErrMsg(Buffer);
3088 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3089 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
3090 << ErrMsg.getMessage();
3093 return Error(Loc, OutputErrMsg.str());
3095 auto &ISAInfo = *ParseResult;
3098 if (ISAInfo->hasExtension(Feature.Key))
3099 setFeatureBits(Feature.Value, Feature.Key);
3101 if (FromOptionDirective) {
3102 if (ISAInfo->getXLen() == 32 && isRV64())
3103 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3104 else if (ISAInfo->getXLen() == 64 && !isRV64())
3105 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3108 if (ISAInfo->getXLen() == 32)
3109 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
3110 else if (ISAInfo->getXLen() == 64)
3111 setFeatureBits(RISCV::Feature64Bit,
"64bit");
3113 return Error(Loc,
"bad arch string " + Arch);
3115 Result = ISAInfo->toString();
3119bool RISCVAsmParser::parseDirectiveOption() {
3120 MCAsmParser &Parser = getParser();
3122 AsmToken Tok = Parser.
getTok();
3130 if (Option ==
"push") {
3134 getTargetStreamer().emitDirectiveOptionPush();
3139 if (Option ==
"pop") {
3144 getTargetStreamer().emitDirectiveOptionPop();
3145 if (popFeatureBits())
3146 return Error(StartLoc,
".option pop with no .option push");
3151 if (Option ==
"arch") {
3159 Type = RISCVOptionArchArgType::Plus;
3161 Type = RISCVOptionArchArgType::Minus;
3162 else if (!
Args.empty())
3164 "unexpected token, expected + or -");
3166 Type = RISCVOptionArchArgType::Full;
3170 "unexpected token, expected identifier");
3176 if (
Type == RISCVOptionArchArgType::Full) {
3178 if (resetToArch(Arch, Loc, Result,
true))
3187 Loc,
"extension version number parsing not currently implemented");
3190 if (!enableExperimentalExtension() &&
3192 return Error(Loc,
"unexpected experimental extensions");
3194 if (Ext == std::end(
RISCVFeatureKV) || StringRef(Ext->Key) != Feature)
3195 return Error(Loc,
"unknown extension feature");
3199 if (
Type == RISCVOptionArchArgType::Plus) {
3202 setFeatureBits(Ext->Value, Ext->Key);
3205 copySTI().setFeatureBits(OldFeatureBits);
3206 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3209 raw_string_ostream OutputErrMsg(Buffer);
3210 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3211 OutputErrMsg << ErrMsg.getMessage();
3214 return Error(Loc, OutputErrMsg.str());
3217 assert(
Type == RISCVOptionArchArgType::Minus);
3222 if (getSTI().hasFeature(Feature.Value) &&
3223 Feature.Implies.test(Ext->Value))
3224 return Error(Loc, Twine(
"can't disable ") + Ext->Key +
3225 " extension; " + Feature.Key +
3226 " extension requires " + Ext->Key +
3230 clearFeatureBits(Ext->Value, Ext->Key);
3237 getTargetStreamer().emitDirectiveOptionArch(Args);
3239 if (
auto ParseResult =
3241 getTargetStreamer().setArchString((*ParseResult)->toString());
3245 if (Option ==
"exact") {
3249 getTargetStreamer().emitDirectiveOptionExact();
3250 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3251 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3255 if (Option ==
"noexact") {
3259 getTargetStreamer().emitDirectiveOptionNoExact();
3260 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3261 setFeatureBits(RISCV::FeatureRelax,
"relax");
3265 if (Option ==
"rvc") {
3269 getTargetStreamer().emitDirectiveOptionRVC();
3270 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3271 if (
auto ParseResult =
3273 getTargetStreamer().setArchString((*ParseResult)->toString());
3277 if (Option ==
"norvc") {
3281 getTargetStreamer().emitDirectiveOptionNoRVC();
3282 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3283 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3284 if (
auto ParseResult =
3286 getTargetStreamer().setArchString((*ParseResult)->toString());
3290 if (Option ==
"pic") {
3294 getTargetStreamer().emitDirectiveOptionPIC();
3295 ParserOptions.IsPicEnabled =
true;
3299 if (Option ==
"nopic") {
3303 getTargetStreamer().emitDirectiveOptionNoPIC();
3304 ParserOptions.IsPicEnabled =
false;
3308 if (Option ==
"relax") {
3312 getTargetStreamer().emitDirectiveOptionRelax();
3313 setFeatureBits(RISCV::FeatureRelax,
"relax");
3317 if (Option ==
"norelax") {
3321 getTargetStreamer().emitDirectiveOptionNoRelax();
3322 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3328 "unknown option, expected 'push', 'pop', "
3329 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3330 "'exact', or 'noexact'");
3338bool RISCVAsmParser::parseDirectiveAttribute() {
3339 MCAsmParser &Parser = getParser();
3345 std::optional<unsigned> Ret =
3348 return Error(TagLoc,
"attribute name not recognised: " + Name);
3352 const MCExpr *AttrExpr;
3359 if (check(!CE, TagLoc,
"expected numeric constant"))
3362 Tag =
CE->getValue();
3368 StringRef StringValue;
3369 int64_t IntegerValue = 0;
3370 bool IsIntegerValue =
true;
3375 IsIntegerValue =
false;
3378 if (IsIntegerValue) {
3379 const MCExpr *ValueExpr;
3385 return Error(ValueExprLoc,
"expected numeric constant");
3386 IntegerValue =
CE->getValue();
3399 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3401 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3404 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3408 getTargetStreamer().emitTextAttribute(
Tag, Result);
3412 getTargetStreamer().setArchString(Result);
3420 .
Cases({
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s"},
true)
3421 .Cases({
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj"},
3423 .
Cases({
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es"},
3432bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3433 MCAsmParser &Parser = getParser();
3440 std::optional<int64_t>
Length;
3450 return Error(ErrorLoc,
3451 "instruction lengths must be a non-zero multiple of two");
3455 return Error(ErrorLoc,
3456 "instruction lengths over 64 bits are not supported");
3462 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3467 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3468 return Error(ErrorLoc,
3469 "instruction length does not match the encoding");
3472 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3475 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3478 if (!getSTI().hasFeature(RISCV::FeatureStdExtZca) &&
3479 (EncodingDerivedLength == 2))
3480 return Error(ErrorLoc,
"compressed instructions are not allowed");
3482 if (getParser().parseEOL(
"invalid operand for instruction")) {
3483 getParser().eatToEndOfStatement();
3491 Opcode = RISCV::Insn16;
3494 Opcode = RISCV::Insn32;
3497 Opcode = RISCV::Insn48;
3500 Opcode = RISCV::Insn64;
3506 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3508 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3513 return Error(ErrorLoc,
"invalid instruction format");
3515 std::string FormatName = (
".insn_" +
Format).str();
3517 ParseInstructionInfo
Info;
3520 if (parseInstruction(Info, FormatName, L, Operands))
3525 return matchAndEmitInstruction(L, Opcode, Operands, Parser.
getStreamer(),
3532bool RISCVAsmParser::parseDirectiveVariantCC() {
3534 if (getParser().parseIdentifier(Name))
3535 return TokError(
"expected symbol name");
3538 getTargetStreamer().emitDirectiveVariantCC(
3543void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3546 const MCSubtargetInfo &STI = getSTI();
3547 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3550 ++RISCVNumInstrsCompressed;
3554void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3559 for (MCInst &Inst : Seq) {
3560 emitToStreamer(Out, Inst);
3564void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3565 const MCExpr *Symbol,
3567 unsigned SecondOpcode, SMLoc IDLoc,
3579 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3584 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3587 .addExpr(RefToLinkTmpLabel));
3590void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3604void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3614 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3615 emitAuipcInstPair(DestReg, DestReg, Symbol,
RISCV::S_GOT_HI, SecondOpcode,
3619void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3628 if (ParserOptions.IsPicEnabled)
3629 emitLoadGlobalAddress(Inst, IDLoc, Out);
3631 emitLoadLocalAddress(Inst, IDLoc, Out);
3634void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3644 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3645 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3646 SecondOpcode, IDLoc, Out);
3649void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3659 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3660 RISCV::ADDI, IDLoc, Out);
3663void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3664 SMLoc IDLoc, MCStreamer &Out,
3673 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3675 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3679 if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].
contains(TmpReg)) {
3680 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3681 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3689void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3690 int64_t Width, SMLoc IDLoc,
3699 const MCOperand &DestReg = Inst.
getOperand(0);
3700 const MCOperand &SourceReg = Inst.
getOperand(1);
3702 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3703 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3705 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3707 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3712 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3718void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
3725 emitToStreamer(Out, MCInstBuilder(Opcode)
3729 .addReg(MCRegister())
3731 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
3742 "The destination register should not be V0.");
3743 emitToStreamer(Out, MCInstBuilder(Opcode)
3749 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
3761 "The destination register should be V0.");
3763 "The temporary vector register should not be V0.");
3764 emitToStreamer(Out, MCInstBuilder(Opcode)
3768 .addReg(MCRegister())
3770 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3782 "The temporary vector register should not be V0.");
3783 emitToStreamer(Out, MCInstBuilder(Opcode)
3787 .addReg(MCRegister())
3789 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3794 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3799 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
3807bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
3809 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3812 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
3813 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3814 "%tprel_add specifier");
3820bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
3822 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
3825 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
3826 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
3827 "%tlsdesc_call specifier");
3833std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3834 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
3837std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3838 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3842std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3843 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3851 case RISCV::VLOXSEG2EI8_V:
3852 case RISCV::VLOXSEG2EI16_V:
3853 case RISCV::VLOXSEG2EI32_V:
3854 case RISCV::VLOXSEG2EI64_V:
3855 case RISCV::VLUXSEG2EI8_V:
3856 case RISCV::VLUXSEG2EI16_V:
3857 case RISCV::VLUXSEG2EI32_V:
3858 case RISCV::VLUXSEG2EI64_V:
3860 case RISCV::VLOXSEG3EI8_V:
3861 case RISCV::VLOXSEG3EI16_V:
3862 case RISCV::VLOXSEG3EI32_V:
3863 case RISCV::VLOXSEG3EI64_V:
3864 case RISCV::VLUXSEG3EI8_V:
3865 case RISCV::VLUXSEG3EI16_V:
3866 case RISCV::VLUXSEG3EI32_V:
3867 case RISCV::VLUXSEG3EI64_V:
3869 case RISCV::VLOXSEG4EI8_V:
3870 case RISCV::VLOXSEG4EI16_V:
3871 case RISCV::VLOXSEG4EI32_V:
3872 case RISCV::VLOXSEG4EI64_V:
3873 case RISCV::VLUXSEG4EI8_V:
3874 case RISCV::VLUXSEG4EI16_V:
3875 case RISCV::VLUXSEG4EI32_V:
3876 case RISCV::VLUXSEG4EI64_V:
3878 case RISCV::VLOXSEG5EI8_V:
3879 case RISCV::VLOXSEG5EI16_V:
3880 case RISCV::VLOXSEG5EI32_V:
3881 case RISCV::VLOXSEG5EI64_V:
3882 case RISCV::VLUXSEG5EI8_V:
3883 case RISCV::VLUXSEG5EI16_V:
3884 case RISCV::VLUXSEG5EI32_V:
3885 case RISCV::VLUXSEG5EI64_V:
3887 case RISCV::VLOXSEG6EI8_V:
3888 case RISCV::VLOXSEG6EI16_V:
3889 case RISCV::VLOXSEG6EI32_V:
3890 case RISCV::VLOXSEG6EI64_V:
3891 case RISCV::VLUXSEG6EI8_V:
3892 case RISCV::VLUXSEG6EI16_V:
3893 case RISCV::VLUXSEG6EI32_V:
3894 case RISCV::VLUXSEG6EI64_V:
3896 case RISCV::VLOXSEG7EI8_V:
3897 case RISCV::VLOXSEG7EI16_V:
3898 case RISCV::VLOXSEG7EI32_V:
3899 case RISCV::VLOXSEG7EI64_V:
3900 case RISCV::VLUXSEG7EI8_V:
3901 case RISCV::VLUXSEG7EI16_V:
3902 case RISCV::VLUXSEG7EI32_V:
3903 case RISCV::VLUXSEG7EI64_V:
3905 case RISCV::VLOXSEG8EI8_V:
3906 case RISCV::VLOXSEG8EI16_V:
3907 case RISCV::VLOXSEG8EI32_V:
3908 case RISCV::VLOXSEG8EI64_V:
3909 case RISCV::VLUXSEG8EI8_V:
3910 case RISCV::VLUXSEG8EI16_V:
3911 case RISCV::VLUXSEG8EI32_V:
3912 case RISCV::VLUXSEG8EI64_V:
3918 if (RISCVMCRegisterClasses[RISCV::VRM2RegClassID].
contains(
Reg))
3920 if (RISCVMCRegisterClasses[RISCV::VRM4RegClassID].
contains(
Reg))
3922 if (RISCVMCRegisterClasses[RISCV::VRM8RegClassID].
contains(
Reg))
3929 case RISCV::VFWMMACC_VV_SCALE:
3930 case RISCV::VFQMMACC_VV_SCALE:
3931 case RISCV::VF8WMMACC_VV_SCALE:
3932 case RISCV::VFWIMMACC_VV:
3933 case RISCV::VFQIMMACC_VV:
3934 case RISCV::VF8WIMMACC_VV:
3941bool RISCVAsmParser::validateInstruction(MCInst &Inst,
3945 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3946 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3949 if (DestReg == TempReg) {
3950 SMLoc Loc = Operands.
back()->getStartLoc();
3951 return Error(Loc,
"the temporary vector register cannot be the same as "
3952 "the destination register");
3956 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3957 Opcode == RISCV::TH_LWD) {
3962 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
3963 SMLoc Loc = Operands[1]->getStartLoc();
3964 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
3968 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
3972 SMLoc Loc = Operands[1]->getStartLoc();
3973 return Error(Loc,
"rs1 and rs2 must be different");
3978 auto CheckOperandDoesNotOverlapV0 = [&](
int OperandIdx,
3979 unsigned ParsedIdx) {
3981 return Error(Operands[ParsedIdx]->getStartLoc(),
3982 "vd, vs1, and vs2 cannot overlap v0.scale");
3987 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
3989 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
3991 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
3992 assert(DestIdx >= 0 && VS1Idx >= 0 && VS2Idx >= 0 &&
3993 "Unexpected Zvvfmm scaled operand list");
3995 if (CheckOperandDoesNotOverlapV0(DestIdx, 1) ||
3996 CheckOperandDoesNotOverlapV0(VS1Idx, 2) ||
3997 CheckOperandDoesNotOverlapV0(VS2Idx, 3))
4001 const MCInstrDesc &MCID = MII.
get(Opcode);
4005 int DestIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4009 const MCParsedAsmOperand *ParsedOp = Operands[1].get();
4010 if (!ParsedOp->
isReg()) {
4013 ParsedOp = Operands[2].get();
4015 assert(ParsedOp->
getReg() == DestReg &&
"Can't find parsed dest operand");
4019 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4023 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4024 assert(VS2Idx >= 0 &&
"No vs2 operand?");
4025 unsigned CheckEncoding =
4028 for (
unsigned i = 0; i < std::max(NF, Lmul); i++) {
4029 if ((DestEncoding + i) == CheckEncoding)
4030 return Error(Loc,
"the destination vector register group cannot overlap"
4031 " the source vector register group");
4036 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4040 unsigned CheckEncoding =
4042 for (
unsigned i = 0; i < Lmul; i++) {
4043 if ((DestEncoding + i) == CheckEncoding)
4045 "the destination vector register group cannot overlap"
4046 " the source vector register group");
4052 int VMIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vm);
4053 assert(VMIdx >= 0 &&
"No vm operand?");
4055 if (DestReg == RISCV::V0) {
4058 return Error(Loc,
"the destination vector register group cannot be V0");
4066 "Unexpected mask operand register");
4068 return Error(Loc,
"the destination vector register group cannot overlap"
4069 " the mask register");
4076bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
4084 case RISCV::PseudoC_ADDI_NOP: {
4086 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
4096 if (getSTI().hasFeature(RISCV::Feature64Bit))
4098 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV32)
4103 case RISCV::PACKW: {
4107 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV64)
4112 case RISCV::PseudoLLAImm:
4113 case RISCV::PseudoLAImm:
4114 case RISCV::PseudoLI: {
4120 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
4132 emitLoadImm(
Reg, Imm, Out);
4135 case RISCV::PseudoLLA:
4136 emitLoadLocalAddress(Inst, IDLoc, Out);
4138 case RISCV::PseudoLGA:
4139 emitLoadGlobalAddress(Inst, IDLoc, Out);
4141 case RISCV::PseudoLA:
4142 emitLoadAddress(Inst, IDLoc, Out);
4144 case RISCV::PseudoLA_TLS_IE:
4145 emitLoadTLSIEAddress(Inst, IDLoc, Out);
4147 case RISCV::PseudoLA_TLS_GD:
4148 emitLoadTLSGDAddress(Inst, IDLoc, Out);
4150 case RISCV::PseudoLB:
4151 case RISCV::PseudoQC_E_LB:
4152 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
4154 case RISCV::PseudoLBU:
4155 case RISCV::PseudoQC_E_LBU:
4156 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
4158 case RISCV::PseudoLH:
4159 case RISCV::PseudoQC_E_LH:
4160 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
4162 case RISCV::PseudoLHU:
4163 case RISCV::PseudoQC_E_LHU:
4164 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
4166 case RISCV::PseudoLW:
4167 case RISCV::PseudoQC_E_LW:
4168 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
4170 case RISCV::PseudoLWU:
4171 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
4173 case RISCV::PseudoLD:
4174 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
4176 case RISCV::PseudoLD_RV32:
4177 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
4179 case RISCV::PseudoFLH:
4180 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
4182 case RISCV::PseudoFLW:
4183 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
4185 case RISCV::PseudoFLD:
4186 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
4188 case RISCV::PseudoFLQ:
4189 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
4191 case RISCV::PseudoSB:
4192 case RISCV::PseudoQC_E_SB:
4193 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
4195 case RISCV::PseudoSH:
4196 case RISCV::PseudoQC_E_SH:
4197 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
4199 case RISCV::PseudoSW:
4200 case RISCV::PseudoQC_E_SW:
4201 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
4203 case RISCV::PseudoSD:
4204 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
4206 case RISCV::PseudoSD_RV32:
4207 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
4209 case RISCV::PseudoFSH:
4210 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
4212 case RISCV::PseudoFSW:
4213 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
4215 case RISCV::PseudoFSD:
4216 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4218 case RISCV::PseudoFSQ:
4219 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4221 case RISCV::PseudoAddTPRel:
4222 if (checkPseudoAddTPRel(Inst, Operands))
4225 case RISCV::PseudoTLSDESCCall:
4226 if (checkPseudoTLSDESCCall(Inst, Operands))
4229 case RISCV::PseudoSEXT_B:
4230 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4232 case RISCV::PseudoSEXT_H:
4233 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4235 case RISCV::PseudoZEXT_H:
4236 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4238 case RISCV::PseudoZEXT_W:
4239 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4241 case RISCV::PseudoVMSGEU_VX:
4242 case RISCV::PseudoVMSGEU_VX_M:
4243 case RISCV::PseudoVMSGEU_VX_M_T:
4244 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4246 case RISCV::PseudoVMSGE_VX:
4247 case RISCV::PseudoVMSGE_VX_M:
4248 case RISCV::PseudoVMSGE_VX_M_T:
4249 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4251 case RISCV::PseudoVMSGE_VI:
4252 case RISCV::PseudoVMSLT_VI: {
4256 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4258 emitToStreamer(Out, MCInstBuilder(
Opc)
4266 case RISCV::PseudoVMSGEU_VI:
4267 case RISCV::PseudoVMSLTU_VI: {
4274 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4277 emitToStreamer(Out, MCInstBuilder(
Opc)
4285 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4288 emitToStreamer(Out, MCInstBuilder(
Opc)
4298 case RISCV::PseudoCV_ELW:
4299 emitLoadStoreSymbol(Inst, RISCV::CV_ELW, IDLoc, Out,
false);
4303 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))
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 MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
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)
@ 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.