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"
220 return parseRegList(Operands,
true);
226 bool ExpectNegative =
false);
228 return parseZcmpStackAdj(Operands,
true);
231 bool parseOperand(
OperandVector &Operands, StringRef Mnemonic);
232 bool parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
233 bool parseDataExpr(
const MCExpr *&Res)
override;
235 bool parseDirectiveOption();
236 bool parseDirectiveAttribute();
237 bool parseDirectiveInsn(SMLoc L);
238 bool parseDirectiveVariantCC();
243 bool resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
244 bool FromOptionDirective);
246 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
247 if (!(getSTI().hasFeature(Feature))) {
248 MCSubtargetInfo &STI = copySTI();
254 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
258 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
259 if (getSTI().hasFeature(Feature)) {
260 MCSubtargetInfo &STI = copySTI();
261 setAvailableFeatures(
266 void pushFeatureBits() {
267 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
268 "These two stacks must be kept synchronized");
269 FeatureBitStack.push_back(getSTI().getFeatureBits());
270 ParserOptionsStack.push_back(ParserOptions);
273 bool popFeatureBits() {
274 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
275 "These two stacks must be kept synchronized");
276 if (FeatureBitStack.empty())
279 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
280 copySTI().setFeatureBits(FeatureBits);
281 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
283 ParserOptions = ParserOptionsStack.pop_back_val();
288 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
289 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
290 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
293 enum RISCVMatchResultTy :
unsigned {
294 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
295#define GET_OPERAND_DIAGNOSTIC_TYPES
296#include "RISCVGenAsmMatcher.inc"
297#undef GET_OPERAND_DIAGNOSTIC_TYPES
301 static bool isSymbolDiff(
const MCExpr *Expr);
303 RISCVAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
304 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
305 : MCTargetAsmParser(
Options, STI, MII) {
312 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
314 auto ABIName = StringRef(
Options.ABIName);
315 if (ABIName.ends_with(
"f") && !getSTI().hasFeature(RISCV::FeatureStdExtF)) {
316 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
317 "doesn't support the F instruction set extension (ignoring "
319 }
else if (ABIName.ends_with(
"d") &&
320 !getSTI().hasFeature(RISCV::FeatureStdExtD)) {
321 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
322 "doesn't support the D instruction set extension (ignoring "
335 getTargetStreamer().emitTargetAttributes(STI,
false);
401 MCRegister OffsetReg;
404 SMLoc StartLoc, EndLoc;
419 RISCVOperand(KindTy K) : Kind(
K) {}
422 RISCVOperand(
const RISCVOperand &o) : MCParsedAsmOperand() {
424 StartLoc =
o.StartLoc;
427 case KindTy::Register:
430 case KindTy::Expression:
433 case KindTy::FPImmediate:
439 case KindTy::SystemRegister:
451 case KindTy::RegList:
454 case KindTy::StackAdj:
455 StackAdj =
o.StackAdj;
463 bool isToken()
const override {
return Kind == KindTy::Token; }
464 bool isReg()
const override {
return Kind == KindTy::Register; }
465 bool isExpr()
const {
return Kind == KindTy::Expression; }
466 bool isV0Reg()
const {
467 return Kind == KindTy::Register &&
Reg.Reg == RISCV::V0;
469 bool isAnyReg()
const {
470 return Kind == KindTy::Register &&
471 (RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.Reg) ||
472 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg.Reg) ||
473 RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg.Reg));
475 bool isAnyRegC()
const {
476 return Kind == KindTy::Register &&
477 (RISCVMCRegisterClasses[RISCV::GPRCRegClassID].contains(
Reg.Reg) ||
478 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg.Reg));
480 bool isImm()
const override {
return isExpr(); }
481 bool isMem()
const override {
return false; }
482 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
483 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
484 bool isRegList()
const {
return Kind == KindTy::RegList; }
485 bool isRegListS0()
const {
486 return Kind == KindTy::RegList && RegList.Encoding !=
RISCVZC::RA;
488 bool isStackAdj()
const {
return Kind == KindTy::StackAdj; }
491 return Kind == KindTy::Register &&
492 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.Reg);
495 bool isGPRPair()
const {
496 return Kind == KindTy::Register &&
497 RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(
Reg.Reg);
500 bool isGPRPairC()
const {
501 return Kind == KindTy::Register &&
502 RISCVMCRegisterClasses[RISCV::GPRPairCRegClassID].contains(
Reg.Reg);
505 bool isGPRPairNoX0()
const {
506 return Kind == KindTy::Register &&
507 RISCVMCRegisterClasses[RISCV::GPRPairNoX0RegClassID].contains(
511 bool isGPRF16()
const {
512 return Kind == KindTy::Register &&
513 RISCVMCRegisterClasses[RISCV::GPRF16RegClassID].contains(
Reg.Reg);
516 bool isGPRF32()
const {
517 return Kind == KindTy::Register &&
518 RISCVMCRegisterClasses[RISCV::GPRF32RegClassID].contains(
Reg.Reg);
521 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
522 bool isGPRAsFPR16()
const {
return isGPRF16() &&
Reg.IsGPRAsFPR; }
523 bool isGPRAsFPR32()
const {
return isGPRF32() &&
Reg.IsGPRAsFPR; }
524 bool isGPRPairAsFPR64()
const {
return isGPRPair() &&
Reg.IsGPRAsFPR; }
526 static bool evaluateConstantExpr(
const MCExpr *Expr, int64_t &Imm) {
528 Imm =
CE->getValue();
537 template <
int N>
bool isBareSimmNLsb0()
const {
542 if (evaluateConstantExpr(
getExpr(), Imm))
543 return isShiftedInt<
N - 1, 1>(fixImmediateForRV32(Imm, isRV64Expr()));
546 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
552 template <
int N>
bool isBareSimmN()
const {
557 if (evaluateConstantExpr(
getExpr(), Imm))
558 return isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
561 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
567 bool isBareSymbol()
const {
570 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
574 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
578 bool isCallSymbol()
const {
581 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
585 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
589 bool isPseudoJumpSymbol()
const {
592 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
596 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
600 bool isTPRelAddSymbol()
const {
603 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
607 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
608 VK == ELF::R_RISCV_TPREL_ADD;
611 bool isTLSDESCCallSymbol()
const {
614 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
618 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
619 VK == ELF::R_RISCV_TLSDESC_CALL;
622 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
626 bool isVTypeI10()
const {
627 if (Kind == KindTy::VType)
631 bool isVTypeI11()
const {
632 if (Kind == KindTy::VType)
637 bool isXSfmmVType()
const {
643 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
646 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
647 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
651 bool isLoadFPImm()
const {
654 if (Kind != KindTy::FPImmediate)
657 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
660 return Idx >= 0 && Idx != 1;
663 bool isImmXLenLI()
const {
669 if (evaluateConstantExpr(
getExpr(), Imm))
672 return RISCVAsmParser::isSymbolDiff(
getExpr());
675 bool isImmXLenLI_Restricted()
const {
679 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
681 return IsConstantImm &&
685 template <
unsigned N>
bool isUImm()
const {
689 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
693 template <
unsigned N,
unsigned S>
bool isUImmShifted()
const {
697 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
701 template <
class Pred>
bool isUImmPred(Pred p)
const {
705 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
706 return IsConstantImm &&
p(Imm);
709 bool isUImmLog2XLen()
const {
710 if (isExpr() && isRV64Expr())
715 bool isUImmLog2XLenNonZero()
const {
716 if (isExpr() && isRV64Expr())
717 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<6>(Imm); });
718 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<5>(Imm); });
721 bool isUImmLog2XLenHalf()
const {
722 if (isExpr() && isRV64Expr())
727 bool isUImm1()
const {
return isUImm<1>(); }
728 bool isUImm2()
const {
return isUImm<2>(); }
729 bool isUImm3()
const {
return isUImm<3>(); }
730 bool isUImm4()
const {
return isUImm<4>(); }
731 bool isUImm5()
const {
return isUImm<5>(); }
732 bool isUImm6()
const {
return isUImm<6>(); }
733 bool isUImm7()
const {
return isUImm<7>(); }
734 bool isUImm8()
const {
return isUImm<8>(); }
735 bool isUImm9()
const {
return isUImm<9>(); }
736 bool isUImm10()
const {
return isUImm<10>(); }
737 bool isUImm11()
const {
return isUImm<11>(); }
738 bool isUImm16()
const {
return isUImm<16>(); }
739 bool isUImm20()
const {
return isUImm<20>(); }
740 bool isUImm32()
const {
return isUImm<32>(); }
741 bool isUImm48()
const {
return isUImm<48>(); }
742 bool isUImm64()
const {
return isUImm<64>(); }
744 bool isUImm5NonZero()
const {
745 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<5>(Imm); });
748 bool isUImm5GT3()
const {
749 return isUImmPred([](int64_t Imm) {
return isUInt<5>(Imm) &&
Imm > 3; });
752 bool isUImm4Plus1()
const {
754 [](int64_t Imm) {
return Imm > 0 &&
isUInt<4>(Imm - 1); });
757 bool isUImm5Plus1()
const {
759 [](int64_t Imm) {
return Imm > 0 &&
isUInt<5>(Imm - 1); });
762 bool isUImm6Plus1()
const {
764 [](int64_t Imm) {
return Imm > 0 &&
isUInt<6>(Imm - 1); });
767 bool isUImm5GE6Plus1()
const {
769 [](int64_t Imm) {
return Imm >= 6 &&
isUInt<5>(Imm - 1); });
772 bool isUImm5Slist()
const {
773 return isUImmPred([](int64_t Imm) {
774 return (Imm == 0) || (
Imm == 1) || (Imm == 2) || (
Imm == 4) ||
775 (Imm == 8) || (
Imm == 16) || (Imm == 15) || (
Imm == 31);
779 bool isUImm8GE32()
const {
780 return isUImmPred([](int64_t Imm) {
return isUInt<8>(Imm) &&
Imm >= 32; });
783 bool isRnumArg()
const {
785 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(10); });
788 bool isRnumArg_0_7()
const {
790 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(7); });
793 bool isRnumArg_1_10()
const {
795 [](int64_t Imm) {
return Imm >= INT64_C(1) &&
Imm <= INT64_C(10); });
798 bool isRnumArg_2_14()
const {
800 [](int64_t Imm) {
return Imm >= INT64_C(2) &&
Imm <= INT64_C(14); });
803 template <
unsigned N>
bool isSImm()
const {
807 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
808 return IsConstantImm &&
isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
811 template <
class Pred>
bool isSImmPred(Pred p)
const {
815 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
816 return IsConstantImm &&
p(fixImmediateForRV32(Imm, isRV64Expr()));
819 bool isSImm5()
const {
return isSImm<5>(); }
820 bool isSImm6()
const {
return isSImm<6>(); }
821 bool isSImm10()
const {
return isSImm<10>(); }
822 bool isSImm11()
const {
return isSImm<11>(); }
823 bool isSImm12()
const {
return isSImm<12>(); }
824 bool isSImm16()
const {
return isSImm<16>(); }
825 bool isSImm26()
const {
return isSImm<26>(); }
827 bool isSImm5NonZero()
const {
828 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<5>(Imm); });
831 bool isSImm6NonZero()
const {
832 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<6>(Imm); });
835 bool isCLUIImm()
const {
836 return isUImmPred([](int64_t Imm) {
837 return (
isUInt<5>(Imm) && Imm != 0) || (
Imm >= 0xfffe0 &&
Imm <= 0xfffff);
841 bool isUImm2Lsb0()
const {
return isUImmShifted<1, 1>(); }
843 bool isUImm5Lsb0()
const {
return isUImmShifted<4, 1>(); }
845 bool isUImm6Lsb0()
const {
return isUImmShifted<5, 1>(); }
847 bool isUImm7Lsb00()
const {
return isUImmShifted<5, 2>(); }
849 bool isUImm7Lsb000()
const {
return isUImmShifted<4, 3>(); }
851 bool isUImm8Lsb00()
const {
return isUImmShifted<6, 2>(); }
853 bool isUImm8Lsb000()
const {
return isUImmShifted<5, 3>(); }
855 bool isUImm9Lsb000()
const {
return isUImmShifted<6, 3>(); }
857 bool isUImm14Lsb00()
const {
return isUImmShifted<12, 2>(); }
859 bool isUImm10Lsb00NonZero()
const {
866 static int64_t fixImmediateForRV32(int64_t Imm,
bool IsRV64Imm) {
872 bool isSImm12LO()
const {
877 if (evaluateConstantExpr(
getExpr(), Imm))
878 return isInt<12>(fixImmediateForRV32(Imm, isRV64Expr()));
881 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
884 VK == ELF::R_RISCV_TLSDESC_ADD_LO12);
887 bool isSImm12Lsb00000()
const {
891 bool isSImm10Lsb0000NonZero()
const {
896 bool isSImm16NonZero()
const {
897 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<16>(Imm); });
900 bool isUImm16NonZero()
const {
901 return isUImmPred([](int64_t Imm) {
return isUInt<16>(Imm) &&
Imm != 0; });
904 bool isSImm20LI()
const {
909 if (evaluateConstantExpr(
getExpr(), Imm))
910 return isInt<20>(fixImmediateForRV32(Imm, isRV64Expr()));
913 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
917 bool isSImm8Unsigned()
const {
return isSImm<8>() || isUImm<8>(); }
918 bool isSImm10Unsigned()
const {
return isSImm<10>() || isUImm<10>(); }
920 bool isSImm10PLI_H()
const {
921 return isSImm<10>() || isUImmPred([](int64_t Imm) {
925 bool isSImm10PLI_W()
const {
926 return isSImm<10>() || isUImmPred([](int64_t Imm) {
931 bool isUImm20LUI()
const {
936 if (evaluateConstantExpr(
getExpr(), Imm))
940 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
941 (VK == ELF::R_RISCV_HI20 || VK == ELF::R_RISCV_TPREL_HI20);
944 bool isUImm20AUIPC()
const {
949 if (evaluateConstantExpr(
getExpr(), Imm))
953 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
955 VK == ELF::R_RISCV_TLS_GOT_HI20 || VK == ELF::R_RISCV_TLS_GD_HI20 ||
956 VK == ELF::R_RISCV_TLSDESC_HI20);
959 bool isImmZero()
const {
960 return isUImmPred([](int64_t Imm) {
return 0 ==
Imm; });
963 bool isImmThree()
const {
964 return isUImmPred([](int64_t Imm) {
return 3 ==
Imm; });
967 bool isImmFour()
const {
968 return isUImmPred([](int64_t Imm) {
return 4 ==
Imm; });
971 bool isImm5Zibi()
const {
973 [](int64_t Imm) {
return (Imm != 0 &&
isUInt<5>(Imm)) ||
Imm == -1; });
976 bool isSImm5Plus1()
const {
981 bool isSImm18()
const {
982 return isSImmPred([](int64_t Imm) {
return isInt<18>(Imm); });
985 bool isSImm18Lsb0()
const {
989 bool isSImm19Lsb00()
const {
993 bool isSImm20Lsb000()
const {
997 bool isSImm32Lsb0()
const {
1002 SMLoc getStartLoc()
const override {
return StartLoc; }
1004 SMLoc getEndLoc()
const override {
return EndLoc; }
1007 bool isRV64Expr()
const {
1008 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1012 MCRegister
getReg()
const override {
1013 assert(Kind == KindTy::Register &&
"Invalid type access!");
1017 StringRef getSysReg()
const {
1018 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
1019 return StringRef(SysReg.Data, SysReg.Length);
1022 const MCExpr *
getExpr()
const {
1023 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1027 uint64_t getFPConst()
const {
1028 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1033 assert(Kind == KindTy::Token &&
"Invalid type access!");
1037 unsigned getVType()
const {
1038 assert(Kind == KindTy::VType &&
"Invalid type access!");
1043 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1047 unsigned getFence()
const {
1048 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1052 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1061 case KindTy::Expression:
1064 OS <<
' ' << (Expr.IsRV64 ?
"rv64" :
"rv32") <<
'>';
1066 case KindTy::FPImmediate:
1067 OS <<
"<fpimm: " << FPImm.Val <<
">";
1069 case KindTy::Register:
1071 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1076 case KindTy::SystemRegister:
1077 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1086 roundingModeToString(getFRM());
1094 case KindTy::RegList:
1099 case KindTy::StackAdj:
1100 OS <<
"<stackadj: ";
1104 case KindTy::RegReg:
1105 OS <<
"<RegReg: BaseReg " <<
RegName(
RegReg.BaseReg) <<
" OffsetReg "
1111 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1112 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1119 static std::unique_ptr<RISCVOperand>
1120 createReg(MCRegister
Reg, SMLoc S, SMLoc
E,
bool IsGPRAsFPR =
false) {
1121 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1123 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1129 static std::unique_ptr<RISCVOperand> createExpr(
const MCExpr *Val, SMLoc S,
1130 SMLoc
E,
bool IsRV64) {
1131 auto Op = std::make_unique<RISCVOperand>(KindTy::Expression);
1132 Op->Expr.Expr = Val;
1133 Op->Expr.IsRV64 = IsRV64;
1139 static std::unique_ptr<RISCVOperand> createFPImm(uint64_t Val, SMLoc S) {
1140 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1141 Op->FPImm.Val = Val;
1147 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1148 unsigned Encoding) {
1149 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1150 Op->SysReg.Data = Str.data();
1151 Op->SysReg.Length = Str.size();
1158 static std::unique_ptr<RISCVOperand>
1160 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1167 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val, SMLoc S) {
1168 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1169 Op->Fence.Val = Val;
1175 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI, SMLoc S) {
1176 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1177 Op->VType.Val = VTypeI;
1183 static std::unique_ptr<RISCVOperand> createRegList(
unsigned RlistEncode,
1185 auto Op = std::make_unique<RISCVOperand>(KindTy::RegList);
1191 static std::unique_ptr<RISCVOperand>
1192 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {
1193 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1195 Op->RegReg.OffsetReg = OffsetReg;
1201 static std::unique_ptr<RISCVOperand> createStackAdj(
unsigned StackAdj, SMLoc S) {
1202 auto Op = std::make_unique<RISCVOperand>(KindTy::StackAdj);
1203 Op->StackAdj.Val = StackAdj;
1208 static void addExpr(MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1209 assert(Expr &&
"Expr shouldn't be null!");
1211 bool IsConstant = evaluateConstantExpr(Expr, Imm);
1221 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1222 assert(
N == 1 &&
"Invalid number of operands!");
1226 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1227 assert(
N == 1 &&
"Invalid number of operands!");
1228 addExpr(Inst,
getExpr(), isRV64Expr());
1231 void addSImm8UnsignedOperands(MCInst &Inst,
unsigned N)
const {
1232 assert(
N == 1 &&
"Invalid number of operands!");
1239 void addSImm10UnsignedOperands(MCInst &Inst,
unsigned N)
const {
1240 assert(
N == 1 &&
"Invalid number of operands!");
1247 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
1248 assert(
N == 1 &&
"Invalid number of operands!");
1250 addExpr(Inst,
getExpr(), isRV64Expr());
1255 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1259 void addFenceArgOperands(MCInst &Inst,
unsigned N)
const {
1260 assert(
N == 1 &&
"Invalid number of operands!");
1264 void addCSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
1265 assert(
N == 1 &&
"Invalid number of operands!");
1272 void addVTypeIOperands(MCInst &Inst,
unsigned N)
const {
1273 assert(
N == 1 &&
"Invalid number of operands!");
1275 if (Kind == KindTy::Expression) {
1276 [[maybe_unused]]
bool IsConstantImm =
1277 evaluateConstantExpr(
getExpr(), Imm);
1278 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1285 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1286 assert(
N == 1 &&
"Invalid number of operands!");
1290 void addRegRegOperands(MCInst &Inst,
unsigned N)
const {
1291 assert(
N == 2 &&
"Invalid number of operands!");
1296 void addStackAdjOperands(MCInst &Inst,
unsigned N)
const {
1297 assert(
N == 1 &&
"Invalid number of operands!");
1301 void addFRMArgOperands(MCInst &Inst,
unsigned N)
const {
1302 assert(
N == 1 &&
"Invalid number of operands!");
1308#define GET_REGISTER_MATCHER
1309#define GET_SUBTARGET_FEATURE_NAME
1310#define GET_MATCHER_IMPLEMENTATION
1311#define GET_MNEMONIC_SPELL_CHECKER
1312#include "RISCVGenAsmMatcher.inc"
1315 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1316 return Reg - RISCV::F0_D + RISCV::F0_H;
1320 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1321 return Reg - RISCV::F0_D + RISCV::F0_F;
1325 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1326 return Reg - RISCV::F0_D + RISCV::F0_Q;
1331 unsigned RegClassID;
1332 if (Kind == MCK_VRM2)
1333 RegClassID = RISCV::VRM2RegClassID;
1334 else if (Kind == MCK_VRM4)
1335 RegClassID = RISCV::VRM4RegClassID;
1336 else if (Kind == MCK_VRM8)
1337 RegClassID = RISCV::VRM8RegClassID;
1341 &RISCVMCRegisterClasses[RegClassID]);
1345 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1346 return Reg - RISCV::F0_D + RISCV::F0_Q2;
1351 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1353 return Match_InvalidOperand;
1355 MCRegister
Reg =
Op.getReg();
1357 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg);
1359 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg);
1360 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg);
1362 if (IsRegFPR64 && Kind == MCK_FPR256) {
1364 return Match_Success;
1366 if (IsRegFPR64 && Kind == MCK_FPR128) {
1368 return Match_Success;
1372 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1373 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1375 return Match_Success;
1379 if (IsRegFPR64 && Kind == MCK_FPR16) {
1381 return Match_Success;
1383 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1384 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_H;
1385 return Match_Success;
1387 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1388 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_W;
1389 return Match_Success;
1396 if (RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg) &&
1397 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1399 return Match_Success;
1403 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1406 return Match_InvalidOperand;
1407 return Match_Success;
1409 return Match_InvalidOperand;
1412bool RISCVAsmParser::generateImmOutOfRangeError(
1413 SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
1414 const Twine &Msg =
"immediate must be an integer in the range") {
1415 return Error(ErrorLoc, Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]");
1418bool RISCVAsmParser::generateImmOutOfRangeError(
1420 const Twine &Msg =
"immediate must be an integer in the range") {
1421 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1422 return generateImmOutOfRangeError(ErrorLoc,
Lower,
Upper, Msg);
1425bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1428 uint64_t &ErrorInfo,
1429 bool MatchingInlineAsm) {
1431 FeatureBitset MissingFeatures;
1433 auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
1439 if (validateInstruction(Inst, Operands))
1441 return processInstruction(Inst, IDLoc, Operands, Out);
1442 case Match_MissingFeature: {
1443 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1444 bool FirstFeature =
true;
1445 std::string Msg =
"instruction requires the following:";
1446 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1447 if (MissingFeatures[i]) {
1448 Msg += FirstFeature ?
" " :
", ";
1450 FirstFeature =
false;
1453 return Error(IDLoc, Msg);
1455 case Match_MnemonicFail: {
1456 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1457 std::string Suggestion = RISCVMnemonicSpellCheck(
1458 ((RISCVOperand &)*Operands[0]).
getToken(), FBS, 0);
1459 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1461 case Match_InvalidOperand: {
1462 SMLoc ErrorLoc = IDLoc;
1463 if (ErrorInfo != ~0ULL) {
1464 if (ErrorInfo >= Operands.
size())
1465 return Error(ErrorLoc,
"too few operands for instruction");
1467 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1468 if (ErrorLoc == SMLoc())
1471 return Error(ErrorLoc,
"invalid operand for instruction");
1478 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1479 SMLoc ErrorLoc = IDLoc;
1480 if (ErrorInfo != ~0ULL && ErrorInfo >= Operands.
size())
1481 return Error(ErrorLoc,
"too few operands for instruction");
1487 case Match_InvalidImmXLenLI:
1489 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1490 return Error(ErrorLoc,
"operand must be a constant 64-bit integer");
1492 return generateImmOutOfRangeError(Operands, ErrorInfo,
1493 std::numeric_limits<int32_t>::min(),
1494 std::numeric_limits<uint32_t>::max());
1495 case Match_InvalidImmXLenLI_Restricted:
1497 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1498 return Error(ErrorLoc,
"operand either must be a constant 64-bit integer "
1499 "or a bare symbol name");
1501 return generateImmOutOfRangeError(
1502 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1503 std::numeric_limits<uint32_t>::max(),
1504 "operand either must be a bare symbol name or an immediate integer in "
1506 case Match_InvalidUImmLog2XLen:
1508 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1509 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1510 case Match_InvalidUImmLog2XLenNonZero:
1512 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
1513 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1514 case Match_InvalidUImm1:
1515 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
1516 case Match_InvalidUImm2:
1517 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
1518 case Match_InvalidUImm2Lsb0:
1519 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 2,
1520 "immediate must be one of");
1521 case Match_InvalidUImm3:
1522 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
1523 case Match_InvalidUImm4:
1524 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
1525 case Match_InvalidUImm4Plus1:
1526 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 4));
1527 case Match_InvalidUImm5:
1528 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1529 case Match_InvalidUImm5NonZero:
1530 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1531 case Match_InvalidUImm5GT3:
1532 return generateImmOutOfRangeError(Operands, ErrorInfo, 4, (1 << 5) - 1);
1533 case Match_InvalidUImm5Plus1:
1534 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));
1535 case Match_InvalidUImm5GE6Plus1:
1536 return generateImmOutOfRangeError(Operands, ErrorInfo, 6, (1 << 5));
1537 case Match_InvalidUImm5Slist: {
1538 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1539 return Error(ErrorLoc,
1540 "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31");
1542 case Match_InvalidUImm6:
1543 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1544 case Match_InvalidUImm6Plus1:
1545 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6));
1546 case Match_InvalidUImm7:
1547 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
1548 case Match_InvalidUImm8:
1549 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
1550 case Match_InvalidUImm8GE32:
1551 return generateImmOutOfRangeError(Operands, ErrorInfo, 32, (1 << 8) - 1);
1552 case Match_InvalidSImm5:
1553 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4),
1555 case Match_InvalidSImm5NonZero:
1556 return generateImmOutOfRangeError(
1557 Operands, ErrorInfo, -(1 << 4), (1 << 4) - 1,
1558 "immediate must be non-zero in the range");
1559 case Match_InvalidSImm6:
1560 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
1562 case Match_InvalidSImm6NonZero:
1563 return generateImmOutOfRangeError(
1564 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
1565 "immediate must be non-zero in the range");
1566 case Match_InvalidCLUIImm:
1567 return generateImmOutOfRangeError(
1568 Operands, ErrorInfo, 1, (1 << 5) - 1,
1569 "immediate must be in [0xfffe0, 0xfffff] or");
1570 case Match_InvalidUImm5Lsb0:
1571 return generateImmOutOfRangeError(
1572 Operands, ErrorInfo, 0, (1 << 5) - 2,
1573 "immediate must be a multiple of 2 bytes in the range");
1574 case Match_InvalidUImm6Lsb0:
1575 return generateImmOutOfRangeError(
1576 Operands, ErrorInfo, 0, (1 << 6) - 2,
1577 "immediate must be a multiple of 2 bytes in the range");
1578 case Match_InvalidUImm7Lsb00:
1579 return generateImmOutOfRangeError(
1580 Operands, ErrorInfo, 0, (1 << 7) - 4,
1581 "immediate must be a multiple of 4 bytes in the range");
1582 case Match_InvalidUImm8Lsb00:
1583 return generateImmOutOfRangeError(
1584 Operands, ErrorInfo, 0, (1 << 8) - 4,
1585 "immediate must be a multiple of 4 bytes in the range");
1586 case Match_InvalidUImm8Lsb000:
1587 return generateImmOutOfRangeError(
1588 Operands, ErrorInfo, 0, (1 << 8) - 8,
1589 "immediate must be a multiple of 8 bytes in the range");
1590 case Match_InvalidUImm9:
1591 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 9) - 1,
1592 "immediate offset must be in the range");
1593 case Match_InvalidBareSImm9Lsb0:
1594 return generateImmOutOfRangeError(
1595 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
1596 "immediate must be a multiple of 2 bytes in the range");
1597 case Match_InvalidUImm9Lsb000:
1598 return generateImmOutOfRangeError(
1599 Operands, ErrorInfo, 0, (1 << 9) - 8,
1600 "immediate must be a multiple of 8 bytes in the range");
1601 case Match_InvalidSImm8Unsigned:
1602 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
1604 case Match_InvalidSImm10:
1605 case Match_InvalidSImm10PLI_H:
1606 case Match_InvalidSImm10PLI_W:
1607 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
1609 case Match_InvalidSImm10Unsigned:
1610 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
1612 case Match_InvalidUImm10Lsb00NonZero:
1613 return generateImmOutOfRangeError(
1614 Operands, ErrorInfo, 4, (1 << 10) - 4,
1615 "immediate must be a multiple of 4 bytes in the range");
1616 case Match_InvalidSImm10Lsb0000NonZero:
1617 return generateImmOutOfRangeError(
1618 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
1619 "immediate must be a multiple of 16 bytes and non-zero in the range");
1620 case Match_InvalidSImm11:
1621 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 10),
1623 case Match_InvalidBareSImm11Lsb0:
1624 return generateImmOutOfRangeError(
1625 Operands, ErrorInfo, -(1 << 10), (1 << 10) - 2,
1626 "immediate must be a multiple of 2 bytes in the range");
1627 case Match_InvalidUImm10:
1628 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 10) - 1);
1629 case Match_InvalidUImm11:
1630 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
1631 case Match_InvalidUImm14Lsb00:
1632 return generateImmOutOfRangeError(
1633 Operands, ErrorInfo, 0, (1 << 14) - 4,
1634 "immediate must be a multiple of 4 bytes in the range");
1635 case Match_InvalidUImm16NonZero:
1636 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16) - 1);
1637 case Match_InvalidSImm12:
1638 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11),
1640 case Match_InvalidSImm12LO:
1641 return generateImmOutOfRangeError(
1642 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
1643 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo specifier or an "
1644 "integer in the range");
1645 case Match_InvalidBareSImm12Lsb0:
1646 return generateImmOutOfRangeError(
1647 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
1648 "immediate must be a multiple of 2 bytes in the range");
1649 case Match_InvalidSImm12Lsb00000:
1650 return generateImmOutOfRangeError(
1651 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 32,
1652 "immediate must be a multiple of 32 bytes in the range");
1653 case Match_InvalidBareSImm13Lsb0:
1654 return generateImmOutOfRangeError(
1655 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
1656 "immediate must be a multiple of 2 bytes in the range");
1657 case Match_InvalidSImm16:
1658 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 15),
1660 case Match_InvalidSImm16NonZero:
1661 return generateImmOutOfRangeError(
1662 Operands, ErrorInfo, -(1 << 15), (1 << 15) - 1,
1663 "immediate must be non-zero in the range");
1664 case Match_InvalidSImm20LI:
1665 return generateImmOutOfRangeError(
1666 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 1,
1667 "operand must be a symbol with a %qc.abs20 specifier or an integer "
1669 case Match_InvalidUImm20LUI:
1670 return generateImmOutOfRangeError(
1671 Operands, ErrorInfo, 0, (1 << 20) - 1,
1672 "operand must be a symbol with "
1673 "%hi/%tprel_hi specifier or an integer in "
1675 case Match_InvalidUImm20:
1676 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1);
1677 case Match_InvalidUImm20AUIPC:
1678 return generateImmOutOfRangeError(
1679 Operands, ErrorInfo, 0, (1 << 20) - 1,
1680 "operand must be a symbol with a "
1681 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
1683 "an integer in the range");
1684 case Match_InvalidBareSImm21Lsb0:
1685 return generateImmOutOfRangeError(
1686 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
1687 "immediate must be a multiple of 2 bytes in the range");
1688 case Match_InvalidCSRSystemRegister: {
1689 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1,
1690 "operand must be a valid system register "
1691 "name or an integer in the range");
1693 case Match_InvalidImm5Zibi:
1694 return generateImmOutOfRangeError(
1695 Operands, ErrorInfo, -1, (1 << 5) - 1,
1696 "immediate must be non-zero in the range");
1697 case Match_InvalidVTypeI: {
1698 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1699 return generateVTypeError(ErrorLoc);
1701 case Match_InvalidSImm5Plus1: {
1702 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1,
1704 "immediate must be in the range");
1706 case Match_InvalidSImm18:
1707 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 17),
1709 case Match_InvalidSImm18Lsb0:
1710 return generateImmOutOfRangeError(
1711 Operands, ErrorInfo, -(1 << 17), (1 << 17) - 2,
1712 "immediate must be a multiple of 2 bytes in the range");
1713 case Match_InvalidSImm19Lsb00:
1714 return generateImmOutOfRangeError(
1715 Operands, ErrorInfo, -(1 << 18), (1 << 18) - 4,
1716 "immediate must be a multiple of 4 bytes in the range");
1717 case Match_InvalidSImm20Lsb000:
1718 return generateImmOutOfRangeError(
1719 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 8,
1720 "immediate must be a multiple of 8 bytes in the range");
1721 case Match_InvalidSImm26:
1722 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 25),
1725 case Match_InvalidBareSymbolQC_E_LI:
1728 case Match_InvalidBareSImm32:
1729 return generateImmOutOfRangeError(Operands, ErrorInfo,
1730 std::numeric_limits<int32_t>::min(),
1731 std::numeric_limits<uint32_t>::max());
1732 case Match_InvalidBareSImm32Lsb0:
1733 return generateImmOutOfRangeError(
1734 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1735 std::numeric_limits<int32_t>::max() - 1,
1736 "operand must be a multiple of 2 bytes in the range");
1737 case Match_InvalidRnumArg: {
1738 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10);
1740 case Match_InvalidStackAdj: {
1741 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1744 "stack adjustment is invalid for this instruction and register list");
1748 if (
const char *MatchDiag = getMatchKindDiag((RISCVMatchResultTy)Result)) {
1749 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1750 return Error(ErrorLoc, MatchDiag);
1760MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name)
const {
1769 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1770 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1771 static_assert(RISCV::F0_D < RISCV::F0_Q,
"FPR matching must be updated");
1774 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1779bool RISCVAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1781 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1782 return Error(StartLoc,
"invalid register name");
1786ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1788 const AsmToken &Tok = getParser().getTok();
1791 StringRef
Name = getLexer().getTok().getIdentifier();
1801ParseStatus RISCVAsmParser::parseRegister(
OperandVector &Operands,
1803 SMLoc FirstS = getLoc();
1804 bool HadParens =
false;
1811 size_t ReadCount = getLexer().peekTokens(Buf);
1814 LParen = getParser().getTok();
1819 switch (getLexer().getKind()) {
1822 getLexer().UnLex(LParen);
1825 StringRef
Name = getLexer().getTok().getIdentifier();
1830 getLexer().UnLex(LParen);
1834 Operands.
push_back(RISCVOperand::createToken(
"(", FirstS));
1836 SMLoc
E = getTok().getEndLoc();
1843 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
1849ParseStatus RISCVAsmParser::parseInsnDirectiveOpcode(
OperandVector &Operands) {
1854 switch (getLexer().getKind()) {
1864 if (getParser().parseExpression(Res,
E))
1869 int64_t
Imm =
CE->getValue();
1871 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1880 if (getParser().parseIdentifier(Identifier))
1883 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1886 "Unexpected opcode");
1889 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1899 return generateImmOutOfRangeError(
1901 "opcode must be a valid opcode name or an immediate in the range");
1904ParseStatus RISCVAsmParser::parseInsnCDirectiveOpcode(
OperandVector &Operands) {
1909 switch (getLexer().getKind()) {
1919 if (getParser().parseExpression(Res,
E))
1924 int64_t
Imm =
CE->getValue();
1925 if (Imm >= 0 && Imm <= 2) {
1926 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1935 if (getParser().parseIdentifier(Identifier))
1939 if (Identifier ==
"C0")
1941 else if (Identifier ==
"C1")
1943 else if (Identifier ==
"C2")
1950 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1959 return generateImmOutOfRangeError(
1961 "opcode must be a valid opcode name or an immediate in the range");
1964ParseStatus RISCVAsmParser::parseCSRSystemRegister(
OperandVector &Operands) {
1968 auto SysRegFromConstantInt = [
this](
const MCExpr *
E, SMLoc S) {
1970 int64_t
Imm =
CE->getValue();
1972 auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
1976 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
1979 return RISCVOperand::createSysReg(
Reg.Name, S, Imm);
1983 return RISCVOperand::createSysReg(
"", S, Imm);
1986 return std::unique_ptr<RISCVOperand>();
1989 switch (getLexer().getKind()) {
1999 if (getParser().parseExpression(Res))
2002 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
2007 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2011 if (getParser().parseIdentifier(Identifier))
2014 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
2017 if (SysReg->IsDeprecatedName) {
2019 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
2021 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2023 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
2029 const auto &FeatureBits = getSTI().getFeatureBits();
2030 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
2032 return SysReg->FeaturesRequired[Feature.Value];
2034 auto ErrorMsg = std::string(
"system register '") + SysReg->Name +
"' ";
2035 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
2036 ErrorMsg +=
"is RV32 only";
2038 ErrorMsg +=
" and ";
2042 "requires '" + std::string(Feature->Key) +
"' to be enabled";
2045 return Error(S, ErrorMsg);
2048 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
2063 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2064 "operand must be a valid system register "
2065 "name or an integer in the range");
2069 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2076ParseStatus RISCVAsmParser::parseFPImm(
OperandVector &Operands) {
2081 StringRef
Identifier = getTok().getIdentifier();
2082 if (
Identifier.compare_insensitive(
"inf") == 0) {
2085 getTok().getEndLoc(), isRV64()));
2086 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2089 getTok().getEndLoc(), isRV64()));
2090 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2093 getTok().getEndLoc(), isRV64()));
2095 return TokError(
"invalid floating point literal");
2106 const AsmToken &Tok = getTok();
2108 return TokError(
"invalid floating point immediate");
2111 APFloat RealVal(APFloat::IEEEdouble());
2113 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2115 return TokError(
"invalid floating point representation");
2118 RealVal.changeSign();
2120 Operands.
push_back(RISCVOperand::createFPImm(
2121 RealVal.bitcastToAPInt().getZExtValue(), S));
2128ParseStatus RISCVAsmParser::parseExpression(
OperandVector &Operands) {
2133 switch (getLexer().getKind()) {
2145 if (getParser().parseExpression(Res,
E))
2149 return parseOperandWithSpecifier(Operands);
2152 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2156ParseStatus RISCVAsmParser::parseOperandWithSpecifier(
OperandVector &Operands) {
2162 const MCExpr *Expr =
nullptr;
2163 bool Failed = parseExprWithSpecifier(Expr,
E);
2165 Operands.
push_back(RISCVOperand::createExpr(Expr, S,
E, isRV64()));
2169bool RISCVAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
2170 SMLoc Loc = getLoc();
2172 return TokError(
"expected '%' relocation specifier");
2173 StringRef
Identifier = getParser().getTok().getIdentifier();
2176 return TokError(
"invalid relocation specifier");
2182 const MCExpr *SubExpr;
2183 if (getParser().parseParenExpression(SubExpr,
E))
2190bool RISCVAsmParser::parseDataExpr(
const MCExpr *&Res) {
2193 return parseExprWithSpecifier(Res,
E);
2194 return getParser().parseExpression(Res);
2197ParseStatus RISCVAsmParser::parseBareSymbol(
OperandVector &Operands) {
2205 AsmToken Tok = getLexer().getTok();
2207 if (getParser().parseIdentifier(Identifier))
2217 getLexer().UnLex(Tok);
2225 switch (getLexer().getKind()) {
2227 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2240 if (getParser().parseExpression(Expr,
E))
2243 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2247ParseStatus RISCVAsmParser::parseCallSymbol(
OperandVector &Operands) {
2253 std::string
Identifier(getTok().getIdentifier());
2259 SMLoc Loc = getLoc();
2260 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2261 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2275 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2279ParseStatus RISCVAsmParser::parsePseudoJumpSymbol(
OperandVector &Operands) {
2284 if (getParser().parseExpression(Res,
E))
2287 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef)
2288 return Error(S,
"operand must be a valid jump target");
2291 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2295ParseStatus RISCVAsmParser::parseJALOffset(
OperandVector &Operands) {
2309 return parseExpression(Operands);
2312bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2313 unsigned &Sew,
unsigned &Lmul,
2314 bool &Fractional,
bool &TailAgnostic,
2315 bool &MaskAgnostic,
bool &AltFmt) {
2320 if (State < VTypeState::SeenSew &&
Identifier.consume_front(
"e")) {
2322 if (Identifier ==
"16alt") {
2325 }
else if (Identifier ==
"8alt") {
2335 State = VTypeState::SeenSew;
2339 if (State < VTypeState::SeenLmul &&
Identifier.consume_front(
"m")) {
2342 if (Identifier ==
"a" || Identifier ==
"u") {
2344 State = VTypeState::SeenMaskPolicy;
2355 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2356 unsigned MinLMUL = ELEN / 8;
2359 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2360 Twine(MinLMUL) +
" is reserved");
2363 State = VTypeState::SeenLmul;
2367 if (State < VTypeState::SeenTailPolicy &&
Identifier.starts_with(
"t")) {
2368 if (Identifier ==
"ta")
2369 TailAgnostic =
true;
2370 else if (Identifier ==
"tu")
2371 TailAgnostic =
false;
2375 State = VTypeState::SeenTailPolicy;
2379 if (State < VTypeState::SeenMaskPolicy &&
Identifier.starts_with(
"m")) {
2380 if (Identifier ==
"ma")
2381 MaskAgnostic =
true;
2382 else if (Identifier ==
"mu")
2383 MaskAgnostic =
false;
2387 State = VTypeState::SeenMaskPolicy;
2394ParseStatus RISCVAsmParser::parseVTypeI(
OperandVector &Operands) {
2400 bool Fractional =
false;
2401 bool TailAgnostic =
false;
2402 bool MaskAgnostic =
false;
2405 VTypeState State = VTypeState::SeenNothingYet;
2407 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2408 MaskAgnostic, AltFmt)) {
2410 if (State == VTypeState::SeenNothingYet)
2419 State == VTypeState::SeenNothingYet)
2420 return generateVTypeError(S);
2424 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2425 unsigned MaxSEW = ELEN / Lmul;
2427 if (MaxSEW >= 8 && Sew > MaxSEW)
2428 Warning(S,
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2429 " and LMUL == mf" + Twine(Lmul) +
2430 " may not be compatible with all RVV implementations");
2435 Operands.
push_back(RISCVOperand::createVType(VTypeI, S));
2439bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2440 if (STI->
hasFeature(RISCV::FeatureStdExtZvfbfa) ||
2441 STI->
hasFeature(RISCV::FeatureStdExtZvfofp8min) ||
2442 STI->
hasFeature(RISCV::FeatureVendorXSfvfbfexp16e))
2446 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2450 "e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2453ParseStatus RISCVAsmParser::parseXSfmmVType(
OperandVector &Operands) {
2470 if (Identifier !=
"16alt")
2499 Operands.
push_back(RISCVOperand::createVType(
2505 return generateXSfmmVTypeError(S);
2508bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
2509 return Error(ErrorLoc,
"operand must be e[8|16|16alt|32|64],w[1|2|4]");
2512ParseStatus RISCVAsmParser::parseMaskReg(
OperandVector &Operands) {
2516 StringRef
Name = getLexer().getTok().getIdentifier();
2517 if (!
Name.consume_back(
".t"))
2518 return Error(getLoc(),
"expected '.t' suffix");
2523 if (
Reg != RISCV::V0)
2526 SMLoc
E = getTok().getEndLoc();
2532ParseStatus RISCVAsmParser::parseGPRAsFPR64(
OperandVector &Operands) {
2533 if (!isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2536 return parseGPRAsFPR(Operands);
2539ParseStatus RISCVAsmParser::parseGPRAsFPR(
OperandVector &Operands) {
2543 StringRef
Name = getLexer().getTok().getIdentifier();
2549 SMLoc
E = getTok().getEndLoc();
2551 Operands.
push_back(RISCVOperand::createReg(
2552 Reg, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2556ParseStatus RISCVAsmParser::parseGPRPairAsFPR64(
OperandVector &Operands) {
2557 if (isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2563 StringRef
Name = getLexer().getTok().getIdentifier();
2569 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2572 if ((
Reg - RISCV::X0) & 1) {
2575 if (getSTI().hasFeature(RISCV::FeatureStdExtZfinx))
2576 return TokError(
"double precision floating point operands must use even "
2577 "numbered X register");
2582 SMLoc
E = getTok().getEndLoc();
2585 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2587 Reg, RISCV::sub_gpr_even,
2588 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2589 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2593template <
bool IsRV64>
2594ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands) {
2595 return parseGPRPair(Operands, IsRV64);
2598ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands,
2605 if (!IsRV64Inst && isRV64())
2611 StringRef
Name = getLexer().getTok().getIdentifier();
2617 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2620 if ((
Reg - RISCV::X0) & 1)
2621 return TokError(
"register must be even");
2624 SMLoc
E = getTok().getEndLoc();
2627 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2629 Reg, RISCV::sub_gpr_even,
2630 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2631 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E));
2635ParseStatus RISCVAsmParser::parseFRMArg(
OperandVector &Operands) {
2638 "operand must be a valid floating point rounding mode mnemonic");
2640 StringRef Str = getLexer().getTok().getIdentifier();
2645 "operand must be a valid floating point rounding mode mnemonic");
2647 Operands.
push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2652ParseStatus RISCVAsmParser::parseFenceArg(
OperandVector &Operands) {
2653 const AsmToken &Tok = getLexer().getTok();
2659 Operands.
push_back(RISCVOperand::createFenceArg(0, getLoc()));
2673 for (
char c : Str) {
2702 Operands.
push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2708 return TokError(
"operand must be formed of letters selected in-order from "
2712ParseStatus RISCVAsmParser::parseMemOpBaseReg(
OperandVector &Operands) {
2715 Operands.
push_back(RISCVOperand::createToken(
"(", getLoc()));
2717 if (!parseRegister(Operands).isSuccess())
2718 return Error(getLoc(),
"expected register");
2722 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
2727ParseStatus RISCVAsmParser::parseZeroOffsetMemOp(
OperandVector &Operands) {
2746 std::unique_ptr<RISCVOperand> OptionalImmOp;
2753 SMLoc ImmStart = getLoc();
2754 if (getParser().parseIntToken(ImmVal,
2755 "expected '(' or optional integer offset"))
2760 SMLoc ImmEnd = getLoc();
2763 ImmStart, ImmEnd, isRV64());
2767 OptionalImmOp ?
"expected '(' after optional integer offset"
2768 :
"expected '(' or optional integer offset"))
2771 if (!parseRegister(Operands).isSuccess())
2772 return Error(getLoc(),
"expected register");
2778 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2780 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2781 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2786ParseStatus RISCVAsmParser::parseRegReg(
OperandVector &Operands) {
2792 StringRef OffsetRegName = getLexer().getTok().getIdentifier();
2795 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(OffsetReg))
2796 return Error(getLoc(),
"expected GPR register");
2803 return Error(getLoc(),
"expected GPR register");
2805 StringRef BaseRegName = getLexer().getTok().getIdentifier();
2808 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(BaseReg))
2809 return Error(getLoc(),
"expected GPR register");
2815 Operands.
push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));
2827ParseStatus RISCVAsmParser::parseRegList(
OperandVector &Operands,
2828 bool MustIncludeS0) {
2840 return Error(getLoc(),
"invalid register");
2842 StringRef
RegName = getTok().getIdentifier();
2845 return Error(getLoc(),
"invalid register");
2848 UsesXRegs =
RegName[0] ==
'x';
2849 if (
Reg != RISCV::X1)
2850 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2851 }
else if (RegEnd == RISCV::X1) {
2852 if (
Reg != RISCV::X8 || (UsesXRegs != (
RegName[0] ==
'x')))
2853 return Error(getLoc(), Twine(
"register must be '") +
2854 (UsesXRegs ?
"x8" :
"s0") +
"'");
2855 }
else if (RegEnd == RISCV::X9 && UsesXRegs) {
2856 if (
Reg != RISCV::X18 || (
RegName[0] !=
'x'))
2857 return Error(getLoc(),
"register must be 'x18'");
2859 return Error(getLoc(),
"too many register ranges");
2866 SMLoc MinusLoc = getLoc();
2868 if (RegEnd == RISCV::X1)
2869 return Error(MinusLoc, Twine(
"register '") + (UsesXRegs ?
"x1" :
"ra") +
2870 "' cannot start a multiple register range");
2873 return Error(getLoc(),
"invalid register");
2875 StringRef
RegName = getTok().getIdentifier();
2878 return Error(getLoc(),
"invalid register");
2880 if (RegEnd == RISCV::X8) {
2881 if ((
Reg != RISCV::X9 &&
2883 (UsesXRegs != (
RegName[0] ==
'x'))) {
2885 return Error(getLoc(),
"register must be 'x9'");
2886 return Error(getLoc(),
"register must be in the range 's1' to 's11'");
2888 }
else if (RegEnd == RISCV::X18) {
2890 return Error(getLoc(),
2891 "register must be in the range 'x19' to 'x27'");
2904 if (RegEnd == RISCV::X26)
2905 return Error(S,
"invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "
2906 "x18-x26}' is not supported");
2912 return Error(S,
"register list must include 's0' or 'x8'");
2914 Operands.
push_back(RISCVOperand::createRegList(Encode, S));
2919ParseStatus RISCVAsmParser::parseZcmpStackAdj(
OperandVector &Operands,
2920 bool ExpectNegative) {
2929 auto *RegListOp =
static_cast<RISCVOperand *
>(Operands.
back().
get());
2930 if (!RegListOp->isRegList())
2933 unsigned RlistEncode = RegListOp->RegList.Encoding;
2937 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||
2938 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {
2939 int64_t
Lower = StackAdjBase;
2940 int64_t
Upper = StackAdjBase + 48;
2941 if (ExpectNegative) {
2946 return generateImmOutOfRangeError(S,
Lower,
Upper,
2947 "stack adjustment for register list must "
2948 "be a multiple of 16 bytes in the range");
2952 Operands.
push_back(RISCVOperand::createStackAdj(StackAdj, S));
2960bool RISCVAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
2964 MatchOperandParserImpl(Operands, Mnemonic,
true);
2971 if (parseRegister(Operands,
true).isSuccess())
2975 if (parseExpression(Operands).isSuccess()) {
2978 return !parseMemOpBaseReg(Operands).isSuccess();
2983 Error(getLoc(),
"unknown operand");
2987bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &Info,
2988 StringRef Name, SMLoc NameLoc,
2994 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
2998 Operands.
push_back(RISCVOperand::createToken(Name, NameLoc));
3007 if (parseOperand(Operands, Name))
3013 if (parseOperand(Operands, Name))
3017 if (getParser().parseEOL(
"unexpected token")) {
3018 getParser().eatToEndOfStatement();
3024bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
3028 Kind = RE->getSpecifier();
3029 Expr = RE->getSubExpr();
3038bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
3047ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
3048 StringRef IDVal = DirectiveID.
getString();
3050 if (IDVal ==
".option")
3051 return parseDirectiveOption();
3052 if (IDVal ==
".attribute")
3053 return parseDirectiveAttribute();
3054 if (IDVal ==
".insn")
3055 return parseDirectiveInsn(DirectiveID.
getLoc());
3056 if (IDVal ==
".variant_cc")
3057 return parseDirectiveVariantCC();
3062bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
3063 bool FromOptionDirective) {
3066 clearFeatureBits(Feature.Value, Feature.Key);
3073 raw_string_ostream OutputErrMsg(Buffer);
3074 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3075 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
3076 << ErrMsg.getMessage();
3079 return Error(Loc, OutputErrMsg.str());
3081 auto &ISAInfo = *ParseResult;
3084 if (ISAInfo->hasExtension(Feature.Key))
3085 setFeatureBits(Feature.Value, Feature.Key);
3087 if (FromOptionDirective) {
3088 if (ISAInfo->getXLen() == 32 && isRV64())
3089 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3090 else if (ISAInfo->getXLen() == 64 && !isRV64())
3091 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3094 if (ISAInfo->getXLen() == 32)
3095 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
3096 else if (ISAInfo->getXLen() == 64)
3097 setFeatureBits(RISCV::Feature64Bit,
"64bit");
3099 return Error(Loc,
"bad arch string " + Arch);
3101 Result = ISAInfo->toString();
3105bool RISCVAsmParser::parseDirectiveOption() {
3106 MCAsmParser &Parser = getParser();
3108 AsmToken Tok = Parser.
getTok();
3116 if (Option ==
"push") {
3120 getTargetStreamer().emitDirectiveOptionPush();
3125 if (Option ==
"pop") {
3130 getTargetStreamer().emitDirectiveOptionPop();
3131 if (popFeatureBits())
3132 return Error(StartLoc,
".option pop with no .option push");
3137 if (Option ==
"arch") {
3145 Type = RISCVOptionArchArgType::Plus;
3147 Type = RISCVOptionArchArgType::Minus;
3148 else if (!
Args.empty())
3150 "unexpected token, expected + or -");
3152 Type = RISCVOptionArchArgType::Full;
3156 "unexpected token, expected identifier");
3162 if (
Type == RISCVOptionArchArgType::Full) {
3164 if (resetToArch(Arch, Loc, Result,
true))
3173 Loc,
"extension version number parsing not currently implemented");
3176 if (!enableExperimentalExtension() &&
3178 return Error(Loc,
"unexpected experimental extensions");
3180 if (Ext == std::end(
RISCVFeatureKV) || StringRef(Ext->Key) != Feature)
3181 return Error(Loc,
"unknown extension feature");
3185 if (
Type == RISCVOptionArchArgType::Plus) {
3188 setFeatureBits(Ext->Value, Ext->Key);
3191 copySTI().setFeatureBits(OldFeatureBits);
3192 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3195 raw_string_ostream OutputErrMsg(Buffer);
3196 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3197 OutputErrMsg << ErrMsg.getMessage();
3200 return Error(Loc, OutputErrMsg.str());
3203 assert(
Type == RISCVOptionArchArgType::Minus);
3208 if (getSTI().hasFeature(Feature.Value) &&
3209 Feature.Implies.test(Ext->Value))
3210 return Error(Loc, Twine(
"can't disable ") + Ext->Key +
3211 " extension; " + Feature.Key +
3212 " extension requires " + Ext->Key +
3216 clearFeatureBits(Ext->Value, Ext->Key);
3223 getTargetStreamer().emitDirectiveOptionArch(Args);
3227 if (Option ==
"exact") {
3231 getTargetStreamer().emitDirectiveOptionExact();
3232 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3233 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3237 if (Option ==
"noexact") {
3241 getTargetStreamer().emitDirectiveOptionNoExact();
3242 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3243 setFeatureBits(RISCV::FeatureRelax,
"relax");
3247 if (Option ==
"rvc") {
3251 getTargetStreamer().emitDirectiveOptionRVC();
3252 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3256 if (Option ==
"norvc") {
3260 getTargetStreamer().emitDirectiveOptionNoRVC();
3261 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3262 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3266 if (Option ==
"pic") {
3270 getTargetStreamer().emitDirectiveOptionPIC();
3271 ParserOptions.IsPicEnabled =
true;
3275 if (Option ==
"nopic") {
3279 getTargetStreamer().emitDirectiveOptionNoPIC();
3280 ParserOptions.IsPicEnabled =
false;
3284 if (Option ==
"relax") {
3288 getTargetStreamer().emitDirectiveOptionRelax();
3289 setFeatureBits(RISCV::FeatureRelax,
"relax");
3293 if (Option ==
"norelax") {
3297 getTargetStreamer().emitDirectiveOptionNoRelax();
3298 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3304 "unknown option, expected 'push', 'pop', "
3305 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3306 "'exact', or 'noexact'");
3314bool RISCVAsmParser::parseDirectiveAttribute() {
3315 MCAsmParser &Parser = getParser();
3321 std::optional<unsigned> Ret =
3324 return Error(TagLoc,
"attribute name not recognised: " + Name);
3328 const MCExpr *AttrExpr;
3335 if (check(!CE, TagLoc,
"expected numeric constant"))
3338 Tag =
CE->getValue();
3344 StringRef StringValue;
3345 int64_t IntegerValue = 0;
3346 bool IsIntegerValue =
true;
3351 IsIntegerValue =
false;
3354 if (IsIntegerValue) {
3355 const MCExpr *ValueExpr;
3361 return Error(ValueExprLoc,
"expected numeric constant");
3362 IntegerValue =
CE->getValue();
3375 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3377 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3380 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3384 getTargetStreamer().emitTextAttribute(
Tag, Result);
3392 .
Cases({
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s"},
true)
3393 .Cases({
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj"},
3395 .
Cases({
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es"},
3404bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3405 MCAsmParser &Parser = getParser();
3412 std::optional<int64_t>
Length;
3422 return Error(ErrorLoc,
3423 "instruction lengths must be a non-zero multiple of two");
3427 return Error(ErrorLoc,
3428 "instruction lengths over 64 bits are not supported");
3434 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3439 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3440 return Error(ErrorLoc,
3441 "instruction length does not match the encoding");
3444 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3447 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3450 if (!getSTI().hasFeature(RISCV::FeatureStdExtZca) &&
3451 (EncodingDerivedLength == 2))
3452 return Error(ErrorLoc,
"compressed instructions are not allowed");
3454 if (getParser().parseEOL(
"invalid operand for instruction")) {
3455 getParser().eatToEndOfStatement();
3463 Opcode = RISCV::Insn16;
3466 Opcode = RISCV::Insn32;
3469 Opcode = RISCV::Insn48;
3472 Opcode = RISCV::Insn64;
3478 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3480 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3485 return Error(ErrorLoc,
"invalid instruction format");
3487 std::string FormatName = (
".insn_" +
Format).str();
3489 ParseInstructionInfo
Info;
3492 if (parseInstruction(Info, FormatName, L, Operands))
3497 return matchAndEmitInstruction(L, Opcode, Operands, Parser.
getStreamer(),
3504bool RISCVAsmParser::parseDirectiveVariantCC() {
3506 if (getParser().parseIdentifier(Name))
3507 return TokError(
"expected symbol name");
3510 getTargetStreamer().emitDirectiveVariantCC(
3515void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3518 const MCSubtargetInfo &STI = getSTI();
3519 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3522 ++RISCVNumInstrsCompressed;
3526void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3531 for (MCInst &Inst : Seq) {
3532 emitToStreamer(Out, Inst);
3536void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3537 const MCExpr *Symbol,
3539 unsigned SecondOpcode, SMLoc IDLoc,
3551 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3556 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3559 .addExpr(RefToLinkTmpLabel));
3562void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3576void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3586 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3587 emitAuipcInstPair(DestReg, DestReg, Symbol,
RISCV::S_GOT_HI, SecondOpcode,
3591void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3600 if (ParserOptions.IsPicEnabled)
3601 emitLoadGlobalAddress(Inst, IDLoc, Out);
3603 emitLoadLocalAddress(Inst, IDLoc, Out);
3606void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3616 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3617 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3618 SecondOpcode, IDLoc, Out);
3621void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3631 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3632 RISCV::ADDI, IDLoc, Out);
3635void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3636 SMLoc IDLoc, MCStreamer &Out,
3645 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3647 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3651 if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].
contains(TmpReg)) {
3652 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3653 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3661void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3662 int64_t Width, SMLoc IDLoc,
3671 const MCOperand &DestReg = Inst.
getOperand(0);
3672 const MCOperand &SourceReg = Inst.
getOperand(1);
3674 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3675 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3677 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3679 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3684 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3690void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
3697 emitToStreamer(Out, MCInstBuilder(Opcode)
3701 .addReg(MCRegister())
3703 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
3714 "The destination register should not be V0.");
3715 emitToStreamer(Out, MCInstBuilder(Opcode)
3721 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
3733 "The destination register should be V0.");
3735 "The temporary vector register should not be V0.");
3736 emitToStreamer(Out, MCInstBuilder(Opcode)
3740 .addReg(MCRegister())
3742 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3754 "The temporary vector register should not be V0.");
3755 emitToStreamer(Out, MCInstBuilder(Opcode)
3759 .addReg(MCRegister())
3761 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3766 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3771 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
3779bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
3781 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3784 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
3785 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3786 "%tprel_add specifier");
3792bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
3794 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
3797 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
3798 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
3799 "%tlsdesc_call specifier");
3805std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3806 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
3809std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3810 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3814std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3815 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3823 case RISCV::VLOXSEG2EI8_V:
3824 case RISCV::VLOXSEG2EI16_V:
3825 case RISCV::VLOXSEG2EI32_V:
3826 case RISCV::VLOXSEG2EI64_V:
3827 case RISCV::VLUXSEG2EI8_V:
3828 case RISCV::VLUXSEG2EI16_V:
3829 case RISCV::VLUXSEG2EI32_V:
3830 case RISCV::VLUXSEG2EI64_V:
3832 case RISCV::VLOXSEG3EI8_V:
3833 case RISCV::VLOXSEG3EI16_V:
3834 case RISCV::VLOXSEG3EI32_V:
3835 case RISCV::VLOXSEG3EI64_V:
3836 case RISCV::VLUXSEG3EI8_V:
3837 case RISCV::VLUXSEG3EI16_V:
3838 case RISCV::VLUXSEG3EI32_V:
3839 case RISCV::VLUXSEG3EI64_V:
3841 case RISCV::VLOXSEG4EI8_V:
3842 case RISCV::VLOXSEG4EI16_V:
3843 case RISCV::VLOXSEG4EI32_V:
3844 case RISCV::VLOXSEG4EI64_V:
3845 case RISCV::VLUXSEG4EI8_V:
3846 case RISCV::VLUXSEG4EI16_V:
3847 case RISCV::VLUXSEG4EI32_V:
3848 case RISCV::VLUXSEG4EI64_V:
3850 case RISCV::VLOXSEG5EI8_V:
3851 case RISCV::VLOXSEG5EI16_V:
3852 case RISCV::VLOXSEG5EI32_V:
3853 case RISCV::VLOXSEG5EI64_V:
3854 case RISCV::VLUXSEG5EI8_V:
3855 case RISCV::VLUXSEG5EI16_V:
3856 case RISCV::VLUXSEG5EI32_V:
3857 case RISCV::VLUXSEG5EI64_V:
3859 case RISCV::VLOXSEG6EI8_V:
3860 case RISCV::VLOXSEG6EI16_V:
3861 case RISCV::VLOXSEG6EI32_V:
3862 case RISCV::VLOXSEG6EI64_V:
3863 case RISCV::VLUXSEG6EI8_V:
3864 case RISCV::VLUXSEG6EI16_V:
3865 case RISCV::VLUXSEG6EI32_V:
3866 case RISCV::VLUXSEG6EI64_V:
3868 case RISCV::VLOXSEG7EI8_V:
3869 case RISCV::VLOXSEG7EI16_V:
3870 case RISCV::VLOXSEG7EI32_V:
3871 case RISCV::VLOXSEG7EI64_V:
3872 case RISCV::VLUXSEG7EI8_V:
3873 case RISCV::VLUXSEG7EI16_V:
3874 case RISCV::VLUXSEG7EI32_V:
3875 case RISCV::VLUXSEG7EI64_V:
3877 case RISCV::VLOXSEG8EI8_V:
3878 case RISCV::VLOXSEG8EI16_V:
3879 case RISCV::VLOXSEG8EI32_V:
3880 case RISCV::VLOXSEG8EI64_V:
3881 case RISCV::VLUXSEG8EI8_V:
3882 case RISCV::VLUXSEG8EI16_V:
3883 case RISCV::VLUXSEG8EI32_V:
3884 case RISCV::VLUXSEG8EI64_V:
3890 if (RISCVMCRegisterClasses[RISCV::VRM2RegClassID].
contains(
Reg))
3892 if (RISCVMCRegisterClasses[RISCV::VRM4RegClassID].
contains(
Reg))
3894 if (RISCVMCRegisterClasses[RISCV::VRM8RegClassID].
contains(
Reg))
3899bool RISCVAsmParser::validateInstruction(MCInst &Inst,
3903 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3904 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3907 if (DestReg == TempReg) {
3908 SMLoc Loc = Operands.
back()->getStartLoc();
3909 return Error(Loc,
"the temporary vector register cannot be the same as "
3910 "the destination register");
3914 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3915 Opcode == RISCV::TH_LWD) {
3920 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
3921 SMLoc Loc = Operands[1]->getStartLoc();
3922 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
3926 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
3930 SMLoc Loc = Operands[1]->getStartLoc();
3931 return Error(Loc,
"rs1 and rs2 must be different");
3935 const MCInstrDesc &MCID = MII.
get(Opcode);
3939 int DestIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
3943 const MCParsedAsmOperand *ParsedOp = Operands[1].get();
3944 if (!ParsedOp->
isReg()) {
3947 ParsedOp = Operands[2].get();
3949 assert(ParsedOp->
getReg() == DestReg &&
"Can't find parsed dest operand");
3953 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3957 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
3958 assert(VS2Idx >= 0 &&
"No vs2 operand?");
3959 unsigned CheckEncoding =
3962 for (
unsigned i = 0; i < std::max(NF, Lmul); i++) {
3963 if ((DestEncoding + i) == CheckEncoding)
3964 return Error(Loc,
"the destination vector register group cannot overlap"
3965 " the source vector register group");
3970 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
3974 unsigned CheckEncoding =
3976 for (
unsigned i = 0; i < Lmul; i++) {
3977 if ((DestEncoding + i) == CheckEncoding)
3979 "the destination vector register group cannot overlap"
3980 " the source vector register group");
3986 int VMIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vm);
3987 assert(VMIdx >= 0 &&
"No vm operand?");
3989 if (DestReg == RISCV::V0) {
3992 return Error(Loc,
"the destination vector register group cannot be V0");
4000 "Unexpected mask operand register");
4002 return Error(Loc,
"the destination vector register group cannot overlap"
4003 " the mask register");
4010bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
4018 case RISCV::PseudoC_ADDI_NOP: {
4020 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
4030 if (getSTI().hasFeature(RISCV::Feature64Bit))
4032 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV32)
4037 case RISCV::PACKW: {
4041 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV64)
4046 case RISCV::PseudoLLAImm:
4047 case RISCV::PseudoLAImm:
4048 case RISCV::PseudoLI: {
4054 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
4066 emitLoadImm(
Reg, Imm, Out);
4069 case RISCV::PseudoLLA:
4070 emitLoadLocalAddress(Inst, IDLoc, Out);
4072 case RISCV::PseudoLGA:
4073 emitLoadGlobalAddress(Inst, IDLoc, Out);
4075 case RISCV::PseudoLA:
4076 emitLoadAddress(Inst, IDLoc, Out);
4078 case RISCV::PseudoLA_TLS_IE:
4079 emitLoadTLSIEAddress(Inst, IDLoc, Out);
4081 case RISCV::PseudoLA_TLS_GD:
4082 emitLoadTLSGDAddress(Inst, IDLoc, Out);
4084 case RISCV::PseudoLB:
4085 case RISCV::PseudoQC_E_LB:
4086 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
4088 case RISCV::PseudoLBU:
4089 case RISCV::PseudoQC_E_LBU:
4090 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
4092 case RISCV::PseudoLH:
4093 case RISCV::PseudoQC_E_LH:
4094 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
4096 case RISCV::PseudoLHU:
4097 case RISCV::PseudoQC_E_LHU:
4098 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
4100 case RISCV::PseudoLW:
4101 case RISCV::PseudoQC_E_LW:
4102 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
4104 case RISCV::PseudoLWU:
4105 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
4107 case RISCV::PseudoLD:
4108 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
4110 case RISCV::PseudoLD_RV32:
4111 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
4113 case RISCV::PseudoFLH:
4114 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
4116 case RISCV::PseudoFLW:
4117 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
4119 case RISCV::PseudoFLD:
4120 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
4122 case RISCV::PseudoFLQ:
4123 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
4125 case RISCV::PseudoSB:
4126 case RISCV::PseudoQC_E_SB:
4127 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
4129 case RISCV::PseudoSH:
4130 case RISCV::PseudoQC_E_SH:
4131 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
4133 case RISCV::PseudoSW:
4134 case RISCV::PseudoQC_E_SW:
4135 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
4137 case RISCV::PseudoSD:
4138 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
4140 case RISCV::PseudoSD_RV32:
4141 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
4143 case RISCV::PseudoFSH:
4144 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
4146 case RISCV::PseudoFSW:
4147 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
4149 case RISCV::PseudoFSD:
4150 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4152 case RISCV::PseudoFSQ:
4153 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4155 case RISCV::PseudoAddTPRel:
4156 if (checkPseudoAddTPRel(Inst, Operands))
4159 case RISCV::PseudoTLSDESCCall:
4160 if (checkPseudoTLSDESCCall(Inst, Operands))
4163 case RISCV::PseudoSEXT_B:
4164 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4166 case RISCV::PseudoSEXT_H:
4167 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4169 case RISCV::PseudoZEXT_H:
4170 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4172 case RISCV::PseudoZEXT_W:
4173 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4175 case RISCV::PseudoVMSGEU_VX:
4176 case RISCV::PseudoVMSGEU_VX_M:
4177 case RISCV::PseudoVMSGEU_VX_M_T:
4178 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4180 case RISCV::PseudoVMSGE_VX:
4181 case RISCV::PseudoVMSGE_VX_M:
4182 case RISCV::PseudoVMSGE_VX_M_T:
4183 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4185 case RISCV::PseudoVMSGE_VI:
4186 case RISCV::PseudoVMSLT_VI: {
4190 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4192 emitToStreamer(Out, MCInstBuilder(
Opc)
4200 case RISCV::PseudoVMSGEU_VI:
4201 case RISCV::PseudoVMSLTU_VI: {
4208 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4211 emitToStreamer(Out, MCInstBuilder(
Opc)
4219 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4222 emitToStreamer(Out, MCInstBuilder(
Opc)
4232 case RISCV::PseudoCV_ELW:
4233 emitLoadStoreSymbol(Inst, RISCV::CV_ELW, IDLoc, Out,
false);
4237 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 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)
StringRef - Represent a constant reference to a string, i.e.
std::string str() const
str - Get the contents as an std::string.
char back() const
back - Get the last character in the string.
A switch()-like statement whose cases are string literals.
StringSwitch & Cases(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.