52#define DEBUG_TYPE "riscv-asm-parser"
55 "Number of RISC-V Compressed instructions emitted");
63struct ParserOptionsSet {
70 enum class VTypeState {
81 ParserOptionsSet ParserOptions;
83 SMLoc getLoc()
const {
return getParser().
getTok().
getLoc(); }
84 bool isRV64()
const {
return getSTI().hasFeature(RISCV::Feature64Bit); }
85 bool isRVE()
const {
return getSTI().hasFeature(RISCV::FeatureStdExtE); }
86 bool enableExperimentalExtension()
const {
87 return getSTI().hasFeature(RISCV::Experimental);
90 RISCVTargetStreamer &getTargetStreamer() {
91 assert(getParser().getStreamer().getTargetStreamer() &&
92 "do not have a target streamer");
93 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
94 return static_cast<RISCVTargetStreamer &
>(TS);
97 unsigned validateTargetOperandClass(MCParsedAsmOperand &
Op,
98 unsigned Kind)
override;
100 bool generateImmOutOfRangeError(SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
103 struct NearMissMessage {
108 std::string getCustomOperandDiag(
unsigned MatchError);
110 void FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
111 SmallVectorImpl<NearMissMessage> &NearMissesOut,
113 void ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses, SMLoc IDLoc,
116 bool matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
119 bool MatchingInlineAsm)
override;
122 bool parseRegister(MCRegister &
Reg, SMLoc &StartLoc, SMLoc &EndLoc)
override;
123 ParseStatus tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
124 SMLoc &EndLoc)
override;
126 bool parseInstruction(ParseInstructionInfo &Info, StringRef Name,
129 ParseStatus parseDirective(AsmToken DirectiveID)
override;
131 bool parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
unsigned &Sew,
132 unsigned &Lmul,
bool &Fractional,
bool &TailAgnostic,
133 bool &MaskAgnostic,
bool &AltFmt);
134 bool generateVTypeError(SMLoc ErrorLoc);
136 bool generateXSfmmVTypeError(SMLoc ErrorLoc);
139 void emitToStreamer(MCStreamer &S,
const MCInst &Inst);
143 void emitLoadImm(MCRegister DestReg, int64_t
Value, MCStreamer &Out);
147 void emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
149 unsigned SecondOpcode, SMLoc IDLoc, MCStreamer &Out);
152 void emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
155 void emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
158 void emitLoadAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
162 void emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
166 void emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
169 void emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
170 MCStreamer &Out,
bool HasTmpReg);
175 void emitQCELILoadStoreSymbol(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
176 MCStreamer &Out,
bool HasTmpReg);
179 void emitPseudoExtend(MCInst &Inst,
bool SignExtend, int64_t Width,
180 SMLoc IDLoc, MCStreamer &Out);
183 void emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc, MCStreamer &Out);
208#define GET_ASSEMBLER_HEADER
209#include "RISCVGenAsmMatcher.inc"
238 return parseRegList(
Operands,
true);
244 bool ExpectNegative =
false);
246 return parseZcmpStackAdj(
Operands,
true);
250 bool parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E);
251 bool parseDataExpr(
const MCExpr *&Res)
override;
253 bool parseDirectiveOption();
254 bool parseDirectiveAttribute();
255 bool parseDirectiveInsn(SMLoc L);
256 bool parseDirectiveVariantCC();
261 bool resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
262 bool FromOptionDirective);
264 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
266 MCSubtargetInfo &STI = copySTI();
272 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
276 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
278 MCSubtargetInfo &STI = copySTI();
279 setAvailableFeatures(
284 void pushFeatureBits() {
285 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
286 "These two stacks must be kept synchronized");
287 FeatureBitStack.push_back(getSTI().getFeatureBits());
288 ParserOptionsStack.push_back(ParserOptions);
291 bool popFeatureBits() {
292 assert(FeatureBitStack.size() == ParserOptionsStack.size() &&
293 "These two stacks must be kept synchronized");
294 if (FeatureBitStack.empty())
297 FeatureBitset FeatureBits = FeatureBitStack.pop_back_val();
298 copySTI().setFeatureBits(FeatureBits);
299 setAvailableFeatures(ComputeAvailableFeatures(FeatureBits));
301 ParserOptions = ParserOptionsStack.pop_back_val();
306 std::unique_ptr<RISCVOperand> defaultMaskRegOp()
const;
307 std::unique_ptr<RISCVOperand> defaultFRMArgOp()
const;
308 std::unique_ptr<RISCVOperand> defaultFRMArgLegacyOp()
const;
309 std::unique_ptr<RISCVOperand> defaultSMTVType();
310 std::unique_ptr<RISCVOperand> defaultZeroOffset();
313 enum RISCVMatchResultTy :
unsigned {
314 Match_Dummy = FIRST_TARGET_MATCH_RESULT_TY,
315#define GET_OPERAND_DIAGNOSTIC_TYPES
316#include "RISCVGenAsmMatcher.inc"
317#undef GET_OPERAND_DIAGNOSTIC_TYPES
321 static bool isSymbolDiff(
const MCExpr *Expr);
323 RISCVAsmParser(
const MCSubtargetInfo &STI, MCAsmParser &Parser,
324 const MCInstrInfo &MII)
325 : MCTargetAsmParser(STI, MII) {
332 setAvailableFeatures(ComputeAvailableFeatures(STI.
getFeatureBits()));
334 auto ABIName = StringRef(getTargetOptions().ABIName);
335 if (ABIName.ends_with(
"f") && !getSTI().
hasFeature(RISCV::FeatureStdExtF)) {
336 errs() <<
"Hard-float 'f' ABI can't be used for a target that "
337 "doesn't support the F instruction set extension (ignoring "
339 }
else if (ABIName.ends_with(
"d") &&
340 !getSTI().
hasFeature(RISCV::FeatureStdExtD)) {
341 errs() <<
"Hard-float 'd' ABI can't be used for a target that "
342 "doesn't support the D instruction set extension (ignoring "
354 getTargetStreamer().emitTargetAttributes(STI,
false);
425 MCRegister OffsetReg;
428 SMLoc StartLoc, EndLoc;
444 RISCVOperand(KindTy K) : Kind(
K) {}
447 RISCVOperand(
const RISCVOperand &o) : MCParsedAsmOperand() {
449 StartLoc =
o.StartLoc;
452 case KindTy::Register:
455 case KindTy::Expression:
458 case KindTy::FPImmediate:
464 case KindTy::SystemRegister:
470 case KindTy::SMTVType:
471 SMTVType =
o.SMTVType;
479 case KindTy::RegList:
482 case KindTy::StackAdj:
483 StackAdj =
o.StackAdj;
491 bool isToken()
const override {
return Kind == KindTy::Token; }
492 bool isReg()
const override {
return Kind == KindTy::Register; }
493 bool isExpr()
const {
return Kind == KindTy::Expression; }
494 bool isV0Reg()
const {
495 return Kind == KindTy::Register &&
Reg.Reg == RISCV::V0;
497 bool isAnyReg()
const {
498 return Kind == KindTy::Register &&
499 (getRISCVMCRegisterClass(RISCV::GPRRegClassID).contains(
Reg.Reg) ||
500 getRISCVMCRegisterClass(RISCV::FPR64RegClassID).contains(
Reg.Reg) ||
501 getRISCVMCRegisterClass(RISCV::VRRegClassID).contains(
Reg.Reg));
503 bool isAnyRegC()
const {
504 return Kind == KindTy::Register &&
505 (getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(
Reg.Reg) ||
506 getRISCVMCRegisterClass(RISCV::FPR64CRegClassID).contains(
Reg.Reg));
508 bool isImm()
const override {
return isExpr(); }
509 bool isMem()
const override {
return false; }
510 bool isSystemRegister()
const {
return Kind == KindTy::SystemRegister; }
511 bool isRegReg()
const {
return Kind == KindTy::RegReg; }
512 bool isRegList()
const {
return Kind == KindTy::RegList; }
513 bool isRegListS0()
const {
514 return Kind == KindTy::RegList && RegList.Encoding !=
RISCVZC::RA;
516 bool isStackAdj()
const {
return Kind == KindTy::StackAdj; }
519 return Kind == KindTy::Register &&
520 getRISCVMCRegisterClass(RISCV::GPRRegClassID).contains(
Reg.Reg);
523 bool isYGPR()
const {
524 return Kind == KindTy::Register &&
525 getRISCVMCRegisterClass(RISCV::YGPRRegClassID).contains(
Reg.Reg);
528 bool isGPRPair()
const {
529 return Kind == KindTy::Register &&
530 getRISCVMCRegisterClass(RISCV::GPRPairRegClassID).contains(
Reg.Reg);
533 bool isGPRPairC()
const {
534 return Kind == KindTy::Register &&
535 getRISCVMCRegisterClass(RISCV::GPRPairCRegClassID).contains(
Reg.Reg);
538 bool isGPRPairNoX0()
const {
539 return Kind == KindTy::Register &&
540 getRISCVMCRegisterClass(RISCV::GPRPairNoX0RegClassID)
544 bool isGPRF16()
const {
545 return Kind == KindTy::Register &&
546 getRISCVMCRegisterClass(RISCV::GPRF16RegClassID).contains(
Reg.Reg);
549 bool isGPRF32()
const {
550 return Kind == KindTy::Register &&
551 getRISCVMCRegisterClass(RISCV::GPRF32RegClassID).contains(
Reg.Reg);
554 bool isGPRAsFPR()
const {
return isGPR() &&
Reg.IsGPRAsFPR; }
555 bool isGPRAsFPR16()
const {
return isGPRF16() &&
Reg.IsGPRAsFPR; }
556 bool isGPRAsFPR32()
const {
return isGPRF32() &&
Reg.IsGPRAsFPR; }
557 bool isGPRPairAsFPR64()
const {
return isGPRPair() &&
Reg.IsGPRAsFPR; }
559 static bool evaluateConstantExpr(
const MCExpr *Expr, int64_t &Imm) {
561 Imm =
CE->getValue();
570 template <
int N>
bool isBareSimmNLsb0()
const {
575 if (evaluateConstantExpr(
getExpr(), Imm))
576 return isShiftedInt<
N - 1, 1>(fixImmediateForRV32(Imm, isRV64Expr()));
579 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
585 template <
int N>
bool isBareSimmN()
const {
590 if (evaluateConstantExpr(
getExpr(), Imm))
591 return isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
594 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
600 bool isBareSymbol()
const {
603 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
607 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
611 bool isCallSymbol()
const {
614 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
618 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
622 bool isPseudoJumpSymbol()
const {
625 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
629 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
633 bool isTPRelAddSymbol()
const {
636 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
640 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
641 VK == ELF::R_RISCV_TPREL_ADD;
644 bool isTLSDESCCallSymbol()
const {
647 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
651 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
652 VK == ELF::R_RISCV_TLSDESC_CALL;
655 bool isQCAccessSymbol()
const {
658 if (!isExpr() || evaluateConstantExpr(
getExpr(), Imm))
662 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
666 bool isCSRSystemRegister()
const {
return isSystemRegister(); }
670 bool isVTypeI10()
const {
671 if (Kind == KindTy::VType)
675 bool isVTypeI11()
const {
676 if (Kind == KindTy::VType)
681 bool isXSfmmVType()
const {
685 bool isTileLambda()
const {
686 return isUImmPred([](int64_t Imm) {
return Imm &&
isUInt<3>(Imm); });
691 bool isFenceArg()
const {
return Kind == KindTy::Fence; }
694 bool isFRMArg()
const {
return Kind == KindTy::FRM; }
695 bool isFRMArgLegacy()
const {
return Kind == KindTy::FRM; }
700 bool isSMTVType()
const {
701 return Kind == KindTy::SMTVType &&
705 bool isSMTI8()
const {
710 bool isLoadFPImm()
const {
713 if (Kind != KindTy::FPImmediate)
716 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
719 return Idx >= 0 && Idx != 1;
722 bool isImmXLenLI()
const {
728 if (evaluateConstantExpr(
getExpr(), Imm))
731 return RISCVAsmParser::isSymbolDiff(
getExpr());
734 bool isImmXLenLI_Restricted()
const {
738 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
740 return IsConstantImm &&
744 template <
unsigned N>
bool isUImm()
const {
748 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
752 template <
unsigned N,
unsigned S>
bool isUImmShifted()
const {
756 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
760 template <
class Pred>
bool isUImmPred(Pred p)
const {
764 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
765 return IsConstantImm &&
p(Imm);
768 bool isUImmLog2XLen()
const {
769 if (isExpr() && isRV64Expr())
774 bool isUImmLog2XLenNonZero()
const {
775 if (isExpr() && isRV64Expr())
776 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<6>(Imm); });
777 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<5>(Imm); });
780 bool isUImmLog2XLenHalf()
const {
781 if (isExpr() && isRV64Expr())
786 bool isUImm1()
const {
return isUImm<1>(); }
787 bool isUImm2()
const {
return isUImm<2>(); }
788 bool isUImm3()
const {
return isUImm<3>(); }
789 bool isUImm4()
const {
return isUImm<4>(); }
790 bool isUImm5()
const {
return isUImm<5>(); }
791 bool isUImm6()
const {
return isUImm<6>(); }
792 bool isUImm7()
const {
return isUImm<7>(); }
793 bool isUImm8()
const {
return isUImm<8>(); }
794 bool isUImm9()
const {
return isUImm<9>(); }
795 bool isUImm10()
const {
return isUImm<10>(); }
796 bool isUImm11()
const {
return isUImm<11>(); }
797 bool isUImm16()
const {
return isUImm<16>(); }
798 bool isUImm20()
const {
return isUImm<20>(); }
799 bool isUImm32()
const {
return isUImm<32>(); }
800 bool isUImm48()
const {
return isUImm<48>(); }
801 bool isUImm64()
const {
return isUImm<64>(); }
803 bool isUImm5NonZero()
const {
804 return isUImmPred([](int64_t Imm) {
return Imm != 0 &&
isUInt<5>(Imm); });
807 bool isUImm5GT3()
const {
808 return isUImmPred([](int64_t Imm) {
return isUInt<5>(Imm) &&
Imm > 3; });
811 bool isUImm4Plus1()
const {
813 [](int64_t Imm) {
return Imm > 0 &&
isUInt<4>(Imm - 1); });
816 bool isUImm5Plus1()
const {
818 [](int64_t Imm) {
return Imm > 0 &&
isUInt<5>(Imm - 1); });
821 bool isUImm6Plus1()
const {
823 [](int64_t Imm) {
return Imm > 0 &&
isUInt<6>(Imm - 1); });
826 bool isUImm5GE6Plus1()
const {
828 [](int64_t Imm) {
return Imm >= 6 &&
isUInt<5>(Imm - 1); });
831 bool isUImm5Slist()
const {
832 return isUImmPred([](int64_t Imm) {
833 return (Imm == 0) || (
Imm == 1) || (Imm == 2) || (
Imm == 4) ||
834 (Imm == 8) || (
Imm == 16) || (Imm == 15) || (
Imm == 31);
838 bool isUImm7EqXLen()
const {
840 [
this](int64_t Imm) {
return isRV64Expr() ?
Imm == 64 :
Imm == 32; });
843 bool isUImm8GE32()
const {
844 return isUImmPred([](int64_t Imm) {
return isUInt<8>(Imm) &&
Imm >= 32; });
847 bool isRnumArg()
const {
849 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(10); });
852 bool isRnumArg_0_7()
const {
854 [](int64_t Imm) {
return Imm >= INT64_C(0) &&
Imm <= INT64_C(7); });
857 bool isRnumArg_1_10()
const {
859 [](int64_t Imm) {
return Imm >= INT64_C(1) &&
Imm <= INT64_C(10); });
862 bool isRnumArg_2_14()
const {
864 [](int64_t Imm) {
return Imm >= INT64_C(2) &&
Imm <= INT64_C(14); });
867 template <
unsigned N>
bool isSImm()
const {
871 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
872 return IsConstantImm &&
isInt<N>(fixImmediateForRV32(Imm, isRV64Expr()));
875 bool isYBNDSWImm()
const {
880 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
884 template <
class Pred>
bool isSImmPred(Pred p)
const {
888 bool IsConstantImm = evaluateConstantExpr(
getExpr(), Imm);
889 return IsConstantImm &&
p(fixImmediateForRV32(Imm, isRV64Expr()));
892 bool isSImm5()
const {
return isSImm<5>(); }
893 bool isSImm6()
const {
return isSImm<6>(); }
894 bool isSImm10()
const {
return isSImm<10>(); }
895 bool isSImm11()
const {
return isSImm<11>(); }
896 bool isSImm12()
const {
return isSImm<12>(); }
897 bool isSImm16()
const {
return isSImm<16>(); }
898 bool isSImm26()
const {
return isSImm<26>(); }
900 bool isSImm5NonZero()
const {
901 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<5>(Imm); });
904 bool isSImm6NonZero()
const {
905 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<6>(Imm); });
908 bool isCLUIImm()
const {
909 return isUImmPred([](int64_t Imm) {
910 return (
isUInt<5>(Imm) && Imm != 0) || (
Imm >= 0xfffe0 &&
Imm <= 0xfffff);
914 bool isUImm2Lsb0()
const {
return isUImmShifted<1, 1>(); }
916 bool isUImm5Lsb0()
const {
return isUImmShifted<4, 1>(); }
918 bool isUImm6Lsb0()
const {
return isUImmShifted<5, 1>(); }
920 bool isUImm6Lsb000()
const {
return isUImmShifted<3, 3>(); }
922 bool isUImm7Lsb00()
const {
return isUImmShifted<5, 2>(); }
924 bool isUImm7Lsb000()
const {
return isUImmShifted<4, 3>(); }
926 bool isUImm8Lsb00()
const {
return isUImmShifted<6, 2>(); }
928 bool isUImm8Lsb000()
const {
return isUImmShifted<5, 3>(); }
930 bool isUImm9Lsb000()
const {
return isUImmShifted<6, 3>(); }
932 bool isUImm14Lsb00()
const {
return isUImmShifted<12, 2>(); }
934 bool isUImm10Lsb00NonZero()
const {
941 static int64_t fixImmediateForRV32(int64_t Imm,
bool IsRV64Imm) {
947 bool isSImm12LO()
const {
952 if (evaluateConstantExpr(
getExpr(), Imm))
953 return isInt<12>(fixImmediateForRV32(Imm, isRV64Expr()));
956 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
959 VK == ELF::R_RISCV_TLSDESC_ADD_LO12);
967 template <
bool (RISCVOperand::*Pred)() const>
968 DiagnosticPredicate isOptionalMemOffset()
const {
972 : DiagnosticPredicate::NearMatch;
975 bool isSImm12Lsb00000()
const {
979 bool isSImm10Lsb0000NonZero()
const {
984 bool isSImm16NonZero()
const {
985 return isSImmPred([](int64_t Imm) {
return Imm != 0 &&
isInt<16>(Imm); });
988 bool isUImm16NonZero()
const {
989 return isUImmPred([](int64_t Imm) {
return isUInt<16>(Imm) &&
Imm != 0; });
992 bool isSImm20LI()
const {
997 if (evaluateConstantExpr(
getExpr(), Imm))
998 return isInt<20>(fixImmediateForRV32(Imm, isRV64Expr()));
1001 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
1005 bool isSImm8PLI_B()
const {
return isSImm<8>() || isUImm<8>(); }
1006 bool isSImm10PLUI()
const {
return isSImm<10>() || isUImm<10>(); }
1008 bool isSImm10PLI_H()
const {
1009 return isSImm<10>() || isUImmPred([](int64_t Imm) {
1013 bool isSImm10PLI_W()
const {
1014 return isSImm<10>() || isUImmPred([](int64_t Imm) {
1019 bool isUImm20LUI()
const {
1024 if (evaluateConstantExpr(
getExpr(), Imm))
1028 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
1029 (VK == ELF::R_RISCV_HI20 || VK == ELF::R_RISCV_TPREL_HI20);
1032 bool isUImm20AUIPC()
const {
1037 if (evaluateConstantExpr(
getExpr(), Imm))
1041 return RISCVAsmParser::classifySymbolRef(
getExpr(), VK) &&
1043 VK == ELF::R_RISCV_TLS_GOT_HI20 || VK == ELF::R_RISCV_TLS_GD_HI20 ||
1044 VK == ELF::R_RISCV_TLSDESC_HI20);
1047 bool isImmZero()
const {
1048 return isUImmPred([](int64_t Imm) {
return 0 ==
Imm; });
1051 bool isImmThree()
const {
1052 return isUImmPred([](int64_t Imm) {
return 3 ==
Imm; });
1055 bool isImmFour()
const {
1056 return isUImmPred([](int64_t Imm) {
return 4 ==
Imm; });
1059 bool isImm5Zibi()
const {
1061 [](int64_t Imm) {
return (Imm != 0 &&
isUInt<5>(Imm)) ||
Imm == -1; });
1064 bool isSImm5Plus1()
const {
1069 bool isSImm18()
const {
1070 return isSImmPred([](int64_t Imm) {
return isInt<18>(Imm); });
1073 bool isSImm18Lsb0()
const {
1077 bool isSImm19Lsb00()
const {
1081 bool isSImm20Lsb000()
const {
1085 bool isSImm32Lsb0()
const {
1090 SMLoc getStartLoc()
const override {
return StartLoc; }
1092 SMLoc getEndLoc()
const override {
return EndLoc; }
1095 bool isRV64Expr()
const {
1096 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1100 MCRegister
getReg()
const override {
1101 assert(Kind == KindTy::Register &&
"Invalid type access!");
1105 StringRef getSysReg()
const {
1106 assert(Kind == KindTy::SystemRegister &&
"Invalid type access!");
1107 return StringRef(SysReg.Data, SysReg.Length);
1110 const MCExpr *
getExpr()
const {
1111 assert(Kind == KindTy::Expression &&
"Invalid type access!");
1115 uint64_t getFPConst()
const {
1116 assert(Kind == KindTy::FPImmediate &&
"Invalid type access!");
1121 assert(Kind == KindTy::Token &&
"Invalid type access!");
1125 unsigned getVType()
const {
1126 assert(Kind == KindTy::VType &&
"Invalid type access!");
1131 assert(Kind == KindTy::FRM &&
"Invalid type access!");
1135 unsigned getFence()
const {
1136 assert(Kind == KindTy::Fence &&
"Invalid type access!");
1141 assert(Kind == KindTy::SMTVType &&
"Invalid type access!");
1142 return SMTVType.SMTVType;
1145 void print(raw_ostream &OS,
const MCAsmInfo &MAI)
const override {
1154 case KindTy::Expression:
1157 OS <<
' ' << (Expr.IsRV64 ?
"rv64" :
"rv32") <<
'>';
1159 case KindTy::FPImmediate:
1160 OS <<
"<fpimm: " << FPImm.Val <<
">";
1162 case KindTy::Register:
1164 << (
Reg.IsGPRAsFPR ?
") GPRasFPR>" :
")>");
1169 case KindTy::SystemRegister:
1170 OS <<
"<sysreg: " << getSysReg() <<
" (" << SysReg.Encoding <<
")>";
1179 OS << roundingModeToString(getFRM());
1182 case KindTy::SMTVType:
1183 OS <<
"<smtvtype: ";
1184 OS << SMTVTypeModeToString(getSMTVType());
1192 case KindTy::RegList:
1197 case KindTy::StackAdj:
1198 OS <<
"<stackadj: ";
1202 case KindTy::RegReg:
1203 OS <<
"<RegReg: BaseReg " <<
RegName(
RegReg.BaseReg) <<
" OffsetReg "
1209 static std::unique_ptr<RISCVOperand> createToken(StringRef Str, SMLoc S) {
1210 auto Op = std::make_unique<RISCVOperand>(KindTy::Token);
1217 static std::unique_ptr<RISCVOperand>
1218 createReg(MCRegister
Reg, SMLoc S, SMLoc
E,
bool IsGPRAsFPR =
false) {
1219 auto Op = std::make_unique<RISCVOperand>(KindTy::Register);
1221 Op->Reg.IsGPRAsFPR = IsGPRAsFPR;
1227 static std::unique_ptr<RISCVOperand> createExpr(
const MCExpr *Val, SMLoc S,
1228 SMLoc
E,
bool IsRV64) {
1229 auto Op = std::make_unique<RISCVOperand>(KindTy::Expression);
1230 Op->Expr.Expr = Val;
1231 Op->Expr.IsRV64 = IsRV64;
1237 static std::unique_ptr<RISCVOperand> createFPImm(uint64_t Val, SMLoc S) {
1238 auto Op = std::make_unique<RISCVOperand>(KindTy::FPImmediate);
1239 Op->FPImm.Val = Val;
1245 static std::unique_ptr<RISCVOperand> createSysReg(StringRef Str, SMLoc S,
1246 unsigned Encoding) {
1247 auto Op = std::make_unique<RISCVOperand>(KindTy::SystemRegister);
1248 Op->SysReg.Data = Str.data();
1249 Op->SysReg.Length = Str.size();
1256 static std::unique_ptr<RISCVOperand>
1258 auto Op = std::make_unique<RISCVOperand>(KindTy::FRM);
1265 static std::unique_ptr<RISCVOperand>
1267 auto Op = std::make_unique<RISCVOperand>(KindTy::SMTVType);
1268 Op->SMTVType.SMTVType = VType;
1274 static std::unique_ptr<RISCVOperand> createFenceArg(
unsigned Val, SMLoc S) {
1275 auto Op = std::make_unique<RISCVOperand>(KindTy::Fence);
1276 Op->Fence.Val = Val;
1282 static std::unique_ptr<RISCVOperand> createVType(
unsigned VTypeI, SMLoc S) {
1283 auto Op = std::make_unique<RISCVOperand>(KindTy::VType);
1284 Op->VType.Val = VTypeI;
1290 static std::unique_ptr<RISCVOperand> createRegList(
unsigned RlistEncode,
1292 auto Op = std::make_unique<RISCVOperand>(KindTy::RegList);
1298 static std::unique_ptr<RISCVOperand>
1299 createRegReg(MCRegister BaseReg, MCRegister OffsetReg, SMLoc S) {
1300 auto Op = std::make_unique<RISCVOperand>(KindTy::RegReg);
1302 Op->RegReg.OffsetReg = OffsetReg;
1308 static std::unique_ptr<RISCVOperand> createStackAdj(
unsigned StackAdj, SMLoc S) {
1309 auto Op = std::make_unique<RISCVOperand>(KindTy::StackAdj);
1310 Op->StackAdj.Val = StackAdj;
1315 static void addExpr(MCInst &Inst,
const MCExpr *Expr,
bool IsRV64Imm) {
1316 assert(Expr &&
"Expr shouldn't be null!");
1318 bool IsConstant = evaluateConstantExpr(Expr, Imm);
1328 void addRegOperands(MCInst &Inst,
unsigned N)
const {
1329 assert(
N == 1 &&
"Invalid number of operands!");
1333 void addImmOperands(MCInst &Inst,
unsigned N)
const {
1334 assert(
N == 1 &&
"Invalid number of operands!");
1335 addExpr(Inst,
getExpr(), isRV64Expr());
1338 template <
unsigned Bits>
1339 void addSExtImmOperands(MCInst &Inst,
unsigned N)
const {
1340 assert(
N == 1 &&
"Invalid number of operands!");
1347 void addFPImmOperands(MCInst &Inst,
unsigned N)
const {
1348 assert(
N == 1 &&
"Invalid number of operands!");
1350 addExpr(Inst,
getExpr(), isRV64Expr());
1355 APFloat(APFloat::IEEEdouble(), APInt(64, getFPConst())));
1359 void addFenceArgOperands(MCInst &Inst,
unsigned N)
const {
1360 assert(
N == 1 &&
"Invalid number of operands!");
1364 void addCSRSystemRegisterOperands(MCInst &Inst,
unsigned N)
const {
1365 assert(
N == 1 &&
"Invalid number of operands!");
1372 void addVTypeIOperands(MCInst &Inst,
unsigned N)
const {
1373 assert(
N == 1 &&
"Invalid number of operands!");
1375 if (Kind == KindTy::Expression) {
1376 [[maybe_unused]]
bool IsConstantImm =
1377 evaluateConstantExpr(
getExpr(), Imm);
1378 assert(IsConstantImm &&
"Invalid VTypeI Operand!");
1385 void addRegListOperands(MCInst &Inst,
unsigned N)
const {
1386 assert(
N == 1 &&
"Invalid number of operands!");
1390 void addRegRegOperands(MCInst &Inst,
unsigned N)
const {
1391 assert(
N == 2 &&
"Invalid number of operands!");
1396 void addStackAdjOperands(MCInst &Inst,
unsigned N)
const {
1397 assert(
N == 1 &&
"Invalid number of operands!");
1401 void addFRMArgOperands(MCInst &Inst,
unsigned N)
const {
1402 assert(
N == 1 &&
"Invalid number of operands!");
1406 void addSMTVTypeOperand(MCInst &Inst,
unsigned N)
const {
1407 assert(
N == 1 &&
"Invalid number of operands!");
1413#define GET_REGISTER_MATCHER
1414#define GET_SUBTARGET_FEATURE_NAME
1415#define GET_MATCHER_IMPLEMENTATION
1416#define GET_MNEMONIC_SPELL_CHECKER
1417#include "RISCVGenAsmMatcher.inc"
1420 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1421 return Reg - RISCV::F0_D + RISCV::F0_H;
1425 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1426 return Reg - RISCV::F0_D + RISCV::F0_F;
1430 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1431 return Reg - RISCV::F0_D + RISCV::F0_Q;
1435 assert(
Reg >= RISCV::X0 &&
Reg <= RISCV::X31 &&
"Invalid register");
1436 return Reg - RISCV::X0 + RISCV::X0_Y;
1441 unsigned RegClassID;
1442 if (Kind == MCK_VRM2)
1443 RegClassID = RISCV::VRM2RegClassID;
1444 else if (Kind == MCK_VRM4)
1445 RegClassID = RISCV::VRM4RegClassID;
1446 else if (Kind == MCK_VRM8)
1447 RegClassID = RISCV::VRM8RegClassID;
1451 &getRISCVMCRegisterClass(RegClassID));
1455 assert(
Reg >= RISCV::F0_D &&
Reg <= RISCV::F31_D &&
"Invalid register");
1456 return Reg - RISCV::F0_D + RISCV::F0_Q2;
1461 RISCVOperand &
Op =
static_cast<RISCVOperand &
>(AsmOp);
1463 return Match_InvalidOperand;
1465 MCRegister
Reg =
Op.getReg();
1467 getRISCVMCRegisterClass(RISCV::FPR64RegClassID).contains(
Reg);
1469 getRISCVMCRegisterClass(RISCV::FPR64CRegClassID).contains(
Reg);
1470 bool IsRegVR = getRISCVMCRegisterClass(RISCV::VRRegClassID).contains(
Reg);
1472 if (
Op.isGPR() && Kind == MCK_YGPR) {
1475 return Match_Success;
1477 if (IsRegFPR64 && Kind == MCK_FPR256) {
1479 return Match_Success;
1481 if (IsRegFPR64 && Kind == MCK_FPR128) {
1483 return Match_Success;
1487 if ((IsRegFPR64 && Kind == MCK_FPR32) ||
1488 (IsRegFPR64C && Kind == MCK_FPR32C)) {
1490 return Match_Success;
1494 if (IsRegFPR64 && Kind == MCK_FPR16) {
1496 return Match_Success;
1498 if (Kind == MCK_GPRAsFPR16 &&
Op.isGPRAsFPR()) {
1499 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_H;
1500 return Match_Success;
1502 if (Kind == MCK_GPRAsFPR32 &&
Op.isGPRAsFPR()) {
1503 Op.Reg.Reg =
Reg - RISCV::X0 + RISCV::X0_W;
1504 return Match_Success;
1511 if (getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg) &&
1512 Kind == MCK_GPRF64AsFPR && STI->
hasFeature(RISCV::FeatureStdExtZdinx) &&
1514 return Match_Success;
1518 if (IsRegVR && (Kind == MCK_VRM2 || Kind == MCK_VRM4 || Kind == MCK_VRM8)) {
1521 return Match_InvalidOperand;
1522 return Match_Success;
1524 return Match_InvalidOperand;
1527bool RISCVAsmParser::generateImmOutOfRangeError(
1528 SMLoc ErrorLoc, int64_t
Lower, int64_t
Upper,
1529 const Twine &
Msg =
"immediate must be an integer in the range") {
1536std::string RISCVAsmParser::getCustomOperandDiag(
unsigned MatchError) {
1538 StringRef
Msg =
"immediate must be an integer in the range") {
1539 return (
Msg +
" [" + Twine(
Lower) +
", " + Twine(
Upper) +
"]").str();
1542 switch (MatchError) {
1546 if (
const char *Diag = getMatchKindDiag((RISCVMatchResultTy)MatchError))
1548 return std::string();
1549 case Match_InvalidImmXLenLI:
1551 return "operand must be a constant 64-bit integer";
1552 return Range(std::numeric_limits<int32_t>::min(),
1553 std::numeric_limits<uint32_t>::max());
1554 case Match_InvalidImmXLenLI_Restricted:
1556 return "operand either must be a constant 64-bit integer "
1557 "or a bare symbol name";
1558 return Range(std::numeric_limits<int32_t>::min(),
1559 std::numeric_limits<uint32_t>::max(),
1560 "operand either must be a bare symbol name or an immediate "
1561 "integer in the range");
1562 case Match_InvalidUImmLog2XLen:
1564 return Range(0, (1 << 6) - 1);
1565 return Range(0, (1 << 5) - 1);
1566 case Match_InvalidUImmLog2XLenNonZero:
1568 return Range(1, (1 << 6) - 1);
1569 return Range(1, (1 << 5) - 1);
1570 case Match_InvalidUImm1:
1571 return Range(0, (1 << 1) - 1);
1572 case Match_InvalidUImm2:
1573 return Range(0, (1 << 2) - 1);
1574 case Match_InvalidUImm2Lsb0:
1575 return Range(0, 2,
"immediate must be one of");
1576 case Match_InvalidUImm3:
1577 return Range(0, (1 << 3) - 1);
1578 case Match_InvalidUImm4:
1579 return Range(0, (1 << 4) - 1);
1580 case Match_InvalidUImm4Plus1:
1581 return Range(1, (1 << 4));
1582 case Match_InvalidUImm5:
1583 return Range(0, (1 << 5) - 1);
1584 case Match_InvalidUImm5NonZero:
1585 return Range(1, (1 << 5) - 1);
1586 case Match_InvalidUImm5GT3:
1587 return Range(4, (1 << 5) - 1);
1588 case Match_InvalidUImm5Plus1:
1589 return Range(1, (1 << 5));
1590 case Match_InvalidUImm5GE6Plus1:
1591 return Range(6, (1 << 5));
1592 case Match_InvalidUImm5Slist:
1593 return "immediate must be one of: 0, 1, 2, 4, 8, 15, 16, 31";
1594 case Match_InvalidUImm6:
1595 return Range(0, (1 << 6) - 1);
1596 case Match_InvalidUImm6Plus1:
1597 return Range(1, (1 << 6));
1598 case Match_InvalidUImm7:
1599 return Range(0, (1 << 7) - 1);
1600 case Match_InvalidUImm8:
1601 return Range(0, (1 << 8) - 1);
1602 case Match_InvalidUImm8GE32:
1603 return Range(32, (1 << 8) - 1);
1604 case Match_InvalidSImm5:
1605 return Range(-(1 << 4), (1 << 4) - 1);
1606 case Match_InvalidSImm5NonZero:
1607 return Range(-(1 << 4), (1 << 4) - 1,
1608 "immediate must be non-zero in the range");
1609 case Match_InvalidSImm6:
1610 return Range(-(1 << 5), (1 << 5) - 1);
1611 case Match_InvalidSImm6NonZero:
1612 return Range(-(1 << 5), (1 << 5) - 1,
1613 "immediate must be non-zero in the range");
1614 case Match_InvalidCLUIImm:
1615 return Range(1, (1 << 5) - 1,
"immediate must be in [0xfffe0, 0xfffff] or");
1616 case Match_InvalidUImm5Lsb0:
1617 return Range(0, (1 << 5) - 2,
1618 "immediate must be a multiple of 2 bytes in the range");
1619 case Match_InvalidUImm6Lsb0:
1620 return Range(0, (1 << 6) - 2,
1621 "immediate must be a multiple of 2 bytes in the range");
1622 case Match_InvalidUImm6Lsb000:
1623 return Range(0, (1 << 6) - 8,
1624 "immediate must be a multiple of 8 in the range");
1625 case Match_InvalidUImm7Lsb00:
1626 return Range(0, (1 << 7) - 4,
1627 "immediate must be a multiple of 4 bytes in the range");
1628 case Match_InvalidUImm8Lsb00:
1629 return Range(0, (1 << 8) - 4,
1630 "immediate must be a multiple of 4 bytes in the range");
1631 case Match_InvalidUImm8Lsb000:
1632 return Range(0, (1 << 8) - 8,
1633 "immediate must be a multiple of 8 bytes in the range");
1634 case Match_InvalidUImm9:
1635 return Range(0, (1 << 9) - 1,
"immediate offset must be in the range");
1636 case Match_InvalidBareSImm9Lsb0:
1637 return Range(-(1 << 8), (1 << 8) - 2,
1638 "immediate must be a multiple of 2 bytes in the range");
1639 case Match_InvalidUImm9Lsb000:
1640 return Range(0, (1 << 9) - 8,
1641 "immediate must be a multiple of 8 bytes in the range");
1642 case Match_InvalidSImm8PLI_B:
1643 return Range(-(1 << 7), (1 << 8) - 1);
1644 case Match_InvalidSImm10:
1645 case Match_InvalidSImm10PLI_H:
1646 case Match_InvalidSImm10PLI_W:
1647 return Range(-(1 << 9), (1 << 9) - 1);
1648 case Match_InvalidSImm10PLUI:
1649 return Range(-(1 << 9), (1 << 10) - 1);
1650 case Match_InvalidUImm10Lsb00NonZero:
1651 return Range(4, (1 << 10) - 4,
1652 "immediate must be a multiple of 4 bytes in the range");
1653 case Match_InvalidSImm10Lsb0000NonZero:
1655 -(1 << 9), (1 << 9) - 16,
1656 "immediate must be a multiple of 16 bytes and non-zero in the range");
1657 case Match_InvalidSImm11:
1658 return Range(-(1 << 10), (1 << 10) - 1);
1659 case Match_InvalidBareSImm11Lsb0:
1660 return Range(-(1 << 10), (1 << 10) - 2,
1661 "immediate must be a multiple of 2 bytes in the range");
1662 case Match_InvalidUImm10:
1663 return Range(0, (1 << 10) - 1);
1664 case Match_InvalidUImm11:
1665 return Range(0, (1 << 11) - 1);
1666 case Match_InvalidUImm14Lsb00:
1667 return Range(0, (1 << 14) - 4,
1668 "immediate must be a multiple of 4 bytes in the range");
1669 case Match_InvalidUImm16NonZero:
1670 return Range(1, (1 << 16) - 1);
1671 case Match_InvalidSImm12:
1672 return Range(-(1 << 11), (1 << 11) - 1);
1673 case Match_InvalidSImm12LO:
1674 return Range(-(1 << 11), (1 << 11) - 1,
1675 "operand must be a symbol with %lo/%pcrel_lo/%tprel_lo "
1676 "specifier or an integer in the range");
1677 case Match_InvalidBareSImm12Lsb0:
1678 return Range(-(1 << 11), (1 << 11) - 2,
1679 "immediate must be a multiple of 2 bytes in the range");
1680 case Match_InvalidSImm12Lsb00000:
1681 return Range(-(1 << 11), (1 << 11) - 32,
1682 "immediate must be a multiple of 32 bytes in the range");
1683 case Match_InvalidBareSImm13Lsb0:
1684 return Range(-(1 << 12), (1 << 12) - 2,
1685 "immediate must be a multiple of 2 bytes in the range");
1686 case Match_InvalidSImm16:
1687 return Range(-(1 << 15), (1 << 15) - 1);
1688 case Match_InvalidSImm16NonZero:
1689 return Range(-(1 << 15), (1 << 15) - 1,
1690 "immediate must be non-zero in the range");
1691 case Match_InvalidSImm20LI:
1692 return Range(-(1 << 19), (1 << 19) - 1,
1693 "operand must be a symbol with a %qc.abs20 specifier or an "
1694 "integer in the range");
1695 case Match_InvalidUImm20LUI:
1696 return Range(0, (1 << 20) - 1,
1697 "operand must be a symbol with %hi/%tprel_hi specifier or an "
1698 "integer in the range");
1699 case Match_InvalidUImm20:
1700 return Range(0, (1 << 20) - 1);
1701 case Match_InvalidUImm20AUIPC:
1704 "operand must be a symbol with a "
1705 "%pcrel_hi/%got_pcrel_hi/%tls_ie_pcrel_hi/%tls_gd_pcrel_hi specifier "
1706 "or an integer in the range");
1707 case Match_InvalidBareSImm21Lsb0:
1708 return Range(-(1 << 20), (1 << 20) - 2,
1709 "immediate must be a multiple of 2 bytes in the range");
1710 case Match_InvalidCSRSystemRegister:
1711 return Range(0, (1 << 12) - 1,
1712 "operand must be a valid system register name or an integer "
1714 case Match_InvalidImm5Zibi:
1715 return Range(-1, (1 << 5) - 1,
"immediate must be non-zero in the range");
1716 case Match_InvalidVTypeI:
1717 return "operand must be "
1718 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]";
1719 case Match_InvalidSImm5Plus1:
1720 return Range(-(1 << 4) + 1, (1 << 4),
"immediate must be in the range");
1721 case Match_InvalidSImm18:
1722 return Range(-(1 << 17), (1 << 17) - 1);
1723 case Match_InvalidSImm18Lsb0:
1724 return Range(-(1 << 17), (1 << 17) - 2,
1725 "immediate must be a multiple of 2 bytes in the range");
1726 case Match_InvalidSImm19Lsb00:
1727 return Range(-(1 << 18), (1 << 18) - 4,
1728 "immediate must be a multiple of 4 bytes in the range");
1729 case Match_InvalidSImm20Lsb000:
1730 return Range(-(1 << 19), (1 << 19) - 8,
1731 "immediate must be a multiple of 8 bytes in the range");
1732 case Match_InvalidSImm26:
1733 return Range(-(1 << 25), (1 << 25) - 1);
1735 case Match_InvalidBareSymbolQC_E_LI:
1738 case Match_InvalidBareSImm32:
1739 return Range(std::numeric_limits<int32_t>::min(),
1740 std::numeric_limits<uint32_t>::max());
1741 case Match_InvalidBareSImm32Lsb0:
1742 return Range(std::numeric_limits<int32_t>::min(),
1743 std::numeric_limits<int32_t>::max() - 1,
1744 "operand must be a multiple of 2 bytes in the range");
1745 case Match_InvalidRnumArg:
1746 return Range(0, 10);
1747 case Match_InvalidStackAdj:
1748 return "stack adjustment is invalid for this instruction and register "
1750 case Match_InvalidYBNDSWImm:
1751 return "immediate must be an integer in the range "
1752 "[1, 255], a multiple of 8 in the range [256, 504], "
1753 "or a multiple of 16 in the range [512, 4096]";
1754 case Match_InvalidUImm7EqXLen:
1755 return (
"immediate must be an integer equal to XLEN (" +
1756 Twine(isRV64() ?
"64" :
"32") +
")")
1764void RISCVAsmParser::FilterNearMisses(
1765 SmallVectorImpl<NearMissInfo> &NearMissesIn,
1766 SmallVectorImpl<NearMissMessage> &NearMissesOut, SMLoc IDLoc,
1770 std::multimap<unsigned, unsigned> OperandMissesSeen;
1771 SmallSet<FeatureBitset, 4> FeatureMissesSeen;
1772 bool ReportedTooFewOperands =
false;
1773 bool ReportedTooManyOperands =
false;
1775 for (NearMissInfo &
I : NearMissesIn) {
1776 switch (
I.getKind()) {
1779 ((RISCVOperand &)*
Operands[
I.getOperandIndex()]).getStartLoc();
1784 if (
I.getOperandClass() == InvalidMatchClass) {
1785 if (!ReportedTooManyOperands) {
1787 OperandLoc,
"unexpected extra operand for instruction"});
1788 ReportedTooManyOperands =
true;
1793 std::string OperandDiag = getCustomOperandDiag(
I.getOperandError());
1797 unsigned DupCheckMatchClass =
1798 OperandDiag.empty() ? ~0
U :
I.getOperandClass();
1799 auto PrevReports = OperandMissesSeen.equal_range(
I.getOperandIndex());
1801 PrevReports.first, PrevReports.second,
1802 [DupCheckMatchClass](
const std::pair<unsigned, unsigned> Pair) {
1803 if (DupCheckMatchClass == ~0U || Pair.second == ~0U)
1804 return Pair.second == DupCheckMatchClass;
1805 return isSubclass((MatchClassKind)DupCheckMatchClass,
1806 (MatchClassKind)Pair.second);
1809 OperandMissesSeen.insert(
1810 std::make_pair(
I.getOperandIndex(), DupCheckMatchClass));
1812 NearMissMessage Message;
1813 Message.Loc = OperandLoc;
1814 if (!OperandDiag.empty()) {
1815 Message.Message = OperandDiag;
1817 Message.Message =
"invalid operand for instruction";
1819 dbgs() <<
"Missing diagnostic string for operand class "
1820 << getMatchClassName((MatchClassKind)
I.getOperandClass())
1821 <<
I.getOperandClass() <<
", error " <<
I.getOperandError()
1822 <<
", opcode " << MII.
getName(
I.getOpcode()) <<
"\n");
1828 const FeatureBitset &MissingFeatures =
I.getFeatures();
1830 if (!FeatureMissesSeen.
insert(MissingFeatures).second)
1833 NearMissMessage Message;
1834 Message.Loc = IDLoc;
1835 bool FirstFeature =
true;
1836 Message.Message =
"instruction requires the following:";
1837 for (
unsigned Feature : MissingFeatures) {
1838 Message.Message += FirstFeature ?
" " :
", ";
1840 FirstFeature =
false;
1850 if (!ReportedTooFewOperands) {
1851 SMLoc EndLoc = ((RISCVOperand &)*
Operands.back()).getEndLoc();
1853 NearMissMessage{EndLoc,
"too few operands for instruction"});
1854 ReportedTooFewOperands =
true;
1866void RISCVAsmParser::ReportNearMisses(SmallVectorImpl<NearMissInfo> &NearMisses,
1869 FilterNearMisses(NearMisses, Messages, IDLoc,
Operands);
1874 Error(IDLoc,
"invalid instruction");
1877 Error(Messages[0].Loc, Messages[0].Message);
1882 "invalid instruction, any one of the following would fix this:");
1883 for (
auto &M : Messages)
1888bool RISCVAsmParser::matchAndEmitInstruction(SMLoc IDLoc,
unsigned &Opcode,
1891 uint64_t &ErrorInfo,
1892 bool MatchingInlineAsm) {
1897 MatchInstructionImpl(
Operands, Inst, &NearMisses, MatchingInlineAsm);
1902 if (validateInstruction(Inst,
Operands))
1904 return processInstruction(Inst, IDLoc,
Operands, Out);
1905 case Match_MnemonicFail: {
1906 FeatureBitset FBS = ComputeAvailableFeatures(getSTI().getFeatureBits());
1907 std::string Suggestion = RISCVMnemonicSpellCheck(
1909 return Error(IDLoc,
"unrecognized instruction mnemonic" + Suggestion);
1911 case Match_NearMisses:
1912 ReportNearMisses(NearMisses, IDLoc,
Operands);
1923MCRegister RISCVAsmParser::matchRegisterNameHelper(StringRef Name)
const {
1932 static_assert(RISCV::F0_D < RISCV::F0_H,
"FPR matching must be updated");
1933 static_assert(RISCV::F0_D < RISCV::F0_F,
"FPR matching must be updated");
1934 static_assert(RISCV::F0_D < RISCV::F0_Q,
"FPR matching must be updated");
1937 if (isRVE() &&
Reg >= RISCV::X16 &&
Reg <= RISCV::X31)
1942bool RISCVAsmParser::parseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1944 if (!tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess())
1945 return Error(StartLoc,
"invalid register name");
1949ParseStatus RISCVAsmParser::tryParseRegister(MCRegister &
Reg, SMLoc &StartLoc,
1951 const AsmToken &Tok = getParser().getTok();
1954 StringRef
Name = getLexer().getTok().getIdentifier();
1966 SMLoc FirstS = getLoc();
1967 bool HadParens =
false;
1974 size_t ReadCount = getLexer().peekTokens(Buf);
1977 LParen = getParser().getTok();
1982 switch (getLexer().getKind()) {
1985 getLexer().UnLex(LParen);
1988 StringRef
Name = getLexer().getTok().getIdentifier();
1993 getLexer().UnLex(LParen);
1997 Operands.push_back(RISCVOperand::createToken(
"(", FirstS));
1999 SMLoc
E = getTok().getEndLoc();
2001 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2006 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2017 switch (getLexer().getKind()) {
2027 if (getParser().parseExpression(Res,
E))
2032 int64_t
Imm =
CE->getValue();
2034 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2043 if (getParser().parseIdentifier(Identifier))
2046 auto Opcode = RISCVInsnOpcode::lookupRISCVOpcodeByName(Identifier);
2049 "Unexpected opcode");
2052 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2062 return generateImmOutOfRangeError(
2064 "opcode must be a valid opcode name or an immediate in the range");
2072 switch (getLexer().getKind()) {
2082 if (getParser().parseExpression(Res,
E))
2087 int64_t
Imm =
CE->getValue();
2088 if (Imm >= 0 && Imm <= 2) {
2089 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2098 if (getParser().parseIdentifier(Identifier))
2102 if (Identifier ==
"C0")
2104 else if (Identifier ==
"C1")
2106 else if (Identifier ==
"C2")
2113 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2122 return generateImmOutOfRangeError(
2124 "opcode must be a valid opcode name or an immediate in the range");
2131 auto SysRegFromConstantInt = [
this](
const MCExpr *
E, SMLoc S) {
2133 int64_t
Imm =
CE->getValue();
2135 auto Range = RISCVSysReg::lookupSysRegByEncoding(Imm);
2139 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2142 return RISCVOperand::createSysReg(
2143 RISCVSysReg::getSysRegStr(
Reg.Name), S, Imm);
2147 return RISCVOperand::createSysReg(
"", S, Imm);
2150 return std::unique_ptr<RISCVOperand>();
2153 switch (getLexer().getKind()) {
2163 if (getParser().parseExpression(Res))
2166 if (
auto SysOpnd = SysRegFromConstantInt(Res, S)) {
2167 Operands.push_back(std::move(SysOpnd));
2171 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2175 if (getParser().parseIdentifier(Identifier))
2178 const auto *SysReg = RISCVSysReg::lookupSysRegByName(Identifier);
2181 if (SysReg->IsDeprecatedName) {
2183 auto Range = RISCVSysReg::lookupSysRegByEncoding(SysReg->Encoding);
2185 if (
Reg.IsAltName ||
Reg.IsDeprecatedName)
2187 Warning(S,
"'" + Identifier +
"' is a deprecated alias for '" +
2188 RISCVSysReg::getSysRegStr(
Reg.Name) +
"'");
2193 const auto &FeatureBits = getSTI().getFeatureBits();
2194 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
2195 if (!SysReg->haveRequiredFeatures(FeatureBits)) {
2196 const auto *Feature =
2198 return SysReg->FeaturesRequired[Feature.Value];
2200 std::string ErrorMsg =
2201 std::string(
"system register '") +
2202 std::string(RISCVSysReg::getSysRegStr(SysReg->Name)) +
"' ";
2203 if (SysReg->IsRV32Only && FeatureBits[RISCV::Feature64Bit]) {
2204 ErrorMsg +=
"is RV32 only";
2206 ErrorMsg +=
" and ";
2210 "requires '" + std::string(Feature->key()) +
"' to be enabled";
2213 return Error(S, ErrorMsg);
2216 RISCVOperand::createSysReg(Identifier, S, SysReg->Encoding));
2226 Operands.push_back(std::move(SysOpnd));
2231 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1,
2232 "operand must be a valid system register "
2233 "name or an integer in the range");
2237 return generateImmOutOfRangeError(S, 0, (1 << 12) - 1);
2249 StringRef
Identifier = getTok().getIdentifier();
2250 if (
Identifier.compare_insensitive(
"inf") == 0) {
2253 getTok().getEndLoc(), isRV64()));
2254 }
else if (
Identifier.compare_insensitive(
"nan") == 0) {
2257 getTok().getEndLoc(), isRV64()));
2258 }
else if (
Identifier.compare_insensitive(
"min") == 0) {
2261 getTok().getEndLoc(), isRV64()));
2263 return TokError(
"invalid floating point literal");
2274 const AsmToken &Tok = getTok();
2276 return TokError(
"invalid floating point immediate");
2279 APFloat RealVal(APFloat::IEEEdouble());
2281 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
2283 return TokError(
"invalid floating point representation");
2286 RealVal.changeSign();
2288 Operands.push_back(RISCVOperand::createFPImm(
2289 RealVal.bitcastToAPInt().getZExtValue(), S));
2301 switch (getLexer().getKind()) {
2313 if (getParser().parseExpression(Res,
E))
2317 return parseOperandWithSpecifier(
Operands);
2320 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2330 const MCExpr *Expr =
nullptr;
2331 bool Failed = parseExprWithSpecifier(Expr,
E);
2333 Operands.push_back(RISCVOperand::createExpr(Expr, S,
E, isRV64()));
2337bool RISCVAsmParser::parseExprWithSpecifier(
const MCExpr *&Res, SMLoc &
E) {
2338 SMLoc Loc = getLoc();
2340 return TokError(
"expected '%' relocation specifier");
2341 StringRef
Identifier = getParser().getTok().getIdentifier();
2344 return TokError(
"invalid relocation specifier");
2350 const MCExpr *SubExpr;
2351 if (getParser().parseParenExpression(SubExpr,
E))
2358bool RISCVAsmParser::parseDataExpr(
const MCExpr *&Res) {
2361 return parseExprWithSpecifier(Res,
E);
2362 return getParser().parseExpression(Res);
2372 StringRef
Identifier = getTok().getIdentifier();
2382 if (getParser().parseExpression(Res,
E))
2385 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2395 std::string
Identifier(getTok().getIdentifier());
2401 SMLoc Loc = getLoc();
2402 if (getParser().parseIdentifier(PLT) || PLT !=
"plt")
2403 return Error(Loc,
"@ (except the deprecated/ignored @plt) is disallowed");
2417 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2426 if (getParser().parseExpression(Res,
E))
2429 if (Res->
getKind() != MCExpr::ExprKind::SymbolRef)
2430 return Error(S,
"operand must be a valid jump target");
2433 Operands.push_back(RISCVOperand::createExpr(Res, S,
E, isRV64()));
2454bool RISCVAsmParser::parseVTypeToken(
const AsmToken &Tok, VTypeState &State,
2455 unsigned &Sew,
unsigned &Lmul,
2456 bool &Fractional,
bool &TailAgnostic,
2457 bool &MaskAgnostic,
bool &AltFmt) {
2462 if (State < VTypeState::SeenSew &&
Identifier.consume_front(
"e")) {
2464 if (Identifier ==
"16alt") {
2467 }
else if (Identifier ==
"8alt") {
2477 State = VTypeState::SeenSew;
2481 if (State < VTypeState::SeenLmul &&
Identifier.consume_front(
"m")) {
2484 if (Identifier ==
"a" || Identifier ==
"u") {
2486 State = VTypeState::SeenMaskPolicy;
2497 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2498 unsigned MinLMUL = ELEN / 8;
2501 "use of vtype encodings with LMUL < SEWMIN/ELEN == mf" +
2502 Twine(MinLMUL) +
" is reserved");
2505 State = VTypeState::SeenLmul;
2509 if (State < VTypeState::SeenTailPolicy &&
Identifier.starts_with(
"t")) {
2510 if (Identifier ==
"ta")
2511 TailAgnostic =
true;
2512 else if (Identifier ==
"tu")
2513 TailAgnostic =
false;
2517 State = VTypeState::SeenTailPolicy;
2521 if (State < VTypeState::SeenMaskPolicy &&
Identifier.starts_with(
"m")) {
2522 if (Identifier ==
"ma")
2523 MaskAgnostic =
true;
2524 else if (Identifier ==
"mu")
2525 MaskAgnostic =
false;
2529 State = VTypeState::SeenMaskPolicy;
2542 bool Fractional =
false;
2543 bool TailAgnostic =
false;
2544 bool MaskAgnostic =
false;
2547 VTypeState State = VTypeState::SeenNothingYet;
2549 if (parseVTypeToken(getTok(), State, Sew, Lmul, Fractional, TailAgnostic,
2550 MaskAgnostic, AltFmt)) {
2552 if (State == VTypeState::SeenNothingYet)
2561 State == VTypeState::SeenNothingYet)
2562 return generateVTypeError(S);
2566 unsigned ELEN = STI->
hasFeature(RISCV::FeatureStdExtZve64x) ? 64 : 32;
2567 unsigned MaxSEW = ELEN / Lmul;
2569 if (MaxSEW >= 8 && Sew > MaxSEW)
2570 Warning(S,
"use of vtype encodings with SEW > " + Twine(MaxSEW) +
2571 " and LMUL == mf" + Twine(Lmul) +
2572 " may not be compatible with all RVV implementations");
2577 Operands.push_back(RISCVOperand::createVType(VTypeI, S));
2581bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) {
2582 return Error(ErrorLoc,
2584 "e[8|8alt|16|16alt|32|64],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]");
2604 if (Identifier !=
"16alt")
2633 Operands.push_back(RISCVOperand::createVType(
2639 return generateXSfmmVTypeError(S);
2642bool RISCVAsmParser::generateXSfmmVTypeError(SMLoc ErrorLoc) {
2643 return Error(ErrorLoc,
"operand must be e[8|16|16alt|32|64],w[1|2|4]");
2650 StringRef
Name = getLexer().getTok().getIdentifier();
2651 if (!
Name.consume_back(
".t")) {
2655 return Error(getLoc(),
"expected '.t' suffix");
2662 if (
Reg != RISCV::V0)
2665 SMLoc
E = getTok().getEndLoc();
2667 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2675 StringRef
Name = getLexer().getTok().getIdentifier();
2676 if (!
Name.consume_back(
".scale"))
2677 return Error(getLoc(),
"expected '.scale' suffix");
2682 if (
Reg != RISCV::V0)
2685 SMLoc
E = getTok().getEndLoc();
2687 Operands.push_back(RISCVOperand::createReg(
Reg, S,
E));
2696 StringRef
Name = getLexer().getTok().getIdentifier();
2697 if (!
Name.consume_front(
"L") && !
Name.consume_front(
"l"))
2702 return Error(S,
"operand must be L1, L2, L4, L8, L16, L32, or L64");
2704 unsigned EncodedLambda =
Log2_32(Lambda) + 1;
2706 SMLoc
E = getTok().getEndLoc();
2708 Operands.push_back(RISCVOperand::createExpr(
2714 if (!isRV64() || getSTI().
hasFeature(RISCV::FeatureStdExtF))
2724 StringRef
Name = getLexer().getTok().getIdentifier();
2730 SMLoc
E = getTok().getEndLoc();
2732 Operands.push_back(RISCVOperand::createReg(
2738 if (isRV64() || getSTI().
hasFeature(RISCV::FeatureStdExtF))
2744 StringRef
Name = getLexer().getTok().getIdentifier();
2750 if (!getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg))
2753 if ((
Reg - RISCV::X0) & 1) {
2756 if (getSTI().
hasFeature(RISCV::FeatureStdExtZfinx))
2757 return TokError(
"double precision floating point operands must use even "
2758 "numbered X register");
2763 SMLoc
E = getTok().getEndLoc();
2766 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2768 Reg, RISCV::sub_gpr_even,
2769 &getRISCVMCRegisterClass(RISCV::GPRPairRegClassID));
2770 Operands.push_back(RISCVOperand::createReg(Pair, S,
E,
true));
2774template <
bool IsRV64>
2776 return parseGPRPair(
Operands, IsRV64);
2786 if (!IsRV64Inst && isRV64())
2792 StringRef
Name = getLexer().getTok().getIdentifier();
2798 if (!getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(
Reg))
2801 if ((
Reg - RISCV::X0) & 1)
2802 return TokError(
"register must be even");
2805 SMLoc
E = getTok().getEndLoc();
2808 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
2810 Reg, RISCV::sub_gpr_even,
2811 &getRISCVMCRegisterClass(RISCV::GPRPairRegClassID));
2812 Operands.push_back(RISCVOperand::createReg(Pair, S,
E));
2819 "operand must be a valid SpacemiT's Integer Matrix VType mnemonic");
2821 StringRef Str = getLexer().getTok().getIdentifier();
2824 if (!isValidSMTVTypeMode(VType))
2825 return TokError(
"SpacemiT's Integer Matrix only supports [i4|i8] mode");
2827 Operands.push_back(RISCVOperand::createSMTVType(VType, getLoc()));
2835 "operand must be a valid floating point rounding mode mnemonic");
2837 StringRef Str = getLexer().getTok().getIdentifier();
2842 "operand must be a valid floating point rounding mode mnemonic");
2844 Operands.push_back(RISCVOperand::createFRMArg(FRM, getLoc()));
2849std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultSMTVType() {
2850 return RISCVOperand::createSMTVType(XSMTVTypeMode::SMTVTypeMode::SMT_I8,
2855 const AsmToken &Tok = getLexer().getTok();
2861 Operands.push_back(RISCVOperand::createFenceArg(0, getLoc()));
2875 for (
char c : Str) {
2904 Operands.push_back(RISCVOperand::createFenceArg(Imm, getLoc()));
2910 return TokError(
"operand must be formed of letters selected in-order from "
2917 Operands.push_back(RISCVOperand::createToken(
"(", getLoc()));
2919 if (!parseRegister(
Operands).isSuccess())
2920 return Error(getLoc(),
"expected register");
2924 Operands.push_back(RISCVOperand::createToken(
")", getLoc()));
2948 std::unique_ptr<RISCVOperand> OptionalImmOp;
2955 SMLoc ImmStart = getLoc();
2956 if (getParser().parseIntToken(ImmVal,
2957 "expected '(' or optional integer offset"))
2962 SMLoc ImmEnd = getLoc();
2965 ImmStart, ImmEnd, isRV64());
2969 OptionalImmOp ?
"expected '(' after optional integer offset"
2970 :
"expected '(' or optional integer offset"))
2973 if (!parseRegister(
Operands).isSuccess())
2974 return Error(getLoc(),
"expected register");
2980 if (OptionalImmOp && !OptionalImmOp->isImmZero())
2982 OptionalImmOp->getStartLoc(),
"optional integer offset must be 0",
2983 SMRange(OptionalImmOp->getStartLoc(), OptionalImmOp->getEndLoc()));
2994 StringRef OffsetRegName = getLexer().getTok().getIdentifier();
2997 !getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(OffsetReg))
2998 return Error(getLoc(),
"expected GPR register");
3005 return Error(getLoc(),
"expected GPR register");
3007 StringRef BaseRegName = getLexer().getTok().getIdentifier();
3010 !getRISCVMCRegisterClass(RISCV::GPRRegClassID).
contains(BaseReg))
3011 return Error(getLoc(),
"expected GPR register");
3017 Operands.push_back(RISCVOperand::createRegReg(BaseReg, OffsetReg, S));
3030 bool MustIncludeS0) {
3042 return Error(getLoc(),
"invalid register");
3044 StringRef
RegName = getTok().getIdentifier();
3047 return Error(getLoc(),
"invalid register");
3050 UsesXRegs =
RegName[0] ==
'x';
3051 if (
Reg != RISCV::X1)
3052 return Error(getLoc(),
"register list must start from 'ra' or 'x1'");
3053 }
else if (RegEnd == RISCV::X1) {
3054 if (
Reg != RISCV::X8 || (UsesXRegs != (
RegName[0] ==
'x')))
3055 return Error(getLoc(), Twine(
"register must be '") +
3056 (UsesXRegs ?
"x8" :
"s0") +
"'");
3057 }
else if (RegEnd == RISCV::X9 && UsesXRegs) {
3058 if (
Reg != RISCV::X18 || (
RegName[0] !=
'x'))
3059 return Error(getLoc(),
"register must be 'x18'");
3061 return Error(getLoc(),
"too many register ranges");
3068 SMLoc MinusLoc = getLoc();
3070 if (RegEnd == RISCV::X1)
3071 return Error(MinusLoc, Twine(
"register '") + (UsesXRegs ?
"x1" :
"ra") +
3072 "' cannot start a multiple register range");
3075 return Error(getLoc(),
"invalid register");
3077 StringRef
RegName = getTok().getIdentifier();
3080 return Error(getLoc(),
"invalid register");
3082 if (RegEnd == RISCV::X8) {
3083 if ((
Reg != RISCV::X9 &&
3085 (UsesXRegs != (
RegName[0] ==
'x'))) {
3087 return Error(getLoc(),
"register must be 'x9'");
3088 return Error(getLoc(),
"register must be in the range 's1' to 's11'");
3090 }
else if (RegEnd == RISCV::X18) {
3092 return Error(getLoc(),
3093 "register must be in the range 'x19' to 'x27'");
3106 if (RegEnd == RISCV::X26)
3107 return Error(S,
"invalid register list, '{ra, s0-s10}' or '{x1, x8-x9, "
3108 "x18-x26}' is not supported");
3114 return Error(S,
"register list must include 's0' or 'x8'");
3116 Operands.push_back(RISCVOperand::createRegList(Encode, S));
3122 bool ExpectNegative) {
3131 auto *RegListOp =
static_cast<RISCVOperand *
>(
Operands.back().
get());
3132 if (!RegListOp->isRegList())
3135 unsigned RlistEncode = RegListOp->RegList.Encoding;
3139 if (Negative != ExpectNegative || StackAdjustment % 16 != 0 ||
3140 StackAdjustment < StackAdjBase || (StackAdjustment - StackAdjBase) > 48) {
3141 int64_t
Lower = StackAdjBase;
3142 int64_t
Upper = StackAdjBase + 48;
3143 if (ExpectNegative) {
3148 return generateImmOutOfRangeError(S,
Lower,
Upper,
3149 "stack adjustment for register list must "
3150 "be a multiple of 16 bytes in the range");
3154 Operands.push_back(RISCVOperand::createStackAdj(StackAdj, S));
3166 MatchOperandParserImpl(
Operands, Mnemonic,
true);
3173 if (parseRegister(
Operands,
true).isSuccess())
3177 if (parseExpression(
Operands).isSuccess()) {
3180 return !parseMemOpBaseReg(
Operands).isSuccess();
3185 Error(getLoc(),
"unknown operand");
3189bool RISCVAsmParser::parseInstruction(ParseInstructionInfo &Info,
3190 StringRef Name, SMLoc NameLoc,
3196 const FeatureBitset &AvailableFeatures = getAvailableFeatures();
3200 Operands.push_back(RISCVOperand::createToken(Name, NameLoc));
3219 if (getParser().parseEOL(
"unexpected token")) {
3220 getParser().eatToEndOfStatement();
3226bool RISCVAsmParser::classifySymbolRef(
const MCExpr *Expr,
3230 Kind = RE->getSpecifier();
3231 Expr = RE->getSubExpr();
3240bool RISCVAsmParser::isSymbolDiff(
const MCExpr *Expr) {
3249ParseStatus RISCVAsmParser::parseDirective(AsmToken DirectiveID) {
3250 StringRef IDVal = DirectiveID.
getString();
3252 if (IDVal ==
".option")
3253 return parseDirectiveOption();
3254 if (IDVal ==
".attribute")
3255 return parseDirectiveAttribute();
3256 if (IDVal ==
".insn")
3257 return parseDirectiveInsn(DirectiveID.
getLoc());
3258 if (IDVal ==
".variant_cc")
3259 return parseDirectiveVariantCC();
3264bool RISCVAsmParser::resetToArch(StringRef Arch, SMLoc Loc, std::string &Result,
3265 bool FromOptionDirective) {
3266 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
3269 clearFeatureBits(Feature.Value, Feature.key());
3276 raw_string_ostream OutputErrMsg(Buffer);
3277 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3278 OutputErrMsg <<
"invalid arch name '" << Arch <<
"', "
3279 << ErrMsg.getMessage();
3282 return Error(Loc, OutputErrMsg.str());
3284 auto &ISAInfo = *ParseResult;
3287 if (ISAInfo->hasExtension(Feature.key()))
3288 setFeatureBits(Feature.Value, Feature.key());
3290 if (FromOptionDirective) {
3291 if (ISAInfo->getXLen() == 32 && isRV64())
3292 return Error(Loc,
"bad arch string switching from rv64 to rv32");
3293 else if (ISAInfo->getXLen() == 64 && !isRV64())
3294 return Error(Loc,
"bad arch string switching from rv32 to rv64");
3297 if (ISAInfo->getXLen() == 32)
3298 clearFeatureBits(RISCV::Feature64Bit,
"64bit");
3299 else if (ISAInfo->getXLen() == 64)
3300 setFeatureBits(RISCV::Feature64Bit,
"64bit");
3302 return Error(Loc,
"bad arch string " + Arch);
3304 Result = ISAInfo->toString();
3308bool RISCVAsmParser::parseDirectiveOption() {
3309 MCAsmParser &Parser = getParser();
3311 AsmToken Tok = Parser.
getTok();
3319 if (Option ==
"push") {
3323 getTargetStreamer().emitDirectiveOptionPush();
3328 if (Option ==
"pop") {
3333 getTargetStreamer().emitDirectiveOptionPop();
3334 if (popFeatureBits())
3335 return Error(StartLoc,
".option pop with no .option push");
3340 if (Option ==
"arch") {
3348 Type = RISCVOptionArchArgType::Plus;
3350 Type = RISCVOptionArchArgType::Minus;
3351 else if (!
Args.empty())
3353 "unexpected token, expected + or -");
3355 Type = RISCVOptionArchArgType::Full;
3359 "unexpected token, expected identifier");
3365 if (
Type == RISCVOptionArchArgType::Full) {
3367 if (resetToArch(Arch, Loc, Result,
true))
3376 Loc,
"extension version number parsing not currently implemented");
3379 if (!enableExperimentalExtension() &&
3381 return Error(Loc,
"unexpected experimental extensions");
3382 const auto &
AllFeatures = getSTI().getAllProcessorFeatures();
3384 if (Ext == std::end(
AllFeatures) || StringRef(Ext->key()) != Feature)
3385 return Error(Loc,
"unknown extension feature");
3389 if (
Type == RISCVOptionArchArgType::Plus) {
3392 setFeatureBits(Ext->Value, Ext->key());
3395 copySTI().setFeatureBits(OldFeatureBits);
3396 setAvailableFeatures(ComputeAvailableFeatures(OldFeatureBits));
3399 raw_string_ostream OutputErrMsg(Buffer);
3400 handleAllErrors(ParseResult.takeError(), [&](llvm::StringError &ErrMsg) {
3401 OutputErrMsg << ErrMsg.getMessage();
3404 return Error(Loc, OutputErrMsg.str());
3407 assert(
Type == RISCVOptionArchArgType::Minus);
3413 Feature.Implies.test(Ext->Value))
3414 return Error(Loc, Twine(
"can't disable ") + Ext->key() +
3415 " extension; " + Feature.key() +
3416 " extension requires " + Ext->key() +
3420 clearFeatureBits(Ext->Value, Ext->key());
3427 getTargetStreamer().emitDirectiveOptionArch(Args);
3430 getTargetStreamer().setArchString((*ParseResult)->toString());
3434 if (Option ==
"exact") {
3438 getTargetStreamer().emitDirectiveOptionExact();
3439 setFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3440 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3444 if (Option ==
"noexact") {
3448 getTargetStreamer().emitDirectiveOptionNoExact();
3449 clearFeatureBits(RISCV::FeatureExactAssembly,
"exact-asm");
3450 setFeatureBits(RISCV::FeatureRelax,
"relax");
3454 if (Option ==
"rvc") {
3458 getTargetStreamer().emitDirectiveOptionRVC();
3459 setFeatureBits(RISCV::FeatureStdExtC,
"c");
3461 getTargetStreamer().setArchString((*ParseResult)->toString());
3465 if (Option ==
"norvc") {
3469 getTargetStreamer().emitDirectiveOptionNoRVC();
3470 clearFeatureBits(RISCV::FeatureStdExtC,
"c");
3471 clearFeatureBits(RISCV::FeatureStdExtZca,
"zca");
3473 getTargetStreamer().setArchString((*ParseResult)->toString());
3477 if (Option ==
"pic") {
3481 getTargetStreamer().emitDirectiveOptionPIC();
3482 ParserOptions.IsPicEnabled =
true;
3486 if (Option ==
"nopic") {
3490 getTargetStreamer().emitDirectiveOptionNoPIC();
3491 ParserOptions.IsPicEnabled =
false;
3495 if (Option ==
"relax") {
3499 getTargetStreamer().emitDirectiveOptionRelax();
3500 setFeatureBits(RISCV::FeatureRelax,
"relax");
3504 if (Option ==
"norelax") {
3508 getTargetStreamer().emitDirectiveOptionNoRelax();
3509 clearFeatureBits(RISCV::FeatureRelax,
"relax");
3515 "unknown option, expected 'push', 'pop', "
3516 "'rvc', 'norvc', 'arch', 'relax', 'norelax', "
3517 "'exact', or 'noexact'");
3525bool RISCVAsmParser::parseDirectiveAttribute() {
3526 MCAsmParser &Parser = getParser();
3532 std::optional<unsigned> Ret =
3535 return Error(TagLoc,
"attribute name not recognised: " + Name);
3539 const MCExpr *AttrExpr;
3546 if (check(!CE, TagLoc,
"expected numeric constant"))
3549 Tag =
CE->getValue();
3555 StringRef StringValue;
3556 int64_t IntegerValue = 0;
3557 bool IsIntegerValue =
true;
3562 IsIntegerValue =
false;
3565 if (IsIntegerValue) {
3566 const MCExpr *ValueExpr;
3572 return Error(ValueExprLoc,
"expected numeric constant");
3573 IntegerValue =
CE->getValue();
3586 getTargetStreamer().emitAttribute(
Tag, IntegerValue);
3588 getTargetStreamer().emitTextAttribute(
Tag, StringValue);
3591 if (resetToArch(StringValue, ValueExprLoc, Result,
false))
3595 getTargetStreamer().emitTextAttribute(
Tag, Result);
3599 getTargetStreamer().setArchString(Result);
3607 .
Cases({
"r",
"r4",
"i",
"b",
"sb",
"u",
"j",
"uj",
"s"},
true)
3608 .Cases({
"cr",
"ci",
"ciw",
"css",
"cl",
"cs",
"ca",
"cb",
"cj"},
3610 .
Cases({
"qc.eai",
"qc.ei",
"qc.eb",
"qc.ej",
"qc.es"},
3619bool RISCVAsmParser::parseDirectiveInsn(SMLoc L) {
3620 MCAsmParser &Parser = getParser();
3627 std::optional<int64_t>
Length;
3637 return Error(ErrorLoc,
3638 "instruction lengths must be a non-zero multiple of two");
3642 return Error(ErrorLoc,
3643 "instruction lengths over 64 bits are not supported");
3649 int64_t EncodingDerivedLength = ((
Value & 0b11) == 0b11) ? 4 : 2;
3654 if ((*
Length <= 4) && (*
Length != EncodingDerivedLength))
3655 return Error(ErrorLoc,
3656 "instruction length does not match the encoding");
3659 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3662 return Error(ErrorLoc,
"encoding value does not fit into instruction");
3665 if (!getSTI().
hasFeature(RISCV::FeatureStdExtZca) &&
3666 (EncodingDerivedLength == 2))
3667 return Error(ErrorLoc,
"compressed instructions are not allowed");
3669 if (getParser().parseEOL(
"invalid operand for instruction")) {
3670 getParser().eatToEndOfStatement();
3678 Opcode = RISCV::Insn16;
3681 Opcode = RISCV::Insn32;
3684 Opcode = RISCV::Insn48;
3687 Opcode = RISCV::Insn64;
3693 Opcode = (EncodingDerivedLength == 2) ? RISCV::Insn16 : RISCV::Insn32;
3695 emitToStreamer(getStreamer(), MCInstBuilder(Opcode).addImm(
Value));
3700 return Error(ErrorLoc,
"invalid instruction format");
3702 std::string FormatName = (
".insn_" +
Format).str();
3704 ParseInstructionInfo
Info;
3707 if (parseInstruction(Info, FormatName, L,
Operands))
3719bool RISCVAsmParser::parseDirectiveVariantCC() {
3721 if (getParser().parseIdentifier(Name))
3722 return TokError(
"expected symbol name");
3725 getTargetStreamer().emitDirectiveVariantCC(
3730void RISCVAsmParser::emitToStreamer(MCStreamer &S,
const MCInst &Inst) {
3733 const MCSubtargetInfo &STI = getSTI();
3734 if (!STI.
hasFeature(RISCV::FeatureExactAssembly))
3737 ++RISCVNumInstrsCompressed;
3741void RISCVAsmParser::emitLoadImm(MCRegister DestReg, int64_t
Value,
3746 for (MCInst &Inst : Seq) {
3747 emitToStreamer(Out, Inst);
3751void RISCVAsmParser::emitAuipcInstPair(MCRegister DestReg, MCRegister TmpReg,
3752 const MCExpr *Symbol,
3754 unsigned SecondOpcode, SMLoc IDLoc,
3766 MCInstBuilder(RISCV::AUIPC).addReg(TmpReg).addExpr(SymbolHi));
3771 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3774 .addExpr(RefToLinkTmpLabel));
3777void RISCVAsmParser::emitLoadLocalAddress(MCInst &Inst, SMLoc IDLoc,
3790 Out, MCInstBuilder(RISCV::QC_E_LI).addReg(DestReg).addExpr(Symbol));
3796void RISCVAsmParser::emitLoadGlobalAddress(MCInst &Inst, SMLoc IDLoc,
3806 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3807 emitAuipcInstPair(DestReg, DestReg, Symbol,
RISCV::S_GOT_HI, SecondOpcode,
3811void RISCVAsmParser::emitLoadAddress(MCInst &Inst, SMLoc IDLoc,
3820 if (ParserOptions.IsPicEnabled)
3821 emitLoadGlobalAddress(Inst, IDLoc, Out);
3823 emitLoadLocalAddress(Inst, IDLoc, Out);
3826void RISCVAsmParser::emitLoadTLSIEAddress(MCInst &Inst, SMLoc IDLoc,
3836 unsigned SecondOpcode = isRV64() ? RISCV::LD : RISCV::LW;
3837 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GOT_HI20,
3838 SecondOpcode, IDLoc, Out);
3841void RISCVAsmParser::emitLoadTLSGDAddress(MCInst &Inst, SMLoc IDLoc,
3851 emitAuipcInstPair(DestReg, DestReg, Symbol, ELF::R_RISCV_TLS_GD_HI20,
3852 RISCV::ADDI, IDLoc, Out);
3855void RISCVAsmParser::emitLoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3856 SMLoc IDLoc, MCStreamer &Out,
3865 unsigned DestRegOpIdx = HasTmpReg ? 1 : 0;
3867 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3871 if (getRISCVMCRegisterClass(RISCV::GPRPairRegClassID).
contains(TmpReg)) {
3872 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
3873 TmpReg = RI->
getSubReg(TmpReg, RISCV::sub_gpr_even);
3881void RISCVAsmParser::emitQCELILoadStoreSymbol(MCInst &Inst,
unsigned Opcode,
3882 SMLoc IDLoc, MCStreamer &Out,
3892 unsigned SymbolOpIdx = HasTmpReg ? 2 : 1;
3896 MCInstBuilder(RISCV::QC_E_LI).addReg(AddrReg).addExpr(Symbol));
3899 const MCExpr *AccessExpr =
3905 struct CompressedForm {
3909 std::optional<CompressedForm> Compressed;
3913 case RISCV::PseudoQCAccessLBU:
3914 Compressed = {RISCV::PseudoQCAccessC_LBU, RISCV::FeatureStdExtZcb};
3916 case RISCV::PseudoQCAccessLH:
3917 Compressed = {RISCV::PseudoQCAccessC_LH, RISCV::FeatureStdExtZcb};
3919 case RISCV::PseudoQCAccessLHU:
3920 Compressed = {RISCV::PseudoQCAccessC_LHU, RISCV::FeatureStdExtZcb};
3922 case RISCV::PseudoQCAccessLW:
3923 Compressed = {RISCV::PseudoQCAccessC_LW, RISCV::FeatureStdExtZca};
3925 case RISCV::PseudoQCAccessSB:
3926 Compressed = {RISCV::PseudoQCAccessC_SB, RISCV::FeatureStdExtZcb};
3928 case RISCV::PseudoQCAccessSH:
3929 Compressed = {RISCV::PseudoQCAccessC_SH, RISCV::FeatureStdExtZcb};
3931 case RISCV::PseudoQCAccessSW:
3932 Compressed = {RISCV::PseudoQCAccessC_SW, RISCV::FeatureStdExtZca};
3939 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(AddrReg);
3940 if (HasTmpReg && CanUseGPRC) {
3943 getRISCVMCRegisterClass(RISCV::GPRCRegClassID).contains(DataReg);
3946 bool UseCompressed =
3947 Compressed && getSTI().hasFeature(Compressed->Feature) && CanUseGPRC;
3949 unsigned ActualOpcode = UseCompressed ? Compressed->Opcode : Opcode;
3952 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3956 .addExpr(AccessExpr));
3958 emitToStreamer(Out, MCInstBuilder(ActualOpcode)
3962 .addExpr(AccessExpr));
3966void RISCVAsmParser::emitPseudoExtend(MCInst &Inst,
bool SignExtend,
3967 int64_t Width, SMLoc IDLoc,
3976 const MCOperand &DestReg = Inst.
getOperand(0);
3977 const MCOperand &SourceReg = Inst.
getOperand(1);
3979 unsigned SecondOpcode = SignExtend ? RISCV::SRAI : RISCV::SRLI;
3980 int64_t ShAmt = (isRV64() ? 64 : 32) - Width;
3982 assert(ShAmt > 0 &&
"Shift amount must be non-zero.");
3984 emitToStreamer(Out, MCInstBuilder(RISCV::SLLI)
3989 emitToStreamer(Out, MCInstBuilder(SecondOpcode)
3995void RISCVAsmParser::emitVMSGE(MCInst &Inst,
unsigned Opcode, SMLoc IDLoc,
4002 emitToStreamer(Out, MCInstBuilder(Opcode)
4006 .addReg(MCRegister())
4008 emitToStreamer(Out, MCInstBuilder(RISCV::VMNAND_MM)
4019 "The destination register should not be V0.");
4021 emitToStreamer(Out, MCInstBuilder(Opcode)
4027 emitToStreamer(Out, MCInstBuilder(RISCV::VMXOR_MM)
4039 "The temporary vector register should not be V0.");
4040 emitToStreamer(Out, MCInstBuilder(Opcode)
4044 .addReg(MCRegister())
4046 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4058 "The temporary vector register should not be V0.");
4059 emitToStreamer(Out, MCInstBuilder(Opcode)
4063 .addReg(MCRegister())
4065 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4070 emitToStreamer(Out, MCInstBuilder(RISCV::VMANDN_MM)
4075 emitToStreamer(Out, MCInstBuilder(RISCV::VMOR_MM)
4083bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
4085 assert(Inst.
getOpcode() == RISCV::PseudoAddTPRel &&
"Invalid instruction");
4088 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
4089 return Error(ErrorLoc,
"the second input operand must be tp/x4 when using "
4090 "%tprel_add specifier");
4096bool RISCVAsmParser::checkPseudoTLSDESCCall(MCInst &Inst,
4098 assert(Inst.
getOpcode() == RISCV::PseudoTLSDESCCall &&
"Invalid instruction");
4101 SMLoc ErrorLoc = ((RISCVOperand &)*
Operands[3]).getStartLoc();
4102 return Error(ErrorLoc,
"the output operand must be t0/x5 when using "
4103 "%tlsdesc_call specifier");
4109std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultMaskRegOp()
const {
4110 return RISCVOperand::createReg(MCRegister(), llvm::SMLoc(), llvm::SMLoc());
4113std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgOp()
const {
4114 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::DYN,
4118std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultFRMArgLegacyOp()
const {
4119 return RISCVOperand::createFRMArg(RISCVFPRndMode::RoundingMode::RNE,
4123std::unique_ptr<RISCVOperand> RISCVAsmParser::defaultZeroOffset() {
4125 llvm::SMLoc(), llvm::SMLoc(), isRV64());
4132 case RISCV::VLOXSEG2EI8_V:
4133 case RISCV::VLOXSEG2EI16_V:
4134 case RISCV::VLOXSEG2EI32_V:
4135 case RISCV::VLOXSEG2EI64_V:
4136 case RISCV::VLUXSEG2EI8_V:
4137 case RISCV::VLUXSEG2EI16_V:
4138 case RISCV::VLUXSEG2EI32_V:
4139 case RISCV::VLUXSEG2EI64_V:
4141 case RISCV::VLOXSEG3EI8_V:
4142 case RISCV::VLOXSEG3EI16_V:
4143 case RISCV::VLOXSEG3EI32_V:
4144 case RISCV::VLOXSEG3EI64_V:
4145 case RISCV::VLUXSEG3EI8_V:
4146 case RISCV::VLUXSEG3EI16_V:
4147 case RISCV::VLUXSEG3EI32_V:
4148 case RISCV::VLUXSEG3EI64_V:
4150 case RISCV::VLOXSEG4EI8_V:
4151 case RISCV::VLOXSEG4EI16_V:
4152 case RISCV::VLOXSEG4EI32_V:
4153 case RISCV::VLOXSEG4EI64_V:
4154 case RISCV::VLUXSEG4EI8_V:
4155 case RISCV::VLUXSEG4EI16_V:
4156 case RISCV::VLUXSEG4EI32_V:
4157 case RISCV::VLUXSEG4EI64_V:
4159 case RISCV::VLOXSEG5EI8_V:
4160 case RISCV::VLOXSEG5EI16_V:
4161 case RISCV::VLOXSEG5EI32_V:
4162 case RISCV::VLOXSEG5EI64_V:
4163 case RISCV::VLUXSEG5EI8_V:
4164 case RISCV::VLUXSEG5EI16_V:
4165 case RISCV::VLUXSEG5EI32_V:
4166 case RISCV::VLUXSEG5EI64_V:
4168 case RISCV::VLOXSEG6EI8_V:
4169 case RISCV::VLOXSEG6EI16_V:
4170 case RISCV::VLOXSEG6EI32_V:
4171 case RISCV::VLOXSEG6EI64_V:
4172 case RISCV::VLUXSEG6EI8_V:
4173 case RISCV::VLUXSEG6EI16_V:
4174 case RISCV::VLUXSEG6EI32_V:
4175 case RISCV::VLUXSEG6EI64_V:
4177 case RISCV::VLOXSEG7EI8_V:
4178 case RISCV::VLOXSEG7EI16_V:
4179 case RISCV::VLOXSEG7EI32_V:
4180 case RISCV::VLOXSEG7EI64_V:
4181 case RISCV::VLUXSEG7EI8_V:
4182 case RISCV::VLUXSEG7EI16_V:
4183 case RISCV::VLUXSEG7EI32_V:
4184 case RISCV::VLUXSEG7EI64_V:
4186 case RISCV::VLOXSEG8EI8_V:
4187 case RISCV::VLOXSEG8EI16_V:
4188 case RISCV::VLOXSEG8EI32_V:
4189 case RISCV::VLOXSEG8EI64_V:
4190 case RISCV::VLUXSEG8EI8_V:
4191 case RISCV::VLUXSEG8EI16_V:
4192 case RISCV::VLUXSEG8EI32_V:
4193 case RISCV::VLUXSEG8EI64_V:
4199 if (getRISCVMCRegisterClass(RISCV::VRM2RegClassID).
contains(
Reg))
4201 if (getRISCVMCRegisterClass(RISCV::VRM4RegClassID).
contains(
Reg))
4203 if (getRISCVMCRegisterClass(RISCV::VRM8RegClassID).
contains(
Reg))
4210 case RISCV::VFWMMACC_VV_SCALE:
4211 case RISCV::VFQMMACC_VV_SCALE:
4212 case RISCV::VF8WMMACC_VV_SCALE:
4213 case RISCV::VFWIMMACC_VV:
4214 case RISCV::VFQIMMACC_VV:
4215 case RISCV::VF8WIMMACC_VV:
4222bool RISCVAsmParser::validateInstruction(MCInst &Inst,
4226 if (Opcode == RISCV::PseudoVMSGEU_VX_M_T ||
4227 Opcode == RISCV::PseudoVMSGE_VX_M_T) {
4230 if (DestReg == TempReg) {
4231 SMLoc Loc =
Operands.back()->getStartLoc();
4232 return Error(Loc,
"the temporary vector register cannot be the same as "
4233 "the destination register");
4237 if (Opcode == RISCV::PseudoVMSGEU_VX_M || Opcode == RISCV::PseudoVMSGE_VX_M) {
4240 if (MaskReg == RISCV::V0 && DestReg == RISCV::V0) {
4241 SMLoc Loc =
Operands.back()->getStartLoc();
4242 return Error(Loc,
"the destination vector register cannot overlap the "
4243 "mask register unless a temporary register is "
4248 if (Opcode == RISCV::TH_LDD || Opcode == RISCV::TH_LWUD ||
4249 Opcode == RISCV::TH_LWD) {
4254 if (Rs1 == Rd1 || Rs1 == Rd2 || Rd1 == Rd2) {
4255 SMLoc Loc =
Operands[1]->getStartLoc();
4256 return Error(Loc,
"rs1, rd1, and rd2 cannot overlap");
4260 if (Opcode == RISCV::CM_MVSA01 || Opcode == RISCV::QC_CM_MVSA01) {
4264 SMLoc Loc =
Operands[1]->getStartLoc();
4265 return Error(Loc,
"rs1 and rs2 must be different");
4270 auto CheckOperandDoesNotOverlapV0 = [&](
int OperandIdx,
4271 unsigned ParsedIdx) {
4274 "vd, vs1, and vs2 cannot overlap v0.scale");
4279 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4281 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4283 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4284 assert(DestIdx >= 0 && VS1Idx >= 0 && VS2Idx >= 0 &&
4285 "Unexpected Zvvfmm scaled operand list");
4287 if (CheckOperandDoesNotOverlapV0(DestIdx, 1) ||
4288 CheckOperandDoesNotOverlapV0(VS1Idx, 2) ||
4289 CheckOperandDoesNotOverlapV0(VS2Idx, 3))
4293 const MCInstrDesc &MCID = MII.
get(Opcode);
4297 int DestIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vd);
4301 const MCParsedAsmOperand *ParsedOp =
Operands[1].get();
4302 if (!ParsedOp->
isReg()) {
4307 assert(ParsedOp->
getReg() == DestReg &&
"Can't find parsed dest operand");
4311 const MCRegisterInfo *RI =
getContext().getRegisterInfo();
4315 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs2);
4316 assert(VS2Idx >= 0 &&
"No vs2 operand?");
4317 unsigned CheckEncoding =
4320 for (
unsigned i = 0; i < std::max(NF, Lmul); i++) {
4321 if ((DestEncoding + i) == CheckEncoding)
4322 return Error(Loc,
"the destination vector register group cannot overlap"
4323 " the source vector register group");
4328 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vs1);
4332 unsigned CheckEncoding =
4334 for (
unsigned i = 0; i < Lmul; i++) {
4335 if ((DestEncoding + i) == CheckEncoding)
4337 "the destination vector register group cannot overlap"
4338 " the source vector register group");
4344 int VMIdx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vm);
4345 assert(VMIdx >= 0 &&
"No vm operand?");
4347 if (DestReg == RISCV::V0) {
4350 return Error(Loc,
"the destination vector register group cannot be V0");
4358 "Unexpected mask operand register");
4360 return Error(Loc,
"the destination vector register group cannot overlap"
4361 " the mask register");
4369 RISCV::getNamedOperandIdx(Inst.
getOpcode(), RISCV::OpName::vmask);
4371 if (MaskReg != RISCV::V0 && MaskReg != RISCV::V1)
4373 "vmask operand only supports v0 or v1");
4376 RISCV::OpName RegOps[] = {RISCV::OpName::vd, RISCV::OpName::vs1,
4377 RISCV::OpName::vs2};
4378 for (RISCV::OpName OpN : RegOps) {
4379 int Idx = RISCV::getNamedOperandIdx(Inst.
getOpcode(), OpN);
4385 for (
unsigned i = 0; i < RegLmul; i++) {
4386 if ((RegEnc + i) == MaskEnc) {
4387 SMLoc Loc =
Operands[Idx]->getStartLoc();
4388 return Error(Loc, Twine(
"register conflicts with vmask register ") +
4398bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
4406 case RISCV::PseudoC_ADDI_NOP: {
4408 emitToStreamer(Out, MCInstBuilder(RISCV::C_NOP));
4418 if (getSTI().
hasFeature(RISCV::Feature64Bit))
4420 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV32)
4425 case RISCV::PACKW: {
4429 emitToStreamer(Out, MCInstBuilder(RISCV::ZEXT_H_RV64)
4434 case RISCV::PseudoLLAImm:
4435 case RISCV::PseudoLAImm:
4436 case RISCV::PseudoLI: {
4442 emitToStreamer(Out, MCInstBuilder(RISCV::ADDI)
4454 emitLoadImm(
Reg, Imm, Out);
4457 case RISCV::PseudoLLA:
4458 emitLoadLocalAddress(Inst, IDLoc, Out);
4460 case RISCV::PseudoLGA:
4461 emitLoadGlobalAddress(Inst, IDLoc, Out);
4463 case RISCV::PseudoLA:
4464 emitLoadAddress(Inst, IDLoc, Out);
4466 case RISCV::PseudoLA_TLS_IE:
4467 emitLoadTLSIEAddress(Inst, IDLoc, Out);
4469 case RISCV::PseudoLA_TLS_GD:
4470 emitLoadTLSGDAddress(Inst, IDLoc, Out);
4472 case RISCV::PseudoLB:
4473 emitLoadStoreSymbol(Inst, RISCV::LB, IDLoc, Out,
false);
4475 case RISCV::PseudoLBU:
4476 emitLoadStoreSymbol(Inst, RISCV::LBU, IDLoc, Out,
false);
4478 case RISCV::PseudoLH:
4479 emitLoadStoreSymbol(Inst, RISCV::LH, IDLoc, Out,
false);
4481 case RISCV::PseudoLHU:
4482 emitLoadStoreSymbol(Inst, RISCV::LHU, IDLoc, Out,
false);
4484 case RISCV::PseudoLW:
4485 emitLoadStoreSymbol(Inst, RISCV::LW, IDLoc, Out,
false);
4487 case RISCV::PseudoLWU:
4488 emitLoadStoreSymbol(Inst, RISCV::LWU, IDLoc, Out,
false);
4490 case RISCV::PseudoLD:
4491 emitLoadStoreSymbol(Inst, RISCV::LD, IDLoc, Out,
false);
4493 case RISCV::PseudoLD_RV32:
4494 emitLoadStoreSymbol(Inst, RISCV::LD_RV32, IDLoc, Out,
false);
4496 case RISCV::PseudoFLH:
4497 emitLoadStoreSymbol(Inst, RISCV::FLH, IDLoc, Out,
true);
4499 case RISCV::PseudoFLW:
4500 emitLoadStoreSymbol(Inst, RISCV::FLW, IDLoc, Out,
true);
4502 case RISCV::PseudoFLD:
4503 emitLoadStoreSymbol(Inst, RISCV::FLD, IDLoc, Out,
true);
4505 case RISCV::PseudoFLQ:
4506 emitLoadStoreSymbol(Inst, RISCV::FLQ, IDLoc, Out,
true);
4508 case RISCV::PseudoSB:
4509 emitLoadStoreSymbol(Inst, RISCV::SB, IDLoc, Out,
true);
4511 case RISCV::PseudoSH:
4512 emitLoadStoreSymbol(Inst, RISCV::SH, IDLoc, Out,
true);
4514 case RISCV::PseudoSW:
4515 emitLoadStoreSymbol(Inst, RISCV::SW, IDLoc, Out,
true);
4517 case RISCV::PseudoSD:
4518 emitLoadStoreSymbol(Inst, RISCV::SD, IDLoc, Out,
true);
4520 case RISCV::PseudoSD_RV32:
4521 emitLoadStoreSymbol(Inst, RISCV::SD_RV32, IDLoc, Out,
true);
4523 case RISCV::PseudoQC_E_LB:
4524 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLB, IDLoc, Out,
4527 case RISCV::PseudoQC_E_LBU:
4528 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLBU, IDLoc, Out,
4531 case RISCV::PseudoQC_E_LH:
4532 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLH, IDLoc, Out,
4535 case RISCV::PseudoQC_E_LHU:
4536 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLHU, IDLoc, Out,
4539 case RISCV::PseudoQC_E_LW:
4540 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessLW, IDLoc, Out,
4543 case RISCV::PseudoQC_E_SB:
4544 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSB, IDLoc, Out,
4547 case RISCV::PseudoQC_E_SH:
4548 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSH, IDLoc, Out,
4551 case RISCV::PseudoQC_E_SW:
4552 emitQCELILoadStoreSymbol(Inst, RISCV::PseudoQCAccessSW, IDLoc, Out,
4555 case RISCV::PseudoFSH:
4556 emitLoadStoreSymbol(Inst, RISCV::FSH, IDLoc, Out,
true);
4558 case RISCV::PseudoFSW:
4559 emitLoadStoreSymbol(Inst, RISCV::FSW, IDLoc, Out,
true);
4561 case RISCV::PseudoFSD:
4562 emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out,
true);
4564 case RISCV::PseudoFSQ:
4565 emitLoadStoreSymbol(Inst, RISCV::FSQ, IDLoc, Out,
true);
4567 case RISCV::PseudoAddTPRel:
4568 if (checkPseudoAddTPRel(Inst,
Operands))
4571 case RISCV::PseudoTLSDESCCall:
4572 if (checkPseudoTLSDESCCall(Inst,
Operands))
4575 case RISCV::PseudoSEXT_B:
4576 emitPseudoExtend(Inst,
true, 8, IDLoc, Out);
4578 case RISCV::PseudoSEXT_H:
4579 emitPseudoExtend(Inst,
true, 16, IDLoc, Out);
4581 case RISCV::PseudoZEXT_H:
4582 emitPseudoExtend(Inst,
false, 16, IDLoc, Out);
4584 case RISCV::PseudoZEXT_W:
4585 emitPseudoExtend(Inst,
false, 32, IDLoc, Out);
4587 case RISCV::PseudoVMSGEU_VX_M:
4588 case RISCV::PseudoVMSGEU_VX_M_T:
4589 emitVMSGE(Inst, RISCV::VMSLTU_VX, IDLoc, Out);
4591 case RISCV::PseudoVMSGE_VX_M:
4592 case RISCV::PseudoVMSGE_VX_M_T:
4593 emitVMSGE(Inst, RISCV::VMSLT_VX, IDLoc, Out);
4595 case RISCV::PseudoVMSGE_VI:
4596 case RISCV::PseudoVMSLT_VI: {
4600 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGE_VI ? RISCV::VMSGT_VI
4602 emitToStreamer(Out, MCInstBuilder(
Opc)
4610 case RISCV::PseudoVMSGEU_VI:
4611 case RISCV::PseudoVMSLTU_VI: {
4618 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4621 emitToStreamer(Out, MCInstBuilder(
Opc)
4629 unsigned Opc = Inst.
getOpcode() == RISCV::PseudoVMSGEU_VI
4632 emitToStreamer(Out, MCInstBuilder(
Opc)
4642 case RISCV::PseudoCV_ELW:
4643 emitLoadStoreSymbol(Inst, RISCV::CV_ELW, IDLoc, Out,
false);
4647 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
const FeatureInfo AllFeatures[]
static bool hasFeature(StringRef Feature, const FeatureBitset &FeatureBits, ArrayRef< SubtargetFeatureKV > ProcFeatures)
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
static MCRegister convertGPRToYGPR(MCRegister Reg)
bool isValidInsnFormat(StringRef Format, const MCSubtargetInfo &STI)
static bool isZvvfmmScaleOpcode(unsigned Opcode)
static MCRegister convertFPR64ToFPR128(MCRegister Reg)
static MCRegister convertFPR64ToFPR32(MCRegister Reg)
static cl::opt< bool > AddBuildAttributes("riscv-add-build-attributes", cl::init(false))
static MCRegister convertFPR64ToFPR16(MCRegister Reg)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeRISCVAsmParser()
static MCRegister convertFPR64ToFPR256(MCRegister Reg)
static MCRegister convertVRToVRMx(const MCRegisterInfo &RI, MCRegister Reg, unsigned Kind)
static unsigned getNFforLXSEG(unsigned Opcode)
unsigned getLMULFromVectorRegister(MCRegister Reg)
static bool isUImm2(const MachineOperand &MO)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file implements the SmallBitVector class.
This file defines the SmallSet 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.
void printExpr(raw_ostream &, const MCExpr &) const
const AsmToken & getTok()
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
virtual void eatToEndOfStatement()=0
Skip to the end of the current statement, for error recovery.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
const AsmToken & getTok() const
Get the current AsmToken from the stream.
virtual bool parseIdentifier(StringRef &Res)=0
Parse an identifier or string (as a quoted identifier) and set Res to the identifier contents.
bool parseOptionalToken(AsmToken::TokenKind T)
Attempt to parse and consume token, returning true on success.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
virtual bool parseAbsoluteExpression(int64_t &Res)=0
Parse an expression which must evaluate to an absolute value.
MCStreamer & getStreamer()
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
const MCObjectFileInfo * getObjectFileInfo() const
LLVM_ABI MCSymbol * createNamedTempSymbol()
Create a temporary symbol with a unique name whose name cannot be omitted in the symbol table.
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
const MCOperand & getOperand(unsigned i) const
ArrayRef< MCOperandInfo > operands() const
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
StringRef getName(unsigned Opcode) const
Returns the name for the instructions with the given 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 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
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
reference emplace_back(ArgTypes &&... Args)
Represent a constant reference to a string, i.e.
std::string str() const
Get the contents as an std::string.
char back() const
Get the last character in the string.
A switch()-like statement whose cases are string literals.
StringSwitch & Cases(std::initializer_list< StringLiteral > CaseStrings, T Value)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
uint16_t StackAdjustment(const RuntimeFunction &RF)
StackAdjustment - calculated stack adjustment in words.
LLVM_ABI std::optional< unsigned > attrTypeFromString(StringRef tag, TagNameMap tagNameMap)
MCExpr const & getExpr(MCExpr const &Expr)
ABI computeTargetABI(const MCSubtargetInfo &STI, StringRef ABIName)
LLVM_ABI const TagNameMap & getRISCVAttributeTags()
static RoundingMode stringToRoundingMode(StringRef Str)
llvm::Expected< std::unique_ptr< RISCVISAInfo > > parseFeatureBits(const MCSubtargetInfo &STI)
int getLoadFPImm(APFloat FPImm)
getLoadFPImm - Return a 5-bit binary encoding of the floating-point immediate value.
void generateMCInstSeq(int64_t Val, const MCSubtargetInfo &STI, MCRegister DestReg, SmallVectorImpl< MCInst > &Insts)
bool compress(MCInst &OutInst, const MCInst &MI, const MCSubtargetInfo &STI)
static VLMUL encodeLMUL(unsigned LMUL, bool Fractional)
LLVM_ABI unsigned encodeXSfmmVType(unsigned SEW, unsigned Widen, bool AltFmt)
static bool isValidLMUL(unsigned LMUL, bool Fractional)
static bool isValidSEW(unsigned SEW)
LLVM_ABI void printVType(unsigned VType, raw_ostream &OS)
static bool isValidXSfmmVType(unsigned VTypeI)
LLVM_ABI unsigned encodeVTYPE(VLMUL VLMUL, unsigned SEW, bool TailAgnostic, bool MaskAgnostic, bool AltFmt=false)
unsigned encodeRegList(MCRegister EndReg, bool IsRVE=false)
static unsigned getStackAdjBase(unsigned RlistVal, bool IsRV64)
void printRegList(unsigned RlistEncode, raw_ostream &OS)
Specifier parseSpecifierName(StringRef name)
void updateCZceFeatureImplications(MCSubtargetInfo &STI)
bool isValidYBNDSWImm(int64_t Imm)
@ CE
Windows NT (Windows on ARM)
static SMTVTypeMode stringToSMTVTypeMode(StringRef Str)
static bool isValidSMTVTypeMode(unsigned Mode)
@ Valid
The data is already valid.
initializer< Ty > init(const Ty &Val)
std::function< llvm::json::Value()> Lambda
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.
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()
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
SmallVectorImpl< std::unique_ptr< MCParsedAsmOperand > > OperandVector
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
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.
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,...