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);
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();
250 setAvailableFeatures(
255 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
256 if (getSTI().hasFeature(Feature)) {
257 MCSubtargetInfo &STI = copySTI();
258 setAvailableFeatures(
263 void pushFeatureBits() {
264 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
265 "These two stacks must be kept synchronized");
266 FeatureBitStack.push_back(getSTI().getFeatureBits());
267 ParserOptionsStack.push_back(ParserOptions);
270 bool popFeatureBits() {
271 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
272 "These two stacks must be kept synchronized");
273 if (FeatureBitStack.empty())
276 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
277 copySTI().setFeatureBits(FeatureBits);
278 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
280 ParserOptions = ParserOptionsStack.pop_back_val();
285 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
286 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
287 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
290 enum RISCVMatchResultTy :
unsigned {
291 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
292#define GET_OPERAND_DIAGNOSTIC_TYPES
293#include "RISCVGenAsmMatcher.inc"
294#undef GET_OPERAND_DIAGNOSTIC_TYPES
298 static bool isSymbolDiff(
const MCExpr *Expr);
300 RISCVAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
301 const MCInstrInfo &MII,
const MCTargetOptions &
Options)
302 : MCTargetAsmParser(
Options, STI, MII) {
309 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
311 auto ABIName = StringRef(
Options.ABIName);
312 if (ABIName.ends_with(
"f") && !getSTI().hasFeature(RISCV::FeatureStdExtF)) {
313 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
314 "doesn't support the F instruction set extension (ignoring "
316 }
else if (ABIName.ends_with(
"d") &&
317 !getSTI().hasFeature(RISCV::FeatureStdExtD)) {
318 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
319 "doesn't support the D instruction set extension (ignoring "
332 getTargetStreamer().emitTargetAttributes(STI,
false);
398 MCRegister OffsetReg;
401 SMLoc StartLoc, EndLoc;
416 RISCVOperand(KindTy K) : Kind(
K) {}
419 RISCVOperand(
const RISCVOperand &o) : MCParsedAsmOperand() {
421 StartLoc =
o.StartLoc;
424 case KindTy::Register:
427 case KindTy::Expression:
430 case KindTy::FPImmediate:
436 case KindTy::SystemRegister:
448 case KindTy::RegList:
451 case KindTy::StackAdj:
452 StackAdj =
o.StackAdj;
460 bool isToken()
const override {
return Kind == KindTy::Token; }
461 bool isReg()
const override {
return Kind == KindTy::Register; }
462 bool isExpr()
const {
return Kind == KindTy::Expression; }
463 bool isV0Reg()
const {
464 return Kind == KindTy::Register &&
Reg.RegNum == RISCV::V0;
466 bool isAnyReg()
const {
467 return Kind == KindTy::Register &&
468 (RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.RegNum) ||
469 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg.RegNum) ||
470 RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg.RegNum));
472 bool isAnyRegC()
const {
473 return Kind == KindTy::Register &&
474 (RISCVMCRegisterClasses[RISCV::GPRCRegClassID].contains(
476 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
479 bool isImm()
const override {
return isExpr(); }
480 bool isMem()
const override {
return false; }
481 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
482 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
483 bool isRegList()
const {
return Kind == KindTy::RegList; }
484 bool isRegListS0()
const {
485 return Kind == KindTy::RegList && RegList.Encoding !=
RISCVZC::RA;
487 bool isStackAdj()
const {
return Kind == KindTy::StackAdj; }
490 return Kind == KindTy::Register &&
491 RISCVMCRegisterClasses[RISCV::GPRRegClassID].contains(
Reg.RegNum);
494 bool isGPRPair()
const {
495 return Kind == KindTy::Register &&
496 RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].contains(
500 bool isGPRPairC()
const {
501 return Kind == KindTy::Register &&
502 RISCVMCRegisterClasses[RISCV::GPRPairCRegClassID].contains(
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.RegNum);
517 bool isGPRF32()
const {
518 return Kind == KindTy::Register &&
519 RISCVMCRegisterClasses[RISCV::GPRF32RegClassID].contains(
Reg.RegNum);
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) &&
587 VK == ELF::R_RISCV_CALL_PLT;
590 bool isPseudoJumpSymbol()
const {
593 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
597 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
598 VK == ELF::R_RISCV_CALL_PLT;
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 isUImm5Plus1()
const {
755 [](int64_t Imm) {
return Imm > 0 &&
isUInt<5>(Imm - 1); });
758 bool isUImm5GE6Plus1()
const {
760 [](int64_t Imm) {
return Imm >= 6 &&
isUInt<5>(Imm - 1); });
763 bool isUImm5Slist()
const {
764 return isUImmPred([](int64_t Imm) {
765 return (Imm == 0) || (
Imm == 1) || (Imm == 2) || (
Imm == 4) ||
766 (Imm == 8) || (
Imm == 16) || (Imm == 15) || (
Imm == 31);
770 bool isUImm8GE32()
const {
771 return isUImmPred([](int64_t Imm) {
return isUInt<8>(Imm) &&
Imm >= 32; });
774 bool isRnumArg()
const {
776 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(10); });
779 bool isRnumArg_0_7()
const {
781 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(7); });
784 bool isRnumArg_1_10()
const {
786 [](int64_t Imm) {
return Imm >= INT64_C(1) &&
Imm <= INT64_C(10); });
789 bool isRnumArg_2_14()
const {
791 [](int64_t Imm) {
return Imm >= INT64_C(2) &&
Imm <= INT64_C(14); });
794 template <
unsigned N>
bool isSImm()
const {
798 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
799 return IsConstantImm &&
isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
802 template <
class Pred>
bool isSImmPred(Pred p)
const {
806 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
807 return IsConstantImm &&
p(fixImmediateForRV32(Imm, isRV64Expr()));
810 bool isSImm5()
const {
return isSImm<5>(); }
811 bool isSImm6()
const {
return isSImm<6>(); }
812 bool isSImm10()
const {
return isSImm<10>(); }
813 bool isSImm11()
const {
return isSImm<11>(); }
814 bool isSImm12()
const {
return isSImm<12>(); }
815 bool isSImm16()
const {
return isSImm<16>(); }
816 bool isSImm26()
const {
return isSImm<26>(); }
818 bool isSImm5NonZero()
const {
819 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<5>(Imm); });
822 bool isSImm6NonZero()
const {
823 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<6>(Imm); });
826 bool isCLUIImm()
const {
827 return isUImmPred([](int64_t Imm) {
828 return (
isUInt<5>(Imm) && Imm != 0) || (
Imm >= 0xfffe0 &&
Imm <= 0xfffff);
832 bool isUImm2Lsb0()
const {
return isUImmShifted<1, 1>(); }
834 bool isUImm5Lsb0()
const {
return isUImmShifted<4, 1>(); }
836 bool isUImm6Lsb0()
const {
return isUImmShifted<5, 1>(); }
838 bool isUImm7Lsb00()
const {
return isUImmShifted<5, 2>(); }
840 bool isUImm7Lsb000()
const {
return isUImmShifted<4, 3>(); }
842 bool isUImm8Lsb00()
const {
return isUImmShifted<6, 2>(); }
844 bool isUImm8Lsb000()
const {
return isUImmShifted<5, 3>(); }
846 bool isUImm9Lsb000()
const {
return isUImmShifted<6, 3>(); }
848 bool isUImm14Lsb00()
const {
return isUImmShifted<12, 2>(); }
850 bool isUImm10Lsb00NonZero()
const {
857 static int64_t fixImmediateForRV32(int64_t Imm,
bool IsRV64Imm) {
863 bool isSImm12LO()
const {
868 if (evaluateConstantExpr(
getExpr(), Imm))
869 return isInt<12>(fixImmediateForRV32(Imm, isRV64Expr()));
872 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
875 VK == ELF::R_RISCV_TLSDESC_ADD_LO12);
878 bool isSImm12Lsb00000()
const {
882 bool isSImm10Lsb0000NonZero()
const {
887 bool isSImm16NonZero()
const {
888 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<16>(Imm); });
891 bool isUImm16NonZero()
const {
892 return isUImmPred([](int64_t Imm) {
return isUInt<16>(Imm) &&
Imm != 0; });
895 bool isSImm20LI()
const {
900 if (evaluateConstantExpr(
getExpr(), Imm))
901 return isInt<20>(fixImmediateForRV32(Imm, isRV64Expr()));
904 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
908 bool isSImm8Unsigned()
const {
return isSImm<8>() || isUImm<8>(); }
909 bool isSImm10Unsigned()
const {
return isSImm<10>() || isUImm<10>(); }
911 bool isUImm20LUI()
const {
916 if (evaluateConstantExpr(
getExpr(), Imm))
920 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
921 (VK == ELF::R_RISCV_HI20 || VK == ELF::R_RISCV_TPREL_HI20);
924 bool isUImm20AUIPC()
const {
929 if (evaluateConstantExpr(
getExpr(), Imm))
933 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
934 (VK == ELF::R_RISCV_PCREL_HI20 || VK == ELF::R_RISCV_GOT_HI20 ||
935 VK == ELF::R_RISCV_TLS_GOT_HI20 || VK == ELF::R_RISCV_TLS_GD_HI20 ||
936 VK == ELF::R_RISCV_TLSDESC_HI20);
939 bool isImmZero()
const {
940 return isUImmPred([](int64_t Imm) {
return 0 ==
Imm; });
943 bool isImmThree()
const {
944 return isUImmPred([](int64_t Imm) {
return 3 ==
Imm; });
947 bool isImmFour()
const {
948 return isUImmPred([](int64_t Imm) {
return 4 ==
Imm; });
951 bool isImm5Zibi()
const {
953 [](int64_t Imm) {
return (Imm != 0 &&
isUInt<5>(Imm)) ||
Imm == -1; });
956 bool isSImm5Plus1()
const {
961 bool isSImm18()
const {
962 return isSImmPred([](int64_t Imm) {
return isInt<18>(Imm); });
965 bool isSImm18Lsb0()
const {
969 bool isSImm19Lsb00()
const {
973 bool isSImm20Lsb000()
const {
977 bool isSImm32Lsb0()
const {
982 SMLoc getStartLoc()
const override {
return StartLoc; }
984 SMLoc getEndLoc()
const override {
return EndLoc; }
987 bool isRV64Expr()
const {
988 assert(Kind == KindTy::Expression &&
"Invalid type access!");
992 MCRegister
getReg()
const override {
993 assert(Kind == KindTy::Register &&
"Invalid type access!");
997 StringRef getSysReg()
const {
998 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
999 return StringRef(SysReg.Data, SysReg.Length);
1002 const MCExpr *
getExpr()
const {
1003 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1007 uint64_t getFPConst()
const {
1008 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1013 assert(Kind == KindTy::Token &&
"Invalid type access!");
1017 unsigned getVType()
const {
1018 assert(Kind == KindTy::VType &&
"Invalid type access!");
1023 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1027 unsigned getFence()
const {
1028 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1032 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1041 case KindTy::Expression:
1044 OS <<
' ' << (Expr.IsRV64 ?
"rv64" :
"rv32") <<
'>';
1046 case KindTy::FPImmediate:
1047 OS <<
"<fpimm: " << FPImm.Val <<
">";
1049 case KindTy::Register:
1051 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1056 case KindTy::SystemRegister:
1057 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1066 roundingModeToString(getFRM());
1074 case KindTy::RegList:
1079 case KindTy::StackAdj:
1080 OS <<
"<stackadj: ";
1084 case KindTy::RegReg:
1085 OS <<
"<RegReg: BaseReg " <<
RegName(
RegReg.BaseReg) <<
" OffsetReg "
1091 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1092 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1099 static std::unique_ptr<RISCVOperand>
1100 createReg(MCRegister
Reg, SMLoc S, SMLoc
E,
bool IsGPRAsFPR =
false) {
1101 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1102 Op->Reg.RegNum =
Reg;
1103 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1109 static std::unique_ptr<RISCVOperand> createExpr(
const MCExpr *Val, SMLoc S,
1110 SMLoc
E,
bool IsRV64) {
1111 auto Op = std::make_unique<RISCVOperand>(KindTy::Expression);
1112 Op->Expr.Expr = Val;
1113 Op->Expr.IsRV64 = IsRV64;
1119 static std::unique_ptr<RISCVOperand> createFPImm(uint64_t Val, SMLoc S) {
1120 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1121 Op->FPImm.Val = Val;
1127 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1128 unsigned Encoding) {
1129 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1130 Op->SysReg.Data = Str.data();
1131 Op->SysReg.Length = Str.size();
1138 static std::unique_ptr<RISCVOperand>
1140 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1147 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val, SMLoc S) {
1148 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1149 Op->Fence.Val = Val;
1155 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI, SMLoc S) {
1156 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1157 Op->VType.Val = VTypeI;
1163 static std::unique_ptr<RISCVOperand> createRegList(
unsigned RlistEncode,
1165 auto Op = std::make_unique<RISCVOperand>(KindTy::RegList);
1171 static std::unique_ptr<RISCVOperand>
1172 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {
1173 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1175 Op->RegReg.OffsetReg = OffsetReg;
1181 static std::unique_ptr<RISCVOperand> createStackAdj(
unsigned StackAdj, SMLoc S) {
1182 auto Op = std::make_unique<RISCVOperand>(KindTy::StackAdj);
1183 Op->StackAdj.Val = StackAdj;
1188 static void addExpr(MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1189 assert(Expr &&
"Expr shouldn't be null!");
1191 bool IsConstant = evaluateConstantExpr(Expr, Imm);
1201 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1202 assert(
N == 1 &&
"Invalid number of operands!");
1206 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1207 assert(
N == 1 &&
"Invalid number of operands!");
1208 addExpr(Inst,
getExpr(), isRV64Expr());
1211 void addSImm8UnsignedOperands(MCInst &Inst,
unsigned N)
const {
1212 assert(
N == 1 &&
"Invalid number of operands!");
1219 void addSImm10UnsignedOperands(MCInst &Inst,
unsigned N)
const {
1220 assert(
N == 1 &&
"Invalid number of operands!");
1227 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
1228 assert(
N == 1 &&
"Invalid number of operands!");
1230 addExpr(Inst,
getExpr(), isRV64Expr());
1235 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1239 void addFenceArgOperands(MCInst &Inst,
unsigned N)
const {
1240 assert(
N == 1 &&
"Invalid number of operands!");
1244 void addCSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
1245 assert(
N == 1 &&
"Invalid number of operands!");
1252 void addVTypeIOperands(MCInst &Inst,
unsigned N)
const {
1253 assert(
N == 1 &&
"Invalid number of operands!");
1255 if (Kind == KindTy::Expression) {
1256 [[maybe_unused]]
bool IsConstantImm =
1257 evaluateConstantExpr(
getExpr(), Imm);
1258 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1265 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1266 assert(
N == 1 &&
"Invalid number of operands!");
1270 void addRegRegOperands(MCInst &Inst,
unsigned N)
const {
1271 assert(
N == 2 &&
"Invalid number of operands!");
1276 void addStackAdjOperands(MCInst &Inst,
unsigned N)
const {
1277 assert(
N == 1 &&
"Invalid number of operands!");
1281 void addFRMArgOperands(MCInst &Inst,
unsigned N)
const {
1282 assert(
N == 1 &&
"Invalid number of operands!");
1288#define GET_REGISTER_MATCHER
1289#define GET_SUBTARGET_FEATURE_NAME
1290#define GET_MATCHER_IMPLEMENTATION
1291#define GET_MNEMONIC_SPELL_CHECKER
1292#include "RISCVGenAsmMatcher.inc"
1295 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1296 return Reg - RISCV::F0_D + RISCV::F0_H;
1300 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1301 return Reg - RISCV::F0_D + RISCV::F0_F;
1305 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1306 return Reg - RISCV::F0_D + RISCV::F0_Q;
1311 unsigned RegClassID;
1312 if (Kind == MCK_VRM2)
1313 RegClassID = RISCV::VRM2RegClassID;
1314 else if (Kind == MCK_VRM4)
1315 RegClassID = RISCV::VRM4RegClassID;
1316 else if (Kind == MCK_VRM8)
1317 RegClassID = RISCV::VRM8RegClassID;
1321 &RISCVMCRegisterClasses[RegClassID]);
1326 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1328 return Match_InvalidOperand;
1330 MCRegister
Reg =
Op.getReg();
1332 RISCVMCRegisterClasses[RISCV::FPR64RegClassID].contains(
Reg);
1334 RISCVMCRegisterClasses[RISCV::FPR64CRegClassID].contains(
Reg);
1335 bool IsRegVR = RISCVMCRegisterClasses[RISCV::VRRegClassID].contains(
Reg);
1337 if (IsRegFPR64 && Kind == MCK_FPR128) {
1339 return Match_Success;
1343 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1344 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1346 return Match_Success;
1350 if (IsRegFPR64 && Kind == MCK_FPR16) {
1352 return Match_Success;
1354 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1355 Op.Reg.RegNum =
Reg - RISCV::X0 + RISCV::X0_H;
1356 return Match_Success;
1358 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1359 Op.Reg.RegNum =
Reg - RISCV::X0 + RISCV::X0_W;
1360 return Match_Success;
1367 if (RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg) &&
1368 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1370 return Match_Success;
1374 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1377 return Match_InvalidOperand;
1378 return Match_Success;
1380 return Match_InvalidOperand;
1383bool RISCVAsmParser::generateImmOutOfRangeError(
1384 SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
1385 const Twine &Msg =
"immediate must be an integer in the range") {
1386 return Error(ErrorLoc, Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]");
1389bool RISCVAsmParser::generateImmOutOfRangeError(
1391 const Twine &Msg =
"immediate must be an integer in the range") {
1392 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1393 return generateImmOutOfRangeError(ErrorLoc,
Lower,
Upper, Msg);
1396bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1399 uint64_t &ErrorInfo,
1400 bool MatchingInlineAsm) {
1402 FeatureBitset MissingFeatures;
1404 auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
1410 if (validateInstruction(Inst, Operands))
1412 return processInstruction(Inst, IDLoc, Operands, Out);
1413 case Match_MissingFeature: {
1414 assert(MissingFeatures.
any() &&
"Unknown missing features!");
1415 bool FirstFeature =
true;
1416 std::string Msg =
"instruction requires the following:";
1417 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
1418 if (MissingFeatures[i]) {
1419 Msg += FirstFeature ?
" " :
", ";
1421 FirstFeature =
false;
1424 return Error(IDLoc, Msg);
1426 case Match_MnemonicFail: {
1427 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1428 std::string Suggestion = RISCVMnemonicSpellCheck(
1429 ((RISCVOperand &)*Operands[0]).
getToken(), FBS, 0);
1430 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1432 case Match_InvalidOperand: {
1433 SMLoc ErrorLoc = IDLoc;
1434 if (ErrorInfo != ~0ULL) {
1435 if (ErrorInfo >= Operands.
size())
1436 return Error(ErrorLoc,
"too few operands for instruction");
1438 ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1439 if (ErrorLoc == SMLoc())
1442 return Error(ErrorLoc,
"invalid operand for instruction");
1449 if (Result > FIRST_TARGET_MATCH_RESULT_TY) {
1450 SMLoc ErrorLoc = IDLoc;
1451 if (ErrorInfo != ~0ULL && ErrorInfo >= Operands.
size())
1452 return Error(ErrorLoc,
"too few operands for instruction");
1458 case Match_InvalidImmXLenLI:
1460 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1461 return Error(ErrorLoc,
"operand must be a constant 64-bit integer");
1463 return generateImmOutOfRangeError(Operands, ErrorInfo,
1464 std::numeric_limits<int32_t>::min(),
1465 std::numeric_limits<uint32_t>::max());
1466 case Match_InvalidImmXLenLI_Restricted:
1468 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1469 return Error(ErrorLoc,
"operand either must be a constant 64-bit integer "
1470 "or a bare symbol name");
1472 return generateImmOutOfRangeError(
1473 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1474 std::numeric_limits<uint32_t>::max(),
1475 "operand either must be a bare symbol name or an immediate integer in "
1477 case Match_InvalidUImmLog2XLen:
1479 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1480 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1481 case Match_InvalidUImmLog2XLenNonZero:
1483 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 6) - 1);
1484 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1485 case Match_InvalidUImm1:
1486 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 1) - 1);
1487 case Match_InvalidUImm2:
1488 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 2) - 1);
1489 case Match_InvalidUImm2Lsb0:
1490 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 2,
1491 "immediate must be one of");
1492 case Match_InvalidUImm3:
1493 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 3) - 1);
1494 case Match_InvalidUImm4:
1495 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 4) - 1);
1496 case Match_InvalidUImm5:
1497 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 5) - 1);
1498 case Match_InvalidUImm5NonZero:
1499 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5) - 1);
1500 case Match_InvalidUImm5GT3:
1501 return generateImmOutOfRangeError(Operands, ErrorInfo, 4, (1 << 5) - 1);
1502 case Match_InvalidUImm5Plus1:
1503 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 5));
1504 case Match_InvalidUImm5GE6Plus1:
1505 return generateImmOutOfRangeError(Operands, ErrorInfo, 6, (1 << 5));
1506 case Match_InvalidUImm5Slist: {
1507 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1508 return Error(ErrorLoc,
1509 "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31");
1511 case Match_InvalidUImm6:
1512 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 6) - 1);
1513 case Match_InvalidUImm7:
1514 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 7) - 1);
1515 case Match_InvalidUImm8:
1516 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 8) - 1);
1517 case Match_InvalidUImm8GE32:
1518 return generateImmOutOfRangeError(Operands, ErrorInfo, 32, (1 << 8) - 1);
1519 case Match_InvalidSImm5:
1520 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4),
1522 case Match_InvalidSImm5NonZero:
1523 return generateImmOutOfRangeError(
1524 Operands, ErrorInfo, -(1 << 4), (1 << 4) - 1,
1525 "immediate must be non-zero in the range");
1526 case Match_InvalidSImm6:
1527 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 5),
1529 case Match_InvalidSImm6NonZero:
1530 return generateImmOutOfRangeError(
1531 Operands, ErrorInfo, -(1 << 5), (1 << 5) - 1,
1532 "immediate must be non-zero in the range");
1533 case Match_InvalidCLUIImm:
1534 return generateImmOutOfRangeError(
1535 Operands, ErrorInfo, 1, (1 << 5) - 1,
1536 "immediate must be in [0xfffe0, 0xfffff] or");
1537 case Match_InvalidUImm5Lsb0:
1538 return generateImmOutOfRangeError(
1539 Operands, ErrorInfo, 0, (1 << 5) - 2,
1540 "immediate must be a multiple of 2 bytes in the range");
1541 case Match_InvalidUImm6Lsb0:
1542 return generateImmOutOfRangeError(
1543 Operands, ErrorInfo, 0, (1 << 6) - 2,
1544 "immediate must be a multiple of 2 bytes in the range");
1545 case Match_InvalidUImm7Lsb00:
1546 return generateImmOutOfRangeError(
1547 Operands, ErrorInfo, 0, (1 << 7) - 4,
1548 "immediate must be a multiple of 4 bytes in the range");
1549 case Match_InvalidUImm8Lsb00:
1550 return generateImmOutOfRangeError(
1551 Operands, ErrorInfo, 0, (1 << 8) - 4,
1552 "immediate must be a multiple of 4 bytes in the range");
1553 case Match_InvalidUImm8Lsb000:
1554 return generateImmOutOfRangeError(
1555 Operands, ErrorInfo, 0, (1 << 8) - 8,
1556 "immediate must be a multiple of 8 bytes in the range");
1557 case Match_InvalidUImm9:
1558 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 9) - 1,
1559 "immediate offset must be in the range");
1560 case Match_InvalidBareSImm9Lsb0:
1561 return generateImmOutOfRangeError(
1562 Operands, ErrorInfo, -(1 << 8), (1 << 8) - 2,
1563 "immediate must be a multiple of 2 bytes in the range");
1564 case Match_InvalidUImm9Lsb000:
1565 return generateImmOutOfRangeError(
1566 Operands, ErrorInfo, 0, (1 << 9) - 8,
1567 "immediate must be a multiple of 8 bytes in the range");
1568 case Match_InvalidSImm8Unsigned:
1569 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 7),
1571 case Match_InvalidSImm10:
1572 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
1574 case Match_InvalidSImm10Unsigned:
1575 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 9),
1577 case Match_InvalidUImm10Lsb00NonZero:
1578 return generateImmOutOfRangeError(
1579 Operands, ErrorInfo, 4, (1 << 10) - 4,
1580 "immediate must be a multiple of 4 bytes in the range");
1581 case Match_InvalidSImm10Lsb0000NonZero:
1582 return generateImmOutOfRangeError(
1583 Operands, ErrorInfo, -(1 << 9), (1 << 9) - 16,
1584 "immediate must be a multiple of 16 bytes and non-zero in the range");
1585 case Match_InvalidSImm11:
1586 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 10),
1588 case Match_InvalidBareSImm11Lsb0:
1589 return generateImmOutOfRangeError(
1590 Operands, ErrorInfo, -(1 << 10), (1 << 10) - 2,
1591 "immediate must be a multiple of 2 bytes in the range");
1592 case Match_InvalidUImm10:
1593 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 10) - 1);
1594 case Match_InvalidUImm11:
1595 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 11) - 1);
1596 case Match_InvalidUImm14Lsb00:
1597 return generateImmOutOfRangeError(
1598 Operands, ErrorInfo, 0, (1 << 14) - 4,
1599 "immediate must be a multiple of 4 bytes in the range");
1600 case Match_InvalidUImm16NonZero:
1601 return generateImmOutOfRangeError(Operands, ErrorInfo, 1, (1 << 16) - 1);
1602 case Match_InvalidSImm12:
1603 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 11),
1605 case Match_InvalidSImm12LO:
1606 return generateImmOutOfRangeError(
1607 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 1,
1608 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo specifier or an "
1609 "integer in the range");
1610 case Match_InvalidBareSImm12Lsb0:
1611 return generateImmOutOfRangeError(
1612 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 2,
1613 "immediate must be a multiple of 2 bytes in the range");
1614 case Match_InvalidSImm12Lsb00000:
1615 return generateImmOutOfRangeError(
1616 Operands, ErrorInfo, -(1 << 11), (1 << 11) - 32,
1617 "immediate must be a multiple of 32 bytes in the range");
1618 case Match_InvalidBareSImm13Lsb0:
1619 return generateImmOutOfRangeError(
1620 Operands, ErrorInfo, -(1 << 12), (1 << 12) - 2,
1621 "immediate must be a multiple of 2 bytes in the range");
1622 case Match_InvalidSImm16:
1623 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 15),
1625 case Match_InvalidSImm16NonZero:
1626 return generateImmOutOfRangeError(
1627 Operands, ErrorInfo, -(1 << 15), (1 << 15) - 1,
1628 "immediate must be non-zero in the range");
1629 case Match_InvalidSImm20LI:
1630 return generateImmOutOfRangeError(
1631 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 1,
1632 "operand must be a symbol with a %qc.abs20 specifier or an integer "
1634 case Match_InvalidUImm20LUI:
1635 return generateImmOutOfRangeError(
1636 Operands, ErrorInfo, 0, (1 << 20) - 1,
1637 "operand must be a symbol with "
1638 "%hi/%tprel_hi specifier or an integer in "
1640 case Match_InvalidUImm20:
1641 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 20) - 1);
1642 case Match_InvalidUImm20AUIPC:
1643 return generateImmOutOfRangeError(
1644 Operands, ErrorInfo, 0, (1 << 20) - 1,
1645 "operand must be a symbol with a "
1646 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
1648 "an integer in the range");
1649 case Match_InvalidBareSImm21Lsb0:
1650 return generateImmOutOfRangeError(
1651 Operands, ErrorInfo, -(1 << 20), (1 << 20) - 2,
1652 "immediate must be a multiple of 2 bytes in the range");
1653 case Match_InvalidCSRSystemRegister: {
1654 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, (1 << 12) - 1,
1655 "operand must be a valid system register "
1656 "name or an integer in the range");
1658 case Match_InvalidImm5Zibi:
1659 return generateImmOutOfRangeError(
1660 Operands, ErrorInfo, -1, (1 << 5) - 1,
1661 "immediate must be non-zero in the range");
1662 case Match_InvalidXSfmmVType: {
1663 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1664 return generateXSfmmVTypeError(ErrorLoc);
1666 case Match_InvalidVTypeI: {
1667 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1668 return generateVTypeError(ErrorLoc);
1670 case Match_InvalidSImm5Plus1: {
1671 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 4) + 1,
1673 "immediate must be in the range");
1675 case Match_InvalidSImm18:
1676 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 17),
1678 case Match_InvalidSImm18Lsb0:
1679 return generateImmOutOfRangeError(
1680 Operands, ErrorInfo, -(1 << 17), (1 << 17) - 2,
1681 "immediate must be a multiple of 2 bytes in the range");
1682 case Match_InvalidSImm19Lsb00:
1683 return generateImmOutOfRangeError(
1684 Operands, ErrorInfo, -(1 << 18), (1 << 18) - 4,
1685 "immediate must be a multiple of 4 bytes in the range");
1686 case Match_InvalidSImm20Lsb000:
1687 return generateImmOutOfRangeError(
1688 Operands, ErrorInfo, -(1 << 19), (1 << 19) - 8,
1689 "immediate must be a multiple of 8 bytes in the range");
1690 case Match_InvalidSImm26:
1691 return generateImmOutOfRangeError(Operands, ErrorInfo, -(1 << 25),
1694 case Match_InvalidBareSymbolQC_E_LI:
1697 case Match_InvalidBareSImm32:
1698 return generateImmOutOfRangeError(Operands, ErrorInfo,
1699 std::numeric_limits<int32_t>::min(),
1700 std::numeric_limits<uint32_t>::max());
1701 case Match_InvalidBareSImm32Lsb0:
1702 return generateImmOutOfRangeError(
1703 Operands, ErrorInfo, std::numeric_limits<int32_t>::min(),
1704 std::numeric_limits<int32_t>::max() - 1,
1705 "operand must be a multiple of 2 bytes in the range");
1706 case Match_InvalidRnumArg: {
1707 return generateImmOutOfRangeError(Operands, ErrorInfo, 0, 10);
1709 case Match_InvalidStackAdj: {
1710 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1713 "stack adjustment is invalid for this instruction and register list");
1717 if (
const char *MatchDiag = getMatchKindDiag((RISCVMatchResultTy)Result)) {
1718 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
1719 return Error(ErrorLoc, MatchDiag);
1729MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name)
const {
1738 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1739 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1740 static_assert(RISCV::F0_D < RISCV::F0_Q,
"FPR matching must be updated");
1743 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1748bool RISCVAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1750 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1751 return Error(StartLoc,
"invalid register name");
1755ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1757 const AsmToken &Tok = getParser().getTok();
1760 StringRef
Name = getLexer().getTok().getIdentifier();
1770ParseStatus RISCVAsmParser::parseRegister(
OperandVector &Operands,
1772 SMLoc FirstS = getLoc();
1773 bool HadParens =
false;
1780 size_t ReadCount = getLexer().peekTokens(Buf);
1783 LParen = getParser().getTok();
1788 switch (getLexer().getKind()) {
1791 getLexer().UnLex(LParen);
1794 StringRef
Name = getLexer().getTok().getIdentifier();
1799 getLexer().UnLex(LParen);
1803 Operands.
push_back(RISCVOperand::createToken(
"(", FirstS));
1805 SMLoc
E = getTok().getEndLoc();
1812 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
1818ParseStatus RISCVAsmParser::parseInsnDirectiveOpcode(
OperandVector &Operands) {
1823 switch (getLexer().getKind()) {
1833 if (getParser().parseExpression(Res,
E))
1838 int64_t
Imm =
CE->getValue();
1840 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1849 if (getParser().parseIdentifier(Identifier))
1852 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
1855 "Unexpected opcode");
1858 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1868 return generateImmOutOfRangeError(
1870 "opcode must be a valid opcode name or an immediate in the range");
1873ParseStatus RISCVAsmParser::parseInsnCDirectiveOpcode(
OperandVector &Operands) {
1878 switch (getLexer().getKind()) {
1888 if (getParser().parseExpression(Res,
E))
1893 int64_t
Imm =
CE->getValue();
1894 if (Imm >= 0 && Imm <= 2) {
1895 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1904 if (getParser().parseIdentifier(Identifier))
1908 if (Identifier ==
"C0")
1910 else if (Identifier ==
"C1")
1912 else if (Identifier ==
"C2")
1919 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
1928 return generateImmOutOfRangeError(
1930 "opcode must be a valid opcode name or an immediate in the range");
1933ParseStatus RISCVAsmParser::parseCSRSystemRegister(
OperandVector &Operands) {
1937 auto SysRegFromConstantInt = [
this](
const MCExpr *
E, SMLoc S) {
1939 int64_t
Imm =
CE->getValue();
1941 auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
1945 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
1948 return RISCVOperand::createSysReg(
Reg.Name, S, Imm);
1952 return RISCVOperand::createSysReg(
"", S, Imm);
1955 return std::unique_ptr<RISCVOperand>();
1958 switch (getLexer().getKind()) {
1968 if (getParser().parseExpression(Res))
1971 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
1976 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
1980 if (getParser().parseIdentifier(Identifier))
1983 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
1986 if (SysReg->IsDeprecatedName) {
1988 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
1990 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
1992 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
1998 const auto &FeatureBits = getSTI().getFeatureBits();
1999 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
2001 return SysReg->FeaturesRequired[Feature.Value];
2003 auto ErrorMsg = std::string(
"system register '") + SysReg->Name +
"' ";
2004 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
2005 ErrorMsg +=
"is RV32 only";
2007 ErrorMsg +=
" and ";
2011 "requires '" + std::string(Feature->Key) +
"' to be enabled";
2014 return Error(S, ErrorMsg);
2017 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
2032 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2033 "operand must be a valid system register "
2034 "name or an integer in the range");
2038 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2045ParseStatus RISCVAsmParser::parseFPImm(
OperandVector &Operands) {
2050 StringRef
Identifier = getTok().getIdentifier();
2051 if (
Identifier.compare_insensitive(
"inf") == 0) {
2054 getTok().getEndLoc(), isRV64()));
2055 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2058 getTok().getEndLoc(), isRV64()));
2059 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2062 getTok().getEndLoc(), isRV64()));
2064 return TokError(
"invalid floating point literal");
2075 const AsmToken &Tok = getTok();
2077 return TokError(
"invalid floating point immediate");
2080 APFloat RealVal(APFloat::IEEEdouble());
2082 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2084 return TokError(
"invalid floating point representation");
2087 RealVal.changeSign();
2089 Operands.
push_back(RISCVOperand::createFPImm(
2090 RealVal.bitcastToAPInt().getZExtValue(), S));
2097ParseStatus RISCVAsmParser::parseExpression(
OperandVector &Operands) {
2102 switch (getLexer().getKind()) {
2114 if (getParser().parseExpression(Res,
E))
2118 return parseOperandWithSpecifier(Operands);
2121 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2125ParseStatus RISCVAsmParser::parseOperandWithSpecifier(
OperandVector &Operands) {
2131 const MCExpr *Expr =
nullptr;
2132 bool Failed = parseExprWithSpecifier(Expr,
E);
2134 Operands.
push_back(RISCVOperand::createExpr(Expr, S,
E, isRV64()));
2138bool RISCVAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
2139 SMLoc Loc = getLoc();
2141 return TokError(
"expected '%' relocation specifier");
2142 StringRef
Identifier = getParser().getTok().getIdentifier();
2145 return TokError(
"invalid relocation specifier");
2151 const MCExpr *SubExpr;
2152 if (getParser().parseParenExpression(SubExpr,
E))
2159bool RISCVAsmParser::parseDataExpr(
const MCExpr *&Res) {
2162 return parseExprWithSpecifier(Res,
E);
2163 return getParser().parseExpression(Res);
2166ParseStatus RISCVAsmParser::parseBareSymbol(
OperandVector &Operands) {
2174 AsmToken Tok = getLexer().getTok();
2176 if (getParser().parseIdentifier(Identifier))
2186 getLexer().UnLex(Tok);
2194 switch (getLexer().getKind()) {
2196 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2209 if (getParser().parseExpression(Expr,
E))
2212 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2216ParseStatus RISCVAsmParser::parseCallSymbol(
OperandVector &Operands) {
2222 std::string
Identifier(getTok().getIdentifier());
2228 SMLoc Loc = getLoc();
2229 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2230 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2244 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2248ParseStatus RISCVAsmParser::parsePseudoJumpSymbol(
OperandVector &Operands) {
2253 if (getParser().parseExpression(Res,
E))
2256 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef)
2257 return Error(S,
"operand must be a valid jump target");
2260 Operands.
push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2264ParseStatus RISCVAsmParser::parseJALOffset(
OperandVector &Operands) {
2278 return parseExpression(Operands);
2281bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2282 unsigned &Sew,
unsigned &Lmul,
2283 bool &Fractional,
bool &TailAgnostic,
2284 bool &MaskAgnostic,
bool &AltFmt) {
2289 if (State < VTypeState::SeenSew &&
Identifier.consume_front(
"e")) {
2291 if (Identifier ==
"16alt") {
2294 }
else if (Identifier ==
"8alt") {
2304 State = VTypeState::SeenSew;
2308 if (State < VTypeState::SeenLmul &&
Identifier.consume_front(
"m")) {
2311 if (Identifier ==
"a" || Identifier ==
"u") {
2313 State = VTypeState::SeenMaskPolicy;
2324 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2325 unsigned MinLMUL = ELEN / 8;
2328 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2329 Twine(MinLMUL) +
" is reserved");
2332 State = VTypeState::SeenLmul;
2336 if (State < VTypeState::SeenTailPolicy &&
Identifier.starts_with(
"t")) {
2337 if (Identifier ==
"ta")
2338 TailAgnostic =
true;
2339 else if (Identifier ==
"tu")
2340 TailAgnostic =
false;
2344 State = VTypeState::SeenTailPolicy;
2348 if (State < VTypeState::SeenMaskPolicy &&
Identifier.starts_with(
"m")) {
2349 if (Identifier ==
"ma")
2350 MaskAgnostic =
true;
2351 else if (Identifier ==
"mu")
2352 MaskAgnostic =
false;
2356 State = VTypeState::SeenMaskPolicy;
2363ParseStatus RISCVAsmParser::parseVTypeI(
OperandVector &Operands) {
2369 bool Fractional =
false;
2370 bool TailAgnostic =
false;
2371 bool MaskAgnostic =
false;
2374 VTypeState State = VTypeState::SeenNothingYet;
2376 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2377 MaskAgnostic, AltFmt)) {
2379 if (State == VTypeState::SeenNothingYet)
2388 State == VTypeState::SeenNothingYet)
2389 return generateVTypeError(S);
2393 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2394 unsigned MaxSEW = ELEN / Lmul;
2396 if (MaxSEW >= 8 && Sew > MaxSEW)
2397 Warning(S,
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2398 " and LMUL == mf" + Twine(Lmul) +
2399 " may not be compatible with all RVV implementations");
2404 Operands.
push_back(RISCVOperand::createVType(VTypeI, S));
2408bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2409 if (STI->
hasFeature(RISCV::FeatureStdExtZvfbfa) ||
2410 STI->
hasFeature(RISCV::FeatureVendorXSfvfbfexp16e))
2414 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2418 "e[8|16|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2421ParseStatus RISCVAsmParser::parseXSfmmVType(
OperandVector &Operands) {
2438 if (Identifier !=
"16alt")
2467 Operands.
push_back(RISCVOperand::createVType(
2473 return generateXSfmmVTypeError(S);
2476bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
2477 return Error(ErrorLoc,
"operand must be e[8|16|16alt|32|64],w[1|2|4]");
2480ParseStatus RISCVAsmParser::parseMaskReg(
OperandVector &Operands) {
2484 StringRef
Name = getLexer().getTok().getIdentifier();
2485 if (!
Name.consume_back(
".t"))
2486 return Error(getLoc(),
"expected '.t' suffix");
2491 if (
Reg != RISCV::V0)
2494 SMLoc
E = getTok().getEndLoc();
2500ParseStatus RISCVAsmParser::parseGPRAsFPR64(
OperandVector &Operands) {
2501 if (!isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2504 return parseGPRAsFPR(Operands);
2507ParseStatus RISCVAsmParser::parseGPRAsFPR(
OperandVector &Operands) {
2511 StringRef
Name = getLexer().getTok().getIdentifier();
2517 SMLoc
E = getTok().getEndLoc();
2519 Operands.
push_back(RISCVOperand::createReg(
2520 Reg, S,
E, !getSTI().hasFeature(RISCV::FeatureStdExtF)));
2524ParseStatus RISCVAsmParser::parseGPRPairAsFPR64(
OperandVector &Operands) {
2525 if (isRV64() || getSTI().hasFeature(RISCV::FeatureStdExtF))
2531 StringRef
Name = getLexer().getTok().getIdentifier();
2537 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2540 if ((
Reg - RISCV::X0) & 1) {
2543 if (getSTI().hasFeature(RISCV::FeatureStdExtZfinx))
2544 return TokError(
"double precision floating point operands must use even "
2545 "numbered X register");
2550 SMLoc
E = getTok().getEndLoc();
2553 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2555 Reg, RISCV::sub_gpr_even,
2556 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2557 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2561template <
bool IsRV64>
2562ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands) {
2563 return parseGPRPair(Operands, IsRV64);
2566ParseStatus RISCVAsmParser::parseGPRPair(
OperandVector &Operands,
2573 if (!IsRV64Inst && isRV64())
2579 StringRef
Name = getLexer().getTok().getIdentifier();
2585 if (!RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(
Reg))
2588 if ((
Reg - RISCV::X0) & 1)
2589 return TokError(
"register must be even");
2592 SMLoc
E = getTok().getEndLoc();
2595 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2597 Reg, RISCV::sub_gpr_even,
2598 &RISCVMCRegisterClasses[RISCV::GPRPairRegClassID]);
2599 Operands.
push_back(RISCVOperand::createReg(Pair, S,
E));
2603ParseStatus RISCVAsmParser::parseFRMArg(
OperandVector &Operands) {
2606 "operand must be a valid floating point rounding mode mnemonic");
2608 StringRef Str = getLexer().getTok().getIdentifier();
2613 "operand must be a valid floating point rounding mode mnemonic");
2615 Operands.
push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2620ParseStatus RISCVAsmParser::parseFenceArg(
OperandVector &Operands) {
2621 const AsmToken &Tok = getLexer().getTok();
2627 Operands.
push_back(RISCVOperand::createFenceArg(0, getLoc()));
2641 for (
char c : Str) {
2670 Operands.
push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2676 return TokError(
"operand must be formed of letters selected in-order from "
2680ParseStatus RISCVAsmParser::parseMemOpBaseReg(
OperandVector &Operands) {
2683 Operands.
push_back(RISCVOperand::createToken(
"(", getLoc()));
2685 if (!parseRegister(Operands).isSuccess())
2686 return Error(getLoc(),
"expected register");
2690 Operands.
push_back(RISCVOperand::createToken(
")", getLoc()));
2695ParseStatus RISCVAsmParser::parseZeroOffsetMemOp(
OperandVector &Operands) {
2714 std::unique_ptr<RISCVOperand> OptionalImmOp;
2721 SMLoc ImmStart = getLoc();
2722 if (getParser().parseIntToken(ImmVal,
2723 "expected '(' or optional integer offset"))
2728 SMLoc ImmEnd = getLoc();
2731 ImmStart, ImmEnd, isRV64());
2735 OptionalImmOp ?
"expected '(' after optional integer offset"
2736 :
"expected '(' or optional integer offset"))
2739 if (!parseRegister(Operands).isSuccess())
2740 return Error(getLoc(),
"expected register");
2746 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2748 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2749 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2754ParseStatus RISCVAsmParser::parseRegReg(
OperandVector &Operands) {
2760 StringRef OffsetRegName = getLexer().getTok().getIdentifier();
2763 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(OffsetReg))
2764 return Error(getLoc(),
"expected GPR register");
2771 return Error(getLoc(),
"expected GPR register");
2773 StringRef BaseRegName = getLexer().getTok().getIdentifier();
2776 !RISCVMCRegisterClasses[RISCV::GPRRegClassID].
contains(BaseReg))
2777 return Error(getLoc(),
"expected GPR register");
2783 Operands.
push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));
2795ParseStatus RISCVAsmParser::parseRegList(
OperandVector &Operands,
2796 bool MustIncludeS0) {
2808 return Error(getLoc(),
"invalid register");
2810 StringRef
RegName = getTok().getIdentifier();
2813 return Error(getLoc(),
"invalid register");
2816 UsesXRegs =
RegName[0] ==
'x';
2817 if (
Reg != RISCV::X1)
2818 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
2819 }
else if (RegEnd == RISCV::X1) {
2820 if (
Reg != RISCV::X8 || (UsesXRegs != (
RegName[0] ==
'x')))
2821 return Error(getLoc(), Twine(
"register must be '") +
2822 (UsesXRegs ?
"x8" :
"s0") +
"'");
2823 }
else if (RegEnd == RISCV::X9 && UsesXRegs) {
2824 if (
Reg != RISCV::X18 || (
RegName[0] !=
'x'))
2825 return Error(getLoc(),
"register must be 'x18'");
2827 return Error(getLoc(),
"too many register ranges");
2834 SMLoc MinusLoc = getLoc();
2836 if (RegEnd == RISCV::X1)
2837 return Error(MinusLoc, Twine(
"register '") + (UsesXRegs ?
"x1" :
"ra") +
2838 "' cannot start a multiple register range");
2841 return Error(getLoc(),
"invalid register");
2843 StringRef
RegName = getTok().getIdentifier();
2846 return Error(getLoc(),
"invalid register");
2848 if (RegEnd == RISCV::X8) {
2849 if ((
Reg != RISCV::X9 &&
2851 (UsesXRegs != (
RegName[0] ==
'x'))) {
2853 return Error(getLoc(),
"register must be 'x9'");
2854 return Error(getLoc(),
"register must be in the range 's1' to 's11'");
2856 }
else if (RegEnd == RISCV::X18) {
2858 return Error(getLoc(),
2859 "register must be in the range 'x19' to 'x27'");
2872 if (RegEnd == RISCV::X26)
2873 return Error(S,
"invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "
2874 "x18-x26}' is not supported");
2880 return Error(S,
"register list must include 's0' or 'x8'");
2882 Operands.
push_back(RISCVOperand::createRegList(Encode, S));
2887ParseStatus RISCVAsmParser::parseZcmpStackAdj(
OperandVector &Operands,
2888 bool ExpectNegative) {
2897 auto *RegListOp =
static_cast<RISCVOperand *
>(Operands.
back().
get());
2898 if (!RegListOp->isRegList())
2901 unsigned RlistEncode = RegListOp->RegList.Encoding;
2905 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||
2906 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {
2907 int64_t
Lower = StackAdjBase;
2908 int64_t
Upper = StackAdjBase + 48;
2909 if (ExpectNegative) {
2914 return generateImmOutOfRangeError(S,
Lower,
Upper,
2915 "stack adjustment for register list must "
2916 "be a multiple of 16 bytes in the range");
2920 Operands.
push_back(RISCVOperand::createStackAdj(StackAdj, S));
2928bool RISCVAsmParser::parseOperand(
OperandVector &Operands, StringRef Mnemonic) {
2932 MatchOperandParserImpl(Operands, Mnemonic,
true);
2939 if (parseRegister(Operands,
true).isSuccess())
2943 if (parseExpression(Operands).isSuccess()) {
2946 return !parseMemOpBaseReg(Operands).isSuccess();
2951 Error(getLoc(),
"unknown operand");
2955bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &
Info,
2956 StringRef Name, SMLoc NameLoc,
2962 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
2966 Operands.
push_back(RISCVOperand::createToken(Name, NameLoc));
2975 if (parseOperand(Operands, Name))
2981 if (parseOperand(Operands, Name))
2985 if (getParser().parseEOL(
"unexpected token")) {
2986 getParser().eatToEndOfStatement();
2992bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
2996 Kind = RE->getSpecifier();
2997 Expr = RE->getSubExpr();
3006bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
3015ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
3016 StringRef IDVal = DirectiveID.
getString();
3018 if (IDVal ==
".option")
3019 return parseDirectiveOption();
3020 if (IDVal ==
".attribute")
3021 return parseDirectiveAttribute();
3022 if (IDVal ==
".insn")
3023 return parseDirectiveInsn(DirectiveID.
getLoc());
3024 if (IDVal ==
".variant_cc")
3025 return parseDirectiveVariantCC();
3030bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
3031 bool FromOptionDirective) {
3034 clearFeatureBits(Feature.Value, Feature.Key);
3041 raw_string_ostream OutputErrMsg(Buffer);
3042 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3043 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
3044 << ErrMsg.getMessage();
3047 return Error(Loc, OutputErrMsg.str());
3049 auto &ISAInfo = *ParseResult;
3052 if (ISAInfo->hasExtension(Feature.Key))
3053 setFeatureBits(Feature.Value, Feature.Key);
3055 if (FromOptionDirective) {
3056 if (ISAInfo->getXLen() == 32 && isRV64())
3057 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3058 else if (ISAInfo->getXLen() == 64 && !isRV64())
3059 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3062 if (ISAInfo->getXLen() == 32)
3063 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
3064 else if (ISAInfo->getXLen() == 64)
3065 setFeatureBits(RISCV::Feature64Bit,
"64bit");
3067 return Error(Loc,
"bad arch string " + Arch);
3069 Result = ISAInfo->toString();
3073bool RISCVAsmParser::parseDirectiveOption() {
3074 MCAsmParser &Parser = getParser();
3076 AsmToken Tok = Parser.
getTok();
3084 if (Option ==
"push") {
3088 getTargetStreamer().emitDirectiveOptionPush();
3093 if (Option ==
"pop") {
3098 getTargetStreamer().emitDirectiveOptionPop();
3099 if (popFeatureBits())
3100 return Error(StartLoc,
".option pop with no .option push");
3105 if (Option ==
"arch") {
3113 Type = RISCVOptionArchArgType::Plus;
3115 Type = RISCVOptionArchArgType::Minus;
3116 else if (!
Args.empty())
3118 "unexpected token, expected + or -");
3120 Type = RISCVOptionArchArgType::Full;
3124 "unexpected token, expected identifier");
3130 if (
Type == RISCVOptionArchArgType::Full) {
3132 if (resetToArch(Arch, Loc, Result,
true))
3141 Loc,
"extension version number parsing not currently implemented");
3144 if (!enableExperimentalExtension() &&
3146 return Error(Loc,
"unexpected experimental extensions");
3149 return Error(Loc,
"unknown extension feature");
3153 if (
Type == RISCVOptionArchArgType::Plus) {
3156 setFeatureBits(
Ext->Value,
Ext->Key);
3159 copySTI().setFeatureBits(OldFeatureBits);
3160 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3163 raw_string_ostream OutputErrMsg(Buffer);
3164 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3165 OutputErrMsg << ErrMsg.getMessage();
3168 return Error(Loc, OutputErrMsg.str());
3171 assert(
Type == RISCVOptionArchArgType::Minus);
3176 if (getSTI().hasFeature(Feature.Value) &&
3177 Feature.Implies.test(
Ext->Value))
3178 return Error(Loc, Twine(
"can't disable ") +
Ext->Key +
3179 " extension; " + Feature.Key +
3180 " extension requires " +
Ext->Key +
3184 clearFeatureBits(
Ext->Value,
Ext->Key);
3191 getTargetStreamer().emitDirectiveOptionArch(Args);
3195 if (Option ==
"exact") {
3199 getTargetStreamer().emitDirectiveOptionExact();
3200 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3201 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3205 if (Option ==
"noexact") {
3209 getTargetStreamer().emitDirectiveOptionNoExact();
3210 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3211 setFeatureBits(RISCV::FeatureRelax,
"relax");
3215 if (Option ==
"rvc") {
3219 getTargetStreamer().emitDirectiveOptionRVC();
3220 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3224 if (Option ==
"norvc") {
3228 getTargetStreamer().emitDirectiveOptionNoRVC();
3229 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3230 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3234 if (Option ==
"pic") {
3238 getTargetStreamer().emitDirectiveOptionPIC();
3239 ParserOptions.IsPicEnabled =
true;
3243 if (Option ==
"nopic") {
3247 getTargetStreamer().emitDirectiveOptionNoPIC();
3248 ParserOptions.IsPicEnabled =
false;
3252 if (Option ==
"relax") {
3256 getTargetStreamer().emitDirectiveOptionRelax();
3257 setFeatureBits(RISCV::FeatureRelax,
"relax");
3261 if (Option ==
"norelax") {
3265 getTargetStreamer().emitDirectiveOptionNoRelax();
3266 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3272 "unknown option, expected 'push', 'pop', "
3273 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3274 "'exact', or 'noexact'");
3282bool RISCVAsmParser::parseDirectiveAttribute() {
3283 MCAsmParser &Parser = getParser();
3289 std::optional<unsigned>
Ret =
3292 return Error(TagLoc,
"attribute name not recognised: " + Name);
3296 const MCExpr *AttrExpr;
3303 if (check(!CE, TagLoc,
"expected numeric constant"))
3306 Tag =
CE->getValue();
3312 StringRef StringValue;
3313 int64_t IntegerValue = 0;
3314 bool IsIntegerValue =
true;
3319 IsIntegerValue =
false;
3322 if (IsIntegerValue) {
3323 const MCExpr *ValueExpr;
3329 return Error(ValueExprLoc,
"expected numeric constant");
3330 IntegerValue =
CE->getValue();
3343 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3345 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3348 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3352 getTargetStreamer().emitTextAttribute(
Tag, Result);
3360 .
Cases({
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s"},
true)
3361 .Cases({
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj"},
3363 .
Cases({
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es"},
3372bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3373 MCAsmParser &Parser = getParser();
3380 std::optional<int64_t>
Length;
3390 return Error(ErrorLoc,
3391 "instruction lengths must be a non-zero multiple of two");
3395 return Error(ErrorLoc,
3396 "instruction lengths over 64 bits are not supported");
3402 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3407 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3408 return Error(ErrorLoc,
3409 "instruction length does not match the encoding");
3412 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3415 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3418 if (!getSTI().hasFeature(RISCV::FeatureStdExtZca) &&
3419 (EncodingDerivedLength == 2))
3420 return Error(ErrorLoc,
"compressed instructions are not allowed");
3422 if (getParser().parseEOL(
"invalid operand for instruction")) {
3423 getParser().eatToEndOfStatement();
3431 Opcode = RISCV::Insn16;
3434 Opcode = RISCV::Insn32;
3437 Opcode = RISCV::Insn48;
3440 Opcode = RISCV::Insn64;
3446 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3448 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3453 return Error(ErrorLoc,
"invalid instruction format");
3455 std::string FormatName = (
".insn_" +
Format).str();
3457 ParseInstructionInfo
Info;
3460 if (parseInstruction(
Info, FormatName, L, Operands))
3465 return matchAndEmitInstruction(L, Opcode, Operands, Parser.
getStreamer(),
3472bool RISCVAsmParser::parseDirectiveVariantCC() {
3474 if (getParser().parseIdentifier(Name))
3475 return TokError(
"expected symbol name");
3478 getTargetStreamer().emitDirectiveVariantCC(
3483void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3486 const MCSubtargetInfo &STI = getSTI();
3487 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3490 ++RISCVNumInstrsCompressed;
3494void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3499 for (MCInst &Inst : Seq) {
3500 emitToStreamer(Out, Inst);
3504void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3505 const MCExpr *Symbol,
3507 unsigned SecondOpcode, SMLoc IDLoc,
3519 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3524 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3527 .addExpr(RefToLinkTmpLabel));
3530void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3540 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_PCREL_HI20,
3541 RISCV::ADDI, IDLoc, Out);
3544void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3554 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3555 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_GOT_HI20,
3556 SecondOpcode, IDLoc, Out);
3559void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3568 if (ParserOptions.IsPicEnabled)
3569 emitLoadGlobalAddress(Inst, IDLoc, Out);
3571 emitLoadLocalAddress(Inst, IDLoc, Out);
3574void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3584 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3585 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3586 SecondOpcode, IDLoc, Out);
3589void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3599 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3600 RISCV::ADDI, IDLoc, Out);
3603void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3604 SMLoc IDLoc, MCStreamer &Out,
3613 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3615 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3619 if (RISCVMCRegisterClasses[RISCV::GPRPairRegClassID].
contains(TmpReg)) {
3620 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3621 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3625 emitAuipcInstPair(DestReg, TmpReg, Symbol, ELF::R_RISCV_PCREL_HI20, Opcode,
3629void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3630 int64_t Width, SMLoc IDLoc,
3639 const MCOperand &DestReg = Inst.
getOperand(0);
3640 const MCOperand &SourceReg = Inst.
getOperand(1);
3642 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3643 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3645 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3647 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3652 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3658void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
3665 emitToStreamer(Out, MCInstBuilder(Opcode)
3669 .addReg(MCRegister())
3671 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
3682 "The destination register should not be V0.");
3683 emitToStreamer(Out, MCInstBuilder(Opcode)
3689 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
3701 "The destination register should be V0.");
3703 "The temporary vector register should not be V0.");
3704 emitToStreamer(Out, MCInstBuilder(Opcode)
3708 .addReg(MCRegister())
3710 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3722 "The temporary vector register should not be V0.");
3723 emitToStreamer(Out, MCInstBuilder(Opcode)
3727 .addReg(MCRegister())
3729 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3734 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
3739 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
3747bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
3749 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
3752 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
3753 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
3754 "%tprel_add specifier");
3760bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
3762 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
3765 SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
3766 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
3767 "%tlsdesc_call specifier");
3773std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
3774 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
3777std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
3778 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
3782std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
3783 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
3787bool RISCVAsmParser::validateInstruction(MCInst &Inst,
3791 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
3792 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
3795 if (DestReg == TempReg) {
3796 SMLoc Loc = Operands.
back()->getStartLoc();
3797 return Error(Loc,
"the temporary vector register cannot be the same as "
3798 "the destination register");
3802 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
3803 Opcode == RISCV::TH_LWD) {
3808 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
3809 SMLoc Loc = Operands[1]->getStartLoc();
3810 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
3814 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
3818 SMLoc Loc = Operands[1]->getStartLoc();
3819 return Error(Loc,
"rs1 and rs2 must be different");
3823 const MCInstrDesc &MCID = MII.
get(Opcode);
3827 if (Opcode == RISCV::SF_VC_V_XVW || Opcode == RISCV::SF_VC_V_IVW ||
3828 Opcode == RISCV::SF_VC_V_FVW || Opcode == RISCV::SF_VC_V_VVW) {
3831 SMLoc VCIXDstLoc = Operands[2]->getStartLoc();
3834 if (VCIXDst == VCIXRs1)
3835 return Error(VCIXDstLoc,
"the destination vector register group cannot"
3836 " overlap the source vector register group");
3840 if (VCIXDst == VCIXRs2)
3841 return Error(VCIXDstLoc,
"the destination vector register group cannot"
3842 " overlap the source vector register group");
3854 SMLoc Loc = Operands[1]->getStartLoc();
3857 if (DestReg == CheckReg)
3858 return Error(Loc,
"the destination vector register group cannot overlap"
3859 " the source vector register group");
3863 if (DestReg == CheckReg)
3864 return Error(Loc,
"the destination vector register group cannot overlap"
3865 " the source vector register group");
3870 if (Opcode == RISCV::VADC_VVM || Opcode == RISCV::VADC_VXM ||
3871 Opcode == RISCV::VADC_VIM || Opcode == RISCV::VSBC_VVM ||
3872 Opcode == RISCV::VSBC_VXM || Opcode == RISCV::VFMERGE_VFM ||
3873 Opcode == RISCV::VMERGE_VIM || Opcode == RISCV::VMERGE_VVM ||
3874 Opcode == RISCV::VMERGE_VXM)
3875 return Error(Loc,
"the destination vector register group cannot be V0");
3882 assert((CheckReg == RISCV::V0 || !CheckReg) &&
3883 "Unexpected register for mask operand");
3885 if (DestReg == CheckReg)
3886 return Error(Loc,
"the destination vector register group cannot overlap"
3887 " the mask register");
3892bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
3900 case RISCV::PseudoC_ADDI_NOP: {
3902 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
3908 case RISCV::PseudoLLAImm:
3909 case RISCV::PseudoLAImm:
3910 case RISCV::PseudoLI: {
3916 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
3928 emitLoadImm(
Reg, Imm, Out);
3931 case RISCV::PseudoLLA:
3932 emitLoadLocalAddress(Inst, IDLoc, Out);
3934 case RISCV::PseudoLGA:
3935 emitLoadGlobalAddress(Inst, IDLoc, Out);
3937 case RISCV::PseudoLA:
3938 emitLoadAddress(Inst, IDLoc, Out);
3940 case RISCV::PseudoLA_TLS_IE:
3941 emitLoadTLSIEAddress(Inst, IDLoc, Out);
3943 case RISCV::PseudoLA_TLS_GD:
3944 emitLoadTLSGDAddress(Inst, IDLoc, Out);
3946 case RISCV::PseudoLB:
3947 case RISCV::PseudoQC_E_LB:
3948 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
3950 case RISCV::PseudoLBU:
3951 case RISCV::PseudoQC_E_LBU:
3952 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
3954 case RISCV::PseudoLH:
3955 case RISCV::PseudoQC_E_LH:
3956 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
3958 case RISCV::PseudoLHU:
3959 case RISCV::PseudoQC_E_LHU:
3960 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
3962 case RISCV::PseudoLW:
3963 case RISCV::PseudoQC_E_LW:
3964 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
3966 case RISCV::PseudoLWU:
3967 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
3969 case RISCV::PseudoLD:
3970 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
3972 case RISCV::PseudoLD_RV32:
3973 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
3975 case RISCV::PseudoFLH:
3976 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
3978 case RISCV::PseudoFLW:
3979 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
3981 case RISCV::PseudoFLD:
3982 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
3984 case RISCV::PseudoFLQ:
3985 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
3987 case RISCV::PseudoSB:
3988 case RISCV::PseudoQC_E_SB:
3989 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
3991 case RISCV::PseudoSH:
3992 case RISCV::PseudoQC_E_SH:
3993 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
3995 case RISCV::PseudoSW:
3996 case RISCV::PseudoQC_E_SW:
3997 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
3999 case RISCV::PseudoSD:
4000 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
4002 case RISCV::PseudoSD_RV32:
4003 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
4005 case RISCV::PseudoFSH:
4006 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
4008 case RISCV::PseudoFSW:
4009 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
4011 case RISCV::PseudoFSD:
4012 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4014 case RISCV::PseudoFSQ:
4015 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4017 case RISCV::PseudoAddTPRel:
4018 if (checkPseudoAddTPRel(Inst, Operands))
4021 case RISCV::PseudoTLSDESCCall:
4022 if (checkPseudoTLSDESCCall(Inst, Operands))
4025 case RISCV::PseudoSEXT_B:
4026 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4028 case RISCV::PseudoSEXT_H:
4029 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4031 case RISCV::PseudoZEXT_H:
4032 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4034 case RISCV::PseudoZEXT_W:
4035 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4037 case RISCV::PseudoVMSGEU_VX:
4038 case RISCV::PseudoVMSGEU_VX_M:
4039 case RISCV::PseudoVMSGEU_VX_M_T:
4040 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4042 case RISCV::PseudoVMSGE_VX:
4043 case RISCV::PseudoVMSGE_VX_M:
4044 case RISCV::PseudoVMSGE_VX_M_T:
4045 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4047 case RISCV::PseudoVMSGE_VI:
4048 case RISCV::PseudoVMSLT_VI: {
4052 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4054 emitToStreamer(Out, MCInstBuilder(
Opc)
4062 case RISCV::PseudoVMSGEU_VI:
4063 case RISCV::PseudoVMSLTU_VI: {
4070 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4073 emitToStreamer(Out, MCInstBuilder(
Opc)
4081 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4084 emitToStreamer(Out, MCInstBuilder(
Opc)
4096 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")
Analysis containing CSE Info
static bool matchRegisterNameHelper(const MCSubtargetInfo &STI, MCRegister &Reg, StringRef Name)
#define LLVM_EXTERNAL_VISIBILITY
Promote Memory to Register
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
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 convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg, unsigned Kind)
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")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
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
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specified operand constraint if it is present.
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.
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.
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.
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
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)
@ CE
Windows NT (Windows on ARM)
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.