71 SVEPredicateAsCounter,
77enum class MatrixKind {
Array, Tile, Row, Col };
79enum RegConstraintEqualityTy {
94 static PrefixInfo CreateFromInst(
const MCInst &Inst,
uint64_t TSFlags) {
97 case AArch64::MOVPRFX_ZZ:
101 case AArch64::MOVPRFX_ZPmZ_B:
102 case AArch64::MOVPRFX_ZPmZ_H:
103 case AArch64::MOVPRFX_ZPmZ_S:
104 case AArch64::MOVPRFX_ZPmZ_D:
109 "No destructive element size set for movprfx");
113 case AArch64::MOVPRFX_ZPzZ_B:
114 case AArch64::MOVPRFX_ZPzZ_H:
115 case AArch64::MOVPRFX_ZPzZ_S:
116 case AArch64::MOVPRFX_ZPzZ_D:
121 "No destructive element size set for movprfx");
132 PrefixInfo() =
default;
133 bool isActive()
const {
return Active; }
135 unsigned getElementSize()
const {
139 unsigned getDstReg()
const {
return Dst; }
140 unsigned getPgReg()
const {
147 bool Predicated =
false;
148 unsigned ElementSize;
164 std::string &Suggestion);
166 unsigned matchRegisterNameAlias(
StringRef Name, RegKind Kind);
168 bool parseSymbolicImmVal(
const MCExpr *&ImmVal);
174 bool invertCondCode);
175 bool parseImmExpr(int64_t &Out);
177 bool parseRegisterInRange(
unsigned &Out,
unsigned Base,
unsigned First,
183 bool parseAuthExpr(
const MCExpr *&Res,
SMLoc &EndLoc);
185 bool parseDirectiveArch(
SMLoc L);
186 bool parseDirectiveArchExtension(
SMLoc L);
187 bool parseDirectiveCPU(
SMLoc L);
188 bool parseDirectiveInst(
SMLoc L);
190 bool parseDirectiveTLSDescCall(
SMLoc L);
193 bool parseDirectiveLtorg(
SMLoc L);
196 bool parseDirectiveUnreq(
SMLoc L);
197 bool parseDirectiveCFINegateRAState();
198 bool parseDirectiveCFIBKeyFrame();
199 bool parseDirectiveCFIMTETaggedFrame();
201 bool parseDirectiveVariantPCS(
SMLoc L);
203 bool parseDirectiveSEHAllocStack(
SMLoc L);
204 bool parseDirectiveSEHPrologEnd(
SMLoc L);
205 bool parseDirectiveSEHSaveR19R20X(
SMLoc L);
206 bool parseDirectiveSEHSaveFPLR(
SMLoc L);
207 bool parseDirectiveSEHSaveFPLRX(
SMLoc L);
208 bool parseDirectiveSEHSaveReg(
SMLoc L);
209 bool parseDirectiveSEHSaveRegX(
SMLoc L);
210 bool parseDirectiveSEHSaveRegP(
SMLoc L);
211 bool parseDirectiveSEHSaveRegPX(
SMLoc L);
212 bool parseDirectiveSEHSaveLRPair(
SMLoc L);
213 bool parseDirectiveSEHSaveFReg(
SMLoc L);
214 bool parseDirectiveSEHSaveFRegX(
SMLoc L);
215 bool parseDirectiveSEHSaveFRegP(
SMLoc L);
216 bool parseDirectiveSEHSaveFRegPX(
SMLoc L);
217 bool parseDirectiveSEHSetFP(
SMLoc L);
218 bool parseDirectiveSEHAddFP(
SMLoc L);
219 bool parseDirectiveSEHNop(
SMLoc L);
220 bool parseDirectiveSEHSaveNext(
SMLoc L);
221 bool parseDirectiveSEHEpilogStart(
SMLoc L);
222 bool parseDirectiveSEHEpilogEnd(
SMLoc L);
223 bool parseDirectiveSEHTrapFrame(
SMLoc L);
224 bool parseDirectiveSEHMachineFrame(
SMLoc L);
225 bool parseDirectiveSEHContext(
SMLoc L);
226 bool parseDirectiveSEHECContext(
SMLoc L);
227 bool parseDirectiveSEHClearUnwoundToCall(
SMLoc L);
228 bool parseDirectiveSEHPACSignLR(
SMLoc L);
229 bool parseDirectiveSEHSaveAnyReg(
SMLoc L,
bool Paired,
bool Writeback);
231 bool validateInstruction(
MCInst &Inst,
SMLoc &IDLoc,
233 unsigned getNumRegsForRegKind(RegKind K);
237 bool MatchingInlineAsm)
override;
241#define GET_ASSEMBLER_HEADER
242#include "AArch64GenAsmMatcher.inc"
256 template <
bool IsSVEPrefetch = false>
263 template <
bool AddFPZeroAsLiteral>
271 template <
bool ParseShiftExtend,
272 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg>
275 template <
bool ParseShiftExtend,
bool ParseSuffix>
277 template <RegKind RK>
279 template <RegKind VectorKind>
281 bool ExpectMatch =
false);
289 enum AArch64MatchResultTy {
291#define GET_OPERAND_DIAGNOSTIC_TYPES
292#include "AArch64GenAsmMatcher.inc"
324 SMLoc &EndLoc)
override;
327 unsigned Kind)
override;
331 static bool classifySymbolRef(
const MCExpr *Expr,
363 SMLoc StartLoc, EndLoc;
372 struct ShiftExtendOp {
375 bool HasExplicitAmount;
385 RegConstraintEqualityTy EqualityTy;
401 ShiftExtendOp ShiftExtend;
406 unsigned ElementWidth;
410 struct MatrixTileListOp {
411 unsigned RegMask = 0;
414 struct VectorListOp {
418 unsigned NumElements;
419 unsigned ElementWidth;
420 RegKind RegisterKind;
423 struct VectorIndexOp {
431 struct ShiftedImmOp {
433 unsigned ShiftAmount;
490 unsigned PStateField;
496 struct MatrixRegOp MatrixReg;
497 struct MatrixTileListOp MatrixTileList;
498 struct VectorListOp VectorList;
499 struct VectorIndexOp VectorIndex;
501 struct ShiftedImmOp ShiftedImm;
502 struct ImmRangeOp ImmRange;
504 struct FPImmOp FPImm;
506 struct SysRegOp SysReg;
507 struct SysCRImmOp SysCRImm;
509 struct PSBHintOp PSBHint;
510 struct BTIHintOp BTIHint;
511 struct ShiftExtendOp ShiftExtend;
524 StartLoc =
o.StartLoc;
534 ShiftedImm =
o.ShiftedImm;
537 ImmRange =
o.ImmRange;
551 case k_MatrixRegister:
552 MatrixReg =
o.MatrixReg;
554 case k_MatrixTileList:
555 MatrixTileList =
o.MatrixTileList;
558 VectorList =
o.VectorList;
561 VectorIndex =
o.VectorIndex;
567 SysCRImm =
o.SysCRImm;
579 ShiftExtend =
o.ShiftExtend;
588 SMLoc getStartLoc()
const override {
return StartLoc; }
590 SMLoc getEndLoc()
const override {
return EndLoc; }
593 assert(Kind == k_Token &&
"Invalid access!");
597 bool isTokenSuffix()
const {
598 assert(Kind == k_Token &&
"Invalid access!");
602 const MCExpr *getImm()
const {
603 assert(Kind == k_Immediate &&
"Invalid access!");
607 const MCExpr *getShiftedImmVal()
const {
608 assert(Kind == k_ShiftedImm &&
"Invalid access!");
609 return ShiftedImm.Val;
612 unsigned getShiftedImmShift()
const {
613 assert(Kind == k_ShiftedImm &&
"Invalid access!");
614 return ShiftedImm.ShiftAmount;
617 unsigned getFirstImmVal()
const {
618 assert(Kind == k_ImmRange &&
"Invalid access!");
619 return ImmRange.First;
622 unsigned getLastImmVal()
const {
623 assert(Kind == k_ImmRange &&
"Invalid access!");
624 return ImmRange.Last;
628 assert(Kind == k_CondCode &&
"Invalid access!");
633 assert (Kind == k_FPImm &&
"Invalid access!");
634 return APFloat(APFloat::IEEEdouble(),
APInt(64, FPImm.Val,
true));
637 bool getFPImmIsExact()
const {
638 assert (Kind == k_FPImm &&
"Invalid access!");
639 return FPImm.IsExact;
642 unsigned getBarrier()
const {
643 assert(Kind == k_Barrier &&
"Invalid access!");
648 assert(Kind == k_Barrier &&
"Invalid access!");
652 bool getBarriernXSModifier()
const {
653 assert(Kind == k_Barrier &&
"Invalid access!");
657 unsigned getReg()
const override {
658 assert(Kind == k_Register &&
"Invalid access!");
662 unsigned getMatrixReg()
const {
663 assert(Kind == k_MatrixRegister &&
"Invalid access!");
664 return MatrixReg.RegNum;
667 unsigned getMatrixElementWidth()
const {
668 assert(Kind == k_MatrixRegister &&
"Invalid access!");
669 return MatrixReg.ElementWidth;
672 MatrixKind getMatrixKind()
const {
673 assert(Kind == k_MatrixRegister &&
"Invalid access!");
674 return MatrixReg.Kind;
677 unsigned getMatrixTileListRegMask()
const {
678 assert(isMatrixTileList() &&
"Invalid access!");
679 return MatrixTileList.RegMask;
682 RegConstraintEqualityTy getRegEqualityTy()
const {
683 assert(Kind == k_Register &&
"Invalid access!");
684 return Reg.EqualityTy;
687 unsigned getVectorListStart()
const {
688 assert(Kind == k_VectorList &&
"Invalid access!");
689 return VectorList.RegNum;
692 unsigned getVectorListCount()
const {
693 assert(Kind == k_VectorList &&
"Invalid access!");
694 return VectorList.Count;
697 unsigned getVectorListStride()
const {
698 assert(Kind == k_VectorList &&
"Invalid access!");
699 return VectorList.Stride;
702 int getVectorIndex()
const {
703 assert(Kind == k_VectorIndex &&
"Invalid access!");
704 return VectorIndex.Val;
708 assert(Kind == k_SysReg &&
"Invalid access!");
709 return StringRef(SysReg.Data, SysReg.Length);
712 unsigned getSysCR()
const {
713 assert(Kind == k_SysCR &&
"Invalid access!");
717 unsigned getPrefetch()
const {
718 assert(Kind == k_Prefetch &&
"Invalid access!");
722 unsigned getPSBHint()
const {
723 assert(Kind == k_PSBHint &&
"Invalid access!");
728 assert(Kind == k_PSBHint &&
"Invalid access!");
729 return StringRef(PSBHint.Data, PSBHint.Length);
732 unsigned getBTIHint()
const {
733 assert(Kind == k_BTIHint &&
"Invalid access!");
738 assert(Kind == k_BTIHint &&
"Invalid access!");
739 return StringRef(BTIHint.Data, BTIHint.Length);
743 assert(Kind == k_SVCR &&
"Invalid access!");
744 return StringRef(SVCR.Data, SVCR.Length);
748 assert(Kind == k_Prefetch &&
"Invalid access!");
753 if (Kind == k_ShiftExtend)
754 return ShiftExtend.Type;
755 if (Kind == k_Register)
756 return Reg.ShiftExtend.Type;
760 unsigned getShiftExtendAmount()
const {
761 if (Kind == k_ShiftExtend)
762 return ShiftExtend.Amount;
763 if (Kind == k_Register)
764 return Reg.ShiftExtend.Amount;
768 bool hasShiftExtendAmount()
const {
769 if (Kind == k_ShiftExtend)
770 return ShiftExtend.HasExplicitAmount;
771 if (Kind == k_Register)
772 return Reg.ShiftExtend.HasExplicitAmount;
776 bool isImm()
const override {
return Kind == k_Immediate; }
777 bool isMem()
const override {
return false; }
779 bool isUImm6()
const {
786 return (Val >= 0 && Val < 64);
789 template <
int W
idth>
bool isSImm()
const {
return isSImmScaled<Width, 1>(); }
792 return isImmScaled<Bits, Scale>(
true);
795 template <
int Bits,
int Scale,
int Offset = 0,
bool IsRange = false>
797 if (IsRange && isImmRange() &&
798 (getLastImmVal() != getFirstImmVal() +
Offset))
799 return DiagnosticPredicateTy::NoMatch;
801 return isImmScaled<Bits, Scale, IsRange>(
false);
804 template <
int Bits,
int Scale,
bool IsRange = false>
806 if ((!
isImm() && !isImmRange()) || (
isImm() && IsRange) ||
807 (isImmRange() && !IsRange))
808 return DiagnosticPredicateTy::NoMatch;
812 Val = getFirstImmVal();
816 return DiagnosticPredicateTy::NoMatch;
820 int64_t MinVal, MaxVal;
822 int64_t Shift =
Bits - 1;
823 MinVal = (int64_t(1) << Shift) * -Scale;
824 MaxVal = ((int64_t(1) << Shift) - 1) * Scale;
827 MaxVal = ((int64_t(1) <<
Bits) - 1) * Scale;
830 if (Val >= MinVal && Val <= MaxVal && (Val % Scale) == 0)
831 return DiagnosticPredicateTy::Match;
833 return DiagnosticPredicateTy::NearMatch;
838 return DiagnosticPredicateTy::NoMatch;
839 auto *MCE = dyn_cast<MCConstantExpr>(getImm());
841 return DiagnosticPredicateTy::NoMatch;
843 if (Val >= 0 && Val < 32)
844 return DiagnosticPredicateTy::Match;
845 return DiagnosticPredicateTy::NearMatch;
850 return DiagnosticPredicateTy::NoMatch;
851 auto *MCE = dyn_cast<MCConstantExpr>(getImm());
853 return DiagnosticPredicateTy::NoMatch;
855 if (Val >= 0 && Val <= 1)
856 return DiagnosticPredicateTy::Match;
857 return DiagnosticPredicateTy::NearMatch;
860 bool isSymbolicUImm12Offset(
const MCExpr *Expr)
const {
864 if (!AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind, DarwinRefKind,
896 template <
int Scale>
bool isUImm12Offset()
const {
902 return isSymbolicUImm12Offset(getImm());
905 return (Val % Scale) == 0 && Val >= 0 && (Val / Scale) < 0x1000;
908 template <
int N,
int M>
909 bool isImmInRange()
const {
916 return (Val >=
N && Val <= M);
921 template <
typename T>
922 bool isLogicalImm()
const {
939 bool isShiftedImm()
const {
return Kind == k_ShiftedImm; }
941 bool isImmRange()
const {
return Kind == k_ImmRange; }
946 template <
unsigned W
idth>
947 std::optional<std::pair<int64_t, unsigned>> getShiftedVal()
const {
948 if (isShiftedImm() && Width == getShiftedImmShift())
949 if (
auto *CE = dyn_cast<MCConstantExpr>(getShiftedImmVal()))
950 return std::make_pair(
CE->getValue(), Width);
953 if (
auto *CE = dyn_cast<MCConstantExpr>(getImm())) {
954 int64_t Val =
CE->getValue();
956 return std::make_pair(Val >> Width, Width);
958 return std::make_pair(Val, 0u);
964 bool isAddSubImm()
const {
965 if (!isShiftedImm() && !
isImm())
971 if (isShiftedImm()) {
972 unsigned Shift = ShiftedImm.ShiftAmount;
973 Expr = ShiftedImm.Val;
974 if (Shift != 0 && Shift != 12)
983 if (AArch64AsmParser::classifySymbolRef(Expr, ELFRefKind,
984 DarwinRefKind, Addend)) {
1001 if (
auto ShiftedVal = getShiftedVal<12>())
1002 return ShiftedVal->first >= 0 && ShiftedVal->first <= 0xfff;
1009 bool isAddSubImmNeg()
const {
1010 if (!isShiftedImm() && !
isImm())
1014 if (
auto ShiftedVal = getShiftedVal<12>())
1015 return ShiftedVal->first < 0 && -ShiftedVal->first <= 0xfff;
1025 template <
typename T>
1027 if (!isShiftedImm() && (!
isImm() || !isa<MCConstantExpr>(getImm())))
1028 return DiagnosticPredicateTy::NoMatch;
1030 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>
::value ||
1031 std::is_same<int8_t, T>::value;
1032 if (
auto ShiftedImm = getShiftedVal<8>())
1033 if (!(IsByte && ShiftedImm->second) &&
1034 AArch64_AM::isSVECpyImm<T>(
uint64_t(ShiftedImm->first)
1035 << ShiftedImm->second))
1036 return DiagnosticPredicateTy::Match;
1038 return DiagnosticPredicateTy::NearMatch;
1045 if (!isShiftedImm() && (!
isImm() || !isa<MCConstantExpr>(getImm())))
1046 return DiagnosticPredicateTy::NoMatch;
1048 bool IsByte = std::is_same<int8_t, std::make_signed_t<T>>
::value ||
1049 std::is_same<int8_t, T>::value;
1050 if (
auto ShiftedImm = getShiftedVal<8>())
1051 if (!(IsByte && ShiftedImm->second) &&
1052 AArch64_AM::isSVEAddSubImm<T>(ShiftedImm->first
1053 << ShiftedImm->second))
1054 return DiagnosticPredicateTy::Match;
1056 return DiagnosticPredicateTy::NearMatch;
1060 if (isLogicalImm<T>() && !isSVECpyImm<T>())
1061 return DiagnosticPredicateTy::Match;
1062 return DiagnosticPredicateTy::NoMatch;
1065 bool isCondCode()
const {
return Kind == k_CondCode; }
1067 bool isSIMDImmType10()
const {
1077 bool isBranchTarget()
const {
1086 assert(
N > 0 &&
"Branch target immediate cannot be 0 bits!");
1087 return (Val >= -((1<<(
N-1)) << 2) && Val <= (((1<<(
N-1))-1) << 2));
1098 if (!AArch64AsmParser::classifySymbolRef(getImm(), ELFRefKind,
1099 DarwinRefKind, Addend)) {
1108 bool isMovWSymbolG3()
const {
1112 bool isMovWSymbolG2()
const {
1113 return isMovWSymbol(
1120 bool isMovWSymbolG1()
const {
1121 return isMovWSymbol(
1129 bool isMovWSymbolG0()
const {
1130 return isMovWSymbol(
1138 template<
int RegW
idth,
int Shift>
1139 bool isMOVZMovAlias()
const {
1140 if (!
isImm())
return false;
1153 template<
int RegW
idth,
int Shift>
1154 bool isMOVNMovAlias()
const {
1155 if (!
isImm())
return false;
1158 if (!CE)
return false;
1164 bool isFPImm()
const {
1165 return Kind == k_FPImm &&
1169 bool isBarrier()
const {
1170 return Kind == k_Barrier && !getBarriernXSModifier();
1172 bool isBarriernXS()
const {
1173 return Kind == k_Barrier && getBarriernXSModifier();
1175 bool isSysReg()
const {
return Kind == k_SysReg; }
1177 bool isMRSSystemRegister()
const {
1178 if (!isSysReg())
return false;
1180 return SysReg.MRSReg != -1U;
1183 bool isMSRSystemRegister()
const {
1184 if (!isSysReg())
return false;
1185 return SysReg.MSRReg != -1U;
1188 bool isSystemPStateFieldWithImm0_1()
const {
1189 if (!isSysReg())
return false;
1190 return AArch64PState::lookupPStateImm0_1ByEncoding(SysReg.PStateField);
1193 bool isSystemPStateFieldWithImm0_15()
const {
1196 return AArch64PState::lookupPStateImm0_15ByEncoding(SysReg.PStateField);
1199 bool isSVCR()
const {
1202 return SVCR.PStateField != -1U;
1205 bool isReg()
const override {
1206 return Kind == k_Register;
1209 bool isVectorList()
const {
return Kind == k_VectorList; }
1211 bool isScalarReg()
const {
1212 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar;
1215 bool isNeonVectorReg()
const {
1216 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector;
1219 bool isNeonVectorRegLo()
const {
1220 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1221 (AArch64MCRegisterClasses[AArch64::FPR128_loRegClassID].contains(
1223 AArch64MCRegisterClasses[AArch64::FPR64_loRegClassID].contains(
1227 bool isNeonVectorReg0to7()
const {
1228 return Kind == k_Register &&
Reg.Kind == RegKind::NeonVector &&
1229 (AArch64MCRegisterClasses[AArch64::FPR128_0to7RegClassID].contains(
1233 bool isMatrix()
const {
return Kind == k_MatrixRegister; }
1234 bool isMatrixTileList()
const {
return Kind == k_MatrixTileList; }
1236 template <
unsigned Class>
bool isSVEPredicateAsCounterReg()
const {
1239 case AArch64::PPRRegClassID:
1240 case AArch64::PPR_3bRegClassID:
1241 case AArch64::PPR_p8to15RegClassID:
1242 case AArch64::PNRRegClassID:
1243 case AArch64::PNR_p8to15RegClassID:
1244 RK = RegKind::SVEPredicateAsCounter;
1250 return (Kind == k_Register &&
Reg.Kind == RK) &&
1251 AArch64MCRegisterClasses[
Class].contains(
getReg());
1254 template <
unsigned Class>
bool isSVEVectorReg()
const {
1257 case AArch64::ZPRRegClassID:
1258 case AArch64::ZPR_3bRegClassID:
1259 case AArch64::ZPR_4bRegClassID:
1260 RK = RegKind::SVEDataVector;
1262 case AArch64::PPRRegClassID:
1263 case AArch64::PPR_3bRegClassID:
1264 case AArch64::PPR_p8to15RegClassID:
1265 case AArch64::PNRRegClassID:
1266 case AArch64::PNR_p8to15RegClassID:
1267 RK = RegKind::SVEPredicateVector;
1273 return (Kind == k_Register &&
Reg.Kind == RK) &&
1274 AArch64MCRegisterClasses[
Class].contains(
getReg());
1277 template <
unsigned Class>
bool isFPRasZPR()
const {
1278 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1279 AArch64MCRegisterClasses[
Class].contains(
getReg());
1282 template <
int ElementW
idth,
unsigned Class>
1284 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateVector)
1285 return DiagnosticPredicateTy::NoMatch;
1287 if (isSVEVectorReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1288 return DiagnosticPredicateTy::Match;
1290 return DiagnosticPredicateTy::NearMatch;
1293 template <
int ElementW
idth,
unsigned Class>
1295 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEPredicateAsCounter)
1296 return DiagnosticPredicateTy::NoMatch;
1298 if (isSVEPredicateAsCounterReg<Class>() && (
Reg.ElementWidth == ElementWidth))
1299 return DiagnosticPredicateTy::Match;
1301 return DiagnosticPredicateTy::NearMatch;
1304 template <
int ElementW
idth,
unsigned Class>
1306 if (Kind != k_Register ||
Reg.Kind != RegKind::SVEDataVector)
1307 return DiagnosticPredicateTy::NoMatch;
1309 if (isSVEVectorReg<Class>() &&
Reg.ElementWidth == ElementWidth)
1310 return DiagnosticPredicateTy::Match;
1312 return DiagnosticPredicateTy::NearMatch;
1315 template <
int ElementWidth,
unsigned Class,
1317 bool ShiftWidthAlwaysSame>
1319 auto VectorMatch = isSVEDataVectorRegOfWidth<ElementWidth, Class>();
1320 if (!VectorMatch.isMatch())
1321 return DiagnosticPredicateTy::NoMatch;
1326 bool MatchShift = getShiftExtendAmount() ==
Log2_32(ShiftWidth / 8);
1329 !ShiftWidthAlwaysSame && hasShiftExtendAmount() && ShiftWidth == 8)
1330 return DiagnosticPredicateTy::NoMatch;
1332 if (MatchShift && ShiftExtendTy == getShiftExtendType())
1333 return DiagnosticPredicateTy::Match;
1335 return DiagnosticPredicateTy::NearMatch;
1338 bool isGPR32as64()
const {
1339 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1340 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].contains(
Reg.RegNum);
1343 bool isGPR64as32()
const {
1344 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1345 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].contains(
Reg.RegNum);
1348 bool isGPR64x8()
const {
1349 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1350 AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID].contains(
1354 bool isWSeqPair()
const {
1355 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1356 AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID].contains(
1360 bool isXSeqPair()
const {
1361 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1362 AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID].contains(
1366 bool isSyspXzrPair()
const {
1367 return isGPR64<AArch64::GPR64RegClassID>() &&
Reg.RegNum == AArch64::XZR;
1370 template<
int64_t Angle,
int64_t Remainder>
1372 if (!
isImm())
return DiagnosticPredicateTy::NoMatch;
1375 if (!CE)
return DiagnosticPredicateTy::NoMatch;
1378 if (
Value % Angle == Remainder &&
Value <= 270)
1379 return DiagnosticPredicateTy::Match;
1380 return DiagnosticPredicateTy::NearMatch;
1383 template <
unsigned RegClassID>
bool isGPR64()
const {
1384 return Kind == k_Register &&
Reg.Kind == RegKind::Scalar &&
1385 AArch64MCRegisterClasses[RegClassID].contains(
getReg());
1388 template <
unsigned RegClassID,
int ExtW
idth>
1390 if (Kind != k_Register ||
Reg.Kind != RegKind::Scalar)
1391 return DiagnosticPredicateTy::NoMatch;
1393 if (isGPR64<RegClassID>() && getShiftExtendType() ==
AArch64_AM::LSL &&
1394 getShiftExtendAmount() ==
Log2_32(ExtWidth / 8))
1395 return DiagnosticPredicateTy::Match;
1396 return DiagnosticPredicateTy::NearMatch;
1401 template <RegKind VectorKind,
unsigned NumRegs>
1402 bool isImplicitlyTypedVectorList()
const {
1403 return Kind == k_VectorList && VectorList.Count == NumRegs &&
1404 VectorList.NumElements == 0 &&
1405 VectorList.RegisterKind == VectorKind;
1408 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1409 unsigned ElementWidth,
unsigned Stride = 1>
1410 bool isTypedVectorList()
const {
1411 if (Kind != k_VectorList)
1413 if (VectorList.Count != NumRegs)
1415 if (VectorList.RegisterKind != VectorKind)
1417 if (VectorList.ElementWidth != ElementWidth)
1419 if (VectorList.Stride != Stride)
1421 return VectorList.NumElements == NumElements;
1424 template <RegKind VectorKind,
unsigned NumRegs,
unsigned NumElements,
1425 unsigned ElementWidth>
1428 isTypedVectorList<VectorKind, NumRegs, NumElements, ElementWidth>();
1430 return DiagnosticPredicateTy::NoMatch;
1431 if (((VectorList.RegNum - AArch64::Z0) % NumRegs) != 0)
1432 return DiagnosticPredicateTy::NearMatch;
1433 return DiagnosticPredicateTy::Match;
1436 template <RegKind VectorKind,
unsigned NumRegs,
unsigned Stride,
1437 unsigned ElementWidth>
1439 bool Res = isTypedVectorList<VectorKind, NumRegs, 0,
1440 ElementWidth, Stride>();
1442 return DiagnosticPredicateTy::NoMatch;
1443 if ((VectorList.RegNum < (AArch64::Z0 + Stride)) ||
1444 ((VectorList.RegNum >= AArch64::Z16) &&
1445 (VectorList.RegNum < (AArch64::Z16 + Stride))))
1446 return DiagnosticPredicateTy::Match;
1447 return DiagnosticPredicateTy::NoMatch;
1450 template <
int Min,
int Max>
1452 if (Kind != k_VectorIndex)
1453 return DiagnosticPredicateTy::NoMatch;
1454 if (VectorIndex.Val >= Min && VectorIndex.Val <= Max)
1455 return DiagnosticPredicateTy::Match;
1456 return DiagnosticPredicateTy::NearMatch;
1459 bool isToken()
const override {
return Kind == k_Token; }
1461 bool isTokenEqual(
StringRef Str)
const {
1462 return Kind == k_Token && getToken() == Str;
1464 bool isSysCR()
const {
return Kind == k_SysCR; }
1465 bool isPrefetch()
const {
return Kind == k_Prefetch; }
1466 bool isPSBHint()
const {
return Kind == k_PSBHint; }
1467 bool isBTIHint()
const {
return Kind == k_BTIHint; }
1468 bool isShiftExtend()
const {
return Kind == k_ShiftExtend; }
1469 bool isShifter()
const {
1470 if (!isShiftExtend())
1480 if (Kind != k_FPImm)
1481 return DiagnosticPredicateTy::NoMatch;
1483 if (getFPImmIsExact()) {
1485 auto *
Desc = AArch64ExactFPImm::lookupExactFPImmByEnum(ImmEnum);
1489 APFloat RealVal(APFloat::IEEEdouble());
1491 RealVal.convertFromString(
Desc->Repr, APFloat::rmTowardZero);
1492 if (
errorToBool(StatusOrErr.takeError()) || *StatusOrErr != APFloat::opOK)
1495 if (
getFPImm().bitwiseIsEqual(RealVal))
1496 return DiagnosticPredicateTy::Match;
1499 return DiagnosticPredicateTy::NearMatch;
1502 template <
unsigned ImmA,
unsigned ImmB>
1505 if ((Res = isExactFPImm<ImmA>()))
1506 return DiagnosticPredicateTy::Match;
1507 if ((Res = isExactFPImm<ImmB>()))
1508 return DiagnosticPredicateTy::Match;
1512 bool isExtend()
const {
1513 if (!isShiftExtend())
1522 getShiftExtendAmount() <= 4;
1525 bool isExtend64()
const {
1535 bool isExtendLSL64()
const {
1541 getShiftExtendAmount() <= 4;
1544 bool isLSLImm3Shift()
const {
1545 if (!isShiftExtend())
1551 template<
int W
idth>
bool isMemXExtend()
const {
1556 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1557 getShiftExtendAmount() == 0);
1560 template<
int W
idth>
bool isMemWExtend()
const {
1565 (getShiftExtendAmount() ==
Log2_32(Width / 8) ||
1566 getShiftExtendAmount() == 0);
1569 template <
unsigned w
idth>
1570 bool isArithmeticShifter()
const {
1580 template <
unsigned w
idth>
1581 bool isLogicalShifter()
const {
1589 getShiftExtendAmount() < width;
1592 bool isMovImm32Shifter()
const {
1600 uint64_t Val = getShiftExtendAmount();
1601 return (Val == 0 || Val == 16);
1604 bool isMovImm64Shifter()
const {
1612 uint64_t Val = getShiftExtendAmount();
1613 return (Val == 0 || Val == 16 || Val == 32 || Val == 48);
1616 bool isLogicalVecShifter()
const {
1621 unsigned Shift = getShiftExtendAmount();
1623 (Shift == 0 || Shift == 8 || Shift == 16 || Shift == 24);
1626 bool isLogicalVecHalfWordShifter()
const {
1627 if (!isLogicalVecShifter())
1631 unsigned Shift = getShiftExtendAmount();
1633 (Shift == 0 || Shift == 8);
1636 bool isMoveVecShifter()
const {
1637 if (!isShiftExtend())
1641 unsigned Shift = getShiftExtendAmount();
1643 (Shift == 8 || Shift == 16);
1652 bool isSImm9OffsetFB()
const {
1653 return isSImm<9>() && !isUImm12Offset<Width / 8>();
1656 bool isAdrpLabel()
const {
1663 int64_t Val =
CE->getValue();
1664 int64_t Min = - (4096 * (1LL << (21 - 1)));
1665 int64_t
Max = 4096 * ((1LL << (21 - 1)) - 1);
1666 return (Val % 4096) == 0 && Val >= Min && Val <=
Max;
1672 bool isAdrLabel()
const {
1679 int64_t Val =
CE->getValue();
1680 int64_t Min = - (1LL << (21 - 1));
1681 int64_t
Max = ((1LL << (21 - 1)) - 1);
1682 return Val >= Min && Val <=
Max;
1688 template <MatrixKind Kind,
unsigned EltSize,
unsigned RegClass>
1691 return DiagnosticPredicateTy::NoMatch;
1692 if (getMatrixKind() != Kind ||
1693 !AArch64MCRegisterClasses[RegClass].
contains(getMatrixReg()) ||
1694 EltSize != getMatrixElementWidth())
1695 return DiagnosticPredicateTy::NearMatch;
1696 return DiagnosticPredicateTy::Match;
1699 bool isPAuthPCRelLabel16Operand()
const {
1711 return (Val <= 0) && (Val > -(1 << 18));
1718 else if (
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
1724 void addRegOperands(
MCInst &Inst,
unsigned N)
const {
1725 assert(
N == 1 &&
"Invalid number of operands!");
1729 void addMatrixOperands(
MCInst &Inst,
unsigned N)
const {
1730 assert(
N == 1 &&
"Invalid number of operands!");
1734 void addGPR32as64Operands(
MCInst &Inst,
unsigned N)
const {
1735 assert(
N == 1 &&
"Invalid number of operands!");
1737 AArch64MCRegisterClasses[AArch64::GPR64RegClassID].
contains(
getReg()));
1746 void addGPR64as32Operands(
MCInst &Inst,
unsigned N)
const {
1747 assert(
N == 1 &&
"Invalid number of operands!");
1749 AArch64MCRegisterClasses[AArch64::GPR32RegClassID].
contains(
getReg()));
1758 template <
int W
idth>
1759 void addFPRasZPRRegOperands(
MCInst &Inst,
unsigned N)
const {
1762 case 8:
Base = AArch64::B0;
break;
1763 case 16:
Base = AArch64::H0;
break;
1764 case 32:
Base = AArch64::S0;
break;
1765 case 64:
Base = AArch64::D0;
break;
1766 case 128:
Base = AArch64::Q0;
break;
1773 void addPNRasPPRRegOperands(
MCInst &Inst,
unsigned N)
const {
1774 assert(
N == 1 &&
"Invalid number of operands!");
1779 void addVectorReg64Operands(
MCInst &Inst,
unsigned N)
const {
1780 assert(
N == 1 &&
"Invalid number of operands!");
1782 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1786 void addVectorReg128Operands(
MCInst &Inst,
unsigned N)
const {
1787 assert(
N == 1 &&
"Invalid number of operands!");
1789 AArch64MCRegisterClasses[AArch64::FPR128RegClassID].
contains(
getReg()));
1793 void addVectorRegLoOperands(
MCInst &Inst,
unsigned N)
const {
1794 assert(
N == 1 &&
"Invalid number of operands!");
1798 void addVectorReg0to7Operands(
MCInst &Inst,
unsigned N)
const {
1799 assert(
N == 1 &&
"Invalid number of operands!");
1803 enum VecListIndexType {
1804 VecListIdx_DReg = 0,
1805 VecListIdx_QReg = 1,
1806 VecListIdx_ZReg = 2,
1807 VecListIdx_PReg = 3,
1810 template <VecListIndexType RegTy,
unsigned NumRegs>
1811 void addVectorListOperands(
MCInst &Inst,
unsigned N)
const {
1812 assert(
N == 1 &&
"Invalid number of operands!");
1813 static const unsigned FirstRegs[][5] = {
1815 AArch64::D0, AArch64::D0_D1,
1816 AArch64::D0_D1_D2, AArch64::D0_D1_D2_D3 },
1818 AArch64::Q0, AArch64::Q0_Q1,
1819 AArch64::Q0_Q1_Q2, AArch64::Q0_Q1_Q2_Q3 },
1821 AArch64::Z0, AArch64::Z0_Z1,
1822 AArch64::Z0_Z1_Z2, AArch64::Z0_Z1_Z2_Z3 },
1824 AArch64::P0, AArch64::P0_P1 }
1827 assert((RegTy != VecListIdx_ZReg || NumRegs <= 4) &&
1828 " NumRegs must be <= 4 for ZRegs");
1830 assert((RegTy != VecListIdx_PReg || NumRegs <= 2) &&
1831 " NumRegs must be <= 2 for PRegs");
1833 unsigned FirstReg = FirstRegs[(
unsigned)RegTy][NumRegs];
1835 FirstRegs[(
unsigned)RegTy][0]));
1838 template <
unsigned NumRegs>
1839 void addStridedVectorListOperands(
MCInst &Inst,
unsigned N)
const {
1840 assert(
N == 1 &&
"Invalid number of operands!");
1841 assert((NumRegs == 2 || NumRegs == 4) &&
" NumRegs must be 2 or 4");
1845 if (getVectorListStart() < AArch64::Z16) {
1846 assert((getVectorListStart() < AArch64::Z8) &&
1847 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1849 AArch64::Z0_Z8 + getVectorListStart() - AArch64::Z0));
1851 assert((getVectorListStart() < AArch64::Z24) &&
1852 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1854 AArch64::Z16_Z24 + getVectorListStart() - AArch64::Z16));
1858 if (getVectorListStart() < AArch64::Z16) {
1859 assert((getVectorListStart() < AArch64::Z4) &&
1860 (getVectorListStart() >= AArch64::Z0) &&
"Invalid Register");
1862 AArch64::Z0_Z4_Z8_Z12 + getVectorListStart() - AArch64::Z0));
1864 assert((getVectorListStart() < AArch64::Z20) &&
1865 (getVectorListStart() >= AArch64::Z16) &&
"Invalid Register");
1867 AArch64::Z16_Z20_Z24_Z28 + getVectorListStart() - AArch64::Z16));
1875 void addMatrixTileListOperands(
MCInst &Inst,
unsigned N)
const {
1876 assert(
N == 1 &&
"Invalid number of operands!");
1877 unsigned RegMask = getMatrixTileListRegMask();
1878 assert(RegMask <= 0xFF &&
"Invalid mask!");
1882 void addVectorIndexOperands(
MCInst &Inst,
unsigned N)
const {
1883 assert(
N == 1 &&
"Invalid number of operands!");
1887 template <
unsigned ImmIs0,
unsigned ImmIs1>
1888 void addExactFPImmOperands(
MCInst &Inst,
unsigned N)
const {
1889 assert(
N == 1 &&
"Invalid number of operands!");
1890 assert(
bool(isExactFPImm<ImmIs0, ImmIs1>()) &&
"Invalid operand");
1894 void addImmOperands(
MCInst &Inst,
unsigned N)
const {
1895 assert(
N == 1 &&
"Invalid number of operands!");
1899 addExpr(Inst, getImm());
1902 template <
int Shift>
1903 void addImmWithOptionalShiftOperands(
MCInst &Inst,
unsigned N)
const {
1904 assert(
N == 2 &&
"Invalid number of operands!");
1905 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1908 }
else if (isShiftedImm()) {
1909 addExpr(Inst, getShiftedImmVal());
1912 addExpr(Inst, getImm());
1917 template <
int Shift>
1918 void addImmNegWithOptionalShiftOperands(
MCInst &Inst,
unsigned N)
const {
1919 assert(
N == 2 &&
"Invalid number of operands!");
1920 if (
auto ShiftedVal = getShiftedVal<Shift>()) {
1927 void addCondCodeOperands(
MCInst &Inst,
unsigned N)
const {
1928 assert(
N == 1 &&
"Invalid number of operands!");
1932 void addAdrpLabelOperands(
MCInst &Inst,
unsigned N)
const {
1933 assert(
N == 1 &&
"Invalid number of operands!");
1936 addExpr(Inst, getImm());
1941 void addAdrLabelOperands(
MCInst &Inst,
unsigned N)
const {
1942 addImmOperands(Inst,
N);
1946 void addUImm12OffsetOperands(
MCInst &Inst,
unsigned N)
const {
1947 assert(
N == 1 &&
"Invalid number of operands!");
1957 void addUImm6Operands(
MCInst &Inst,
unsigned N)
const {
1958 assert(
N == 1 &&
"Invalid number of operands!");
1963 template <
int Scale>
1964 void addImmScaledOperands(
MCInst &Inst,
unsigned N)
const {
1965 assert(
N == 1 &&
"Invalid number of operands!");
1970 template <
int Scale>
1971 void addImmScaledRangeOperands(
MCInst &Inst,
unsigned N)
const {
1972 assert(
N == 1 &&
"Invalid number of operands!");
1976 template <
typename T>
1977 void addLogicalImmOperands(
MCInst &Inst,
unsigned N)
const {
1978 assert(
N == 1 &&
"Invalid number of operands!");
1980 std::make_unsigned_t<T> Val = MCE->
getValue();
1985 template <
typename T>
1986 void addLogicalImmNotOperands(
MCInst &Inst,
unsigned N)
const {
1987 assert(
N == 1 &&
"Invalid number of operands!");
1989 std::make_unsigned_t<T> Val = ~MCE->getValue();
1994 void addSIMDImmType10Operands(
MCInst &Inst,
unsigned N)
const {
1995 assert(
N == 1 &&
"Invalid number of operands!");
2001 void addBranchTarget26Operands(
MCInst &Inst,
unsigned N)
const {
2005 assert(
N == 1 &&
"Invalid number of operands!");
2008 addExpr(Inst, getImm());
2011 assert(MCE &&
"Invalid constant immediate operand!");
2015 void addPAuthPCRelLabel16Operands(
MCInst &Inst,
unsigned N)
const {
2019 assert(
N == 1 &&
"Invalid number of operands!");
2022 addExpr(Inst, getImm());
2028 void addPCRelLabel19Operands(
MCInst &Inst,
unsigned N)
const {
2032 assert(
N == 1 &&
"Invalid number of operands!");
2035 addExpr(Inst, getImm());
2038 assert(MCE &&
"Invalid constant immediate operand!");
2042 void addBranchTarget14Operands(
MCInst &Inst,
unsigned N)
const {
2046 assert(
N == 1 &&
"Invalid number of operands!");
2049 addExpr(Inst, getImm());
2052 assert(MCE &&
"Invalid constant immediate operand!");
2056 void addFPImmOperands(
MCInst &Inst,
unsigned N)
const {
2057 assert(
N == 1 &&
"Invalid number of operands!");
2062 void addBarrierOperands(
MCInst &Inst,
unsigned N)
const {
2063 assert(
N == 1 &&
"Invalid number of operands!");
2067 void addBarriernXSOperands(
MCInst &Inst,
unsigned N)
const {
2068 assert(
N == 1 &&
"Invalid number of operands!");
2072 void addMRSSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
2073 assert(
N == 1 &&
"Invalid number of operands!");
2078 void addMSRSystemRegisterOperands(
MCInst &Inst,
unsigned N)
const {
2079 assert(
N == 1 &&
"Invalid number of operands!");
2084 void addSystemPStateFieldWithImm0_1Operands(
MCInst &Inst,
unsigned N)
const {
2085 assert(
N == 1 &&
"Invalid number of operands!");
2090 void addSVCROperands(
MCInst &Inst,
unsigned N)
const {
2091 assert(
N == 1 &&
"Invalid number of operands!");
2096 void addSystemPStateFieldWithImm0_15Operands(
MCInst &Inst,
unsigned N)
const {
2097 assert(
N == 1 &&
"Invalid number of operands!");
2102 void addSysCROperands(
MCInst &Inst,
unsigned N)
const {
2103 assert(
N == 1 &&
"Invalid number of operands!");
2107 void addPrefetchOperands(
MCInst &Inst,
unsigned N)
const {
2108 assert(
N == 1 &&
"Invalid number of operands!");
2112 void addPSBHintOperands(
MCInst &Inst,
unsigned N)
const {
2113 assert(
N == 1 &&
"Invalid number of operands!");
2117 void addBTIHintOperands(
MCInst &Inst,
unsigned N)
const {
2118 assert(
N == 1 &&
"Invalid number of operands!");
2122 void addShifterOperands(
MCInst &Inst,
unsigned N)
const {
2123 assert(
N == 1 &&
"Invalid number of operands!");
2129 void addLSLImm3ShifterOperands(
MCInst &Inst,
unsigned N)
const {
2130 assert(
N == 1 &&
"Invalid number of operands!");
2131 unsigned Imm = getShiftExtendAmount();
2135 void addSyspXzrPairOperand(
MCInst &Inst,
unsigned N)
const {
2136 assert(
N == 1 &&
"Invalid number of operands!");
2144 if (
Reg != AArch64::XZR)
2150 void addExtendOperands(
MCInst &Inst,
unsigned N)
const {
2151 assert(
N == 1 &&
"Invalid number of operands!");
2158 void addExtend64Operands(
MCInst &Inst,
unsigned N)
const {
2159 assert(
N == 1 &&
"Invalid number of operands!");
2166 void addMemExtendOperands(
MCInst &Inst,
unsigned N)
const {
2167 assert(
N == 2 &&
"Invalid number of operands!");
2178 void addMemExtend8Operands(
MCInst &Inst,
unsigned N)
const {
2179 assert(
N == 2 &&
"Invalid number of operands!");
2187 void addMOVZMovAliasOperands(
MCInst &Inst,
unsigned N)
const {
2188 assert(
N == 1 &&
"Invalid number of operands!");
2195 addExpr(Inst, getImm());
2200 void addMOVNMovAliasOperands(
MCInst &Inst,
unsigned N)
const {
2201 assert(
N == 1 &&
"Invalid number of operands!");
2208 void addComplexRotationEvenOperands(
MCInst &Inst,
unsigned N)
const {
2209 assert(
N == 1 &&
"Invalid number of operands!");
2214 void addComplexRotationOddOperands(
MCInst &Inst,
unsigned N)
const {
2215 assert(
N == 1 &&
"Invalid number of operands!");
2222 static std::unique_ptr<AArch64Operand>
2224 auto Op = std::make_unique<AArch64Operand>(k_Token, Ctx);
2225 Op->Tok.Data = Str.data();
2226 Op->Tok.Length = Str.size();
2227 Op->Tok.IsSuffix = IsSuffix;
2233 static std::unique_ptr<AArch64Operand>
2235 RegConstraintEqualityTy EqTy = RegConstraintEqualityTy::EqualsReg,
2237 unsigned ShiftAmount = 0,
2238 unsigned HasExplicitAmount =
false) {
2239 auto Op = std::make_unique<AArch64Operand>(k_Register, Ctx);
2240 Op->Reg.RegNum = RegNum;
2242 Op->Reg.ElementWidth = 0;
2243 Op->Reg.EqualityTy = EqTy;
2244 Op->Reg.ShiftExtend.Type = ExtTy;
2245 Op->Reg.ShiftExtend.Amount = ShiftAmount;
2246 Op->Reg.ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2252 static std::unique_ptr<AArch64Operand>
2253 CreateVectorReg(
unsigned RegNum, RegKind Kind,
unsigned ElementWidth,
2256 unsigned ShiftAmount = 0,
2257 unsigned HasExplicitAmount =
false) {
2258 assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector ||
2259 Kind == RegKind::SVEPredicateVector ||
2260 Kind == RegKind::SVEPredicateAsCounter) &&
2261 "Invalid vector kind");
2262 auto Op = CreateReg(RegNum, Kind, S,
E, Ctx, EqualsReg, ExtTy, ShiftAmount,
2264 Op->Reg.ElementWidth = ElementWidth;
2268 static std::unique_ptr<AArch64Operand>
2269 CreateVectorList(
unsigned RegNum,
unsigned Count,
unsigned Stride,
2270 unsigned NumElements,
unsigned ElementWidth,
2272 auto Op = std::make_unique<AArch64Operand>(k_VectorList, Ctx);
2273 Op->VectorList.RegNum = RegNum;
2274 Op->VectorList.Count = Count;
2275 Op->VectorList.Stride = Stride;
2276 Op->VectorList.NumElements = NumElements;
2277 Op->VectorList.ElementWidth = ElementWidth;
2278 Op->VectorList.RegisterKind = RegisterKind;
2284 static std::unique_ptr<AArch64Operand>
2286 auto Op = std::make_unique<AArch64Operand>(k_VectorIndex, Ctx);
2287 Op->VectorIndex.Val =
Idx;
2293 static std::unique_ptr<AArch64Operand>
2295 auto Op = std::make_unique<AArch64Operand>(k_MatrixTileList, Ctx);
2296 Op->MatrixTileList.RegMask = RegMask;
2303 const unsigned ElementWidth) {
2304 static std::map<std::pair<unsigned, unsigned>, std::vector<unsigned>>
2306 {{0, AArch64::ZAB0},
2307 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2308 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2309 {{8, AArch64::ZAB0},
2310 {AArch64::ZAD0, AArch64::ZAD1, AArch64::ZAD2, AArch64::ZAD3,
2311 AArch64::ZAD4, AArch64::ZAD5, AArch64::ZAD6, AArch64::ZAD7}},
2312 {{16, AArch64::ZAH0},
2313 {AArch64::ZAD0, AArch64::ZAD2, AArch64::ZAD4, AArch64::ZAD6}},
2314 {{16, AArch64::ZAH1},
2315 {AArch64::ZAD1, AArch64::ZAD3, AArch64::ZAD5, AArch64::ZAD7}},
2316 {{32, AArch64::ZAS0}, {AArch64::ZAD0, AArch64::ZAD4}},
2317 {{32, AArch64::ZAS1}, {AArch64::ZAD1, AArch64::ZAD5}},
2318 {{32, AArch64::ZAS2}, {AArch64::ZAD2, AArch64::ZAD6}},
2319 {{32, AArch64::ZAS3}, {AArch64::ZAD3, AArch64::ZAD7}},
2322 if (ElementWidth == 64)
2325 std::vector<unsigned> Regs = RegMap[std::make_pair(ElementWidth,
Reg)];
2326 assert(!Regs.empty() &&
"Invalid tile or element width!");
2327 for (
auto OutReg : Regs)
2332 static std::unique_ptr<AArch64Operand> CreateImm(
const MCExpr *Val,
SMLoc S,
2334 auto Op = std::make_unique<AArch64Operand>(k_Immediate, Ctx);
2341 static std::unique_ptr<AArch64Operand> CreateShiftedImm(
const MCExpr *Val,
2342 unsigned ShiftAmount,
2345 auto Op = std::make_unique<AArch64Operand>(k_ShiftedImm, Ctx);
2346 Op->ShiftedImm .Val = Val;
2347 Op->ShiftedImm.ShiftAmount = ShiftAmount;
2353 static std::unique_ptr<AArch64Operand> CreateImmRange(
unsigned First,
2357 auto Op = std::make_unique<AArch64Operand>(k_ImmRange, Ctx);
2359 Op->ImmRange.Last =
Last;
2364 static std::unique_ptr<AArch64Operand>
2366 auto Op = std::make_unique<AArch64Operand>(k_CondCode, Ctx);
2367 Op->CondCode.Code =
Code;
2373 static std::unique_ptr<AArch64Operand>
2375 auto Op = std::make_unique<AArch64Operand>(k_FPImm, Ctx);
2377 Op->FPImm.IsExact = IsExact;
2383 static std::unique_ptr<AArch64Operand> CreateBarrier(
unsigned Val,
2387 bool HasnXSModifier) {
2388 auto Op = std::make_unique<AArch64Operand>(k_Barrier, Ctx);
2389 Op->Barrier.Val = Val;
2390 Op->Barrier.Data = Str.data();
2391 Op->Barrier.Length = Str.size();
2392 Op->Barrier.HasnXSModifier = HasnXSModifier;
2398 static std::unique_ptr<AArch64Operand> CreateSysReg(
StringRef Str,
SMLoc S,
2403 auto Op = std::make_unique<AArch64Operand>(k_SysReg, Ctx);
2404 Op->SysReg.Data = Str.data();
2405 Op->SysReg.Length = Str.size();
2406 Op->SysReg.MRSReg = MRSReg;
2407 Op->SysReg.MSRReg = MSRReg;
2408 Op->SysReg.PStateField = PStateField;
2414 static std::unique_ptr<AArch64Operand> CreateSysCR(
unsigned Val,
SMLoc S,
2416 auto Op = std::make_unique<AArch64Operand>(k_SysCR, Ctx);
2417 Op->SysCRImm.Val = Val;
2423 static std::unique_ptr<AArch64Operand> CreatePrefetch(
unsigned Val,
2427 auto Op = std::make_unique<AArch64Operand>(k_Prefetch, Ctx);
2428 Op->Prefetch.Val = Val;
2429 Op->Barrier.Data = Str.data();
2430 Op->Barrier.Length = Str.size();
2436 static std::unique_ptr<AArch64Operand> CreatePSBHint(
unsigned Val,
2440 auto Op = std::make_unique<AArch64Operand>(k_PSBHint, Ctx);
2441 Op->PSBHint.Val = Val;
2442 Op->PSBHint.Data = Str.data();
2443 Op->PSBHint.Length = Str.size();
2449 static std::unique_ptr<AArch64Operand> CreateBTIHint(
unsigned Val,
2453 auto Op = std::make_unique<AArch64Operand>(k_BTIHint, Ctx);
2454 Op->BTIHint.Val = Val | 32;
2455 Op->BTIHint.Data = Str.data();
2456 Op->BTIHint.Length = Str.size();
2462 static std::unique_ptr<AArch64Operand>
2463 CreateMatrixRegister(
unsigned RegNum,
unsigned ElementWidth, MatrixKind Kind,
2465 auto Op = std::make_unique<AArch64Operand>(k_MatrixRegister, Ctx);
2466 Op->MatrixReg.RegNum = RegNum;
2467 Op->MatrixReg.ElementWidth = ElementWidth;
2468 Op->MatrixReg.Kind =
Kind;
2474 static std::unique_ptr<AArch64Operand>
2476 auto Op = std::make_unique<AArch64Operand>(k_SVCR, Ctx);
2477 Op->SVCR.PStateField = PStateField;
2478 Op->SVCR.Data = Str.data();
2479 Op->SVCR.Length = Str.size();
2485 static std::unique_ptr<AArch64Operand>
2488 auto Op = std::make_unique<AArch64Operand>(k_ShiftExtend, Ctx);
2489 Op->ShiftExtend.Type = ShOp;
2490 Op->ShiftExtend.Amount = Val;
2491 Op->ShiftExtend.HasExplicitAmount = HasExplicitAmount;
2503 OS <<
"<fpimm " <<
getFPImm().bitcastToAPInt().getZExtValue();
2504 if (!getFPImmIsExact())
2511 OS <<
"<barrier " <<
Name <<
">";
2513 OS <<
"<barrier invalid #" << getBarrier() <<
">";
2519 case k_ShiftedImm: {
2520 unsigned Shift = getShiftedImmShift();
2521 OS <<
"<shiftedimm ";
2522 OS << *getShiftedImmVal();
2528 OS << getFirstImmVal();
2529 OS <<
":" << getLastImmVal() <<
">";
2535 case k_VectorList: {
2536 OS <<
"<vectorlist ";
2537 unsigned Reg = getVectorListStart();
2538 for (
unsigned i = 0, e = getVectorListCount(); i !=
e; ++i)
2539 OS <<
Reg + i * getVectorListStride() <<
" ";
2544 OS <<
"<vectorindex " << getVectorIndex() <<
">";
2547 OS <<
"<sysreg: " << getSysReg() <<
'>';
2550 OS <<
"'" << getToken() <<
"'";
2553 OS <<
"c" << getSysCR();
2558 OS <<
"<prfop " <<
Name <<
">";
2560 OS <<
"<prfop invalid #" << getPrefetch() <<
">";
2564 OS << getPSBHintName();
2567 OS << getBTIHintName();
2569 case k_MatrixRegister:
2570 OS <<
"<matrix " << getMatrixReg() <<
">";
2572 case k_MatrixTileList: {
2573 OS <<
"<matrixlist ";
2574 unsigned RegMask = getMatrixTileListRegMask();
2575 unsigned MaxBits = 8;
2576 for (
unsigned I = MaxBits;
I > 0; --
I)
2577 OS << ((RegMask & (1 << (
I - 1))) >> (
I - 1));
2586 OS <<
"<register " <<
getReg() <<
">";
2587 if (!getShiftExtendAmount() && !hasShiftExtendAmount())
2592 << getShiftExtendAmount();
2593 if (!hasShiftExtendAmount())
2609 .
Case(
"v0", AArch64::Q0)
2610 .
Case(
"v1", AArch64::Q1)
2611 .
Case(
"v2", AArch64::Q2)
2612 .
Case(
"v3", AArch64::Q3)
2613 .
Case(
"v4", AArch64::Q4)
2614 .
Case(
"v5", AArch64::Q5)
2615 .
Case(
"v6", AArch64::Q6)
2616 .
Case(
"v7", AArch64::Q7)
2617 .
Case(
"v8", AArch64::Q8)
2618 .
Case(
"v9", AArch64::Q9)
2619 .
Case(
"v10", AArch64::Q10)
2620 .
Case(
"v11", AArch64::Q11)
2621 .
Case(
"v12", AArch64::Q12)
2622 .
Case(
"v13", AArch64::Q13)
2623 .
Case(
"v14", AArch64::Q14)
2624 .
Case(
"v15", AArch64::Q15)
2625 .
Case(
"v16", AArch64::Q16)
2626 .
Case(
"v17", AArch64::Q17)
2627 .
Case(
"v18", AArch64::Q18)
2628 .
Case(
"v19", AArch64::Q19)
2629 .
Case(
"v20", AArch64::Q20)
2630 .
Case(
"v21", AArch64::Q21)
2631 .
Case(
"v22", AArch64::Q22)
2632 .
Case(
"v23", AArch64::Q23)
2633 .
Case(
"v24", AArch64::Q24)
2634 .
Case(
"v25", AArch64::Q25)
2635 .
Case(
"v26", AArch64::Q26)
2636 .
Case(
"v27", AArch64::Q27)
2637 .
Case(
"v28", AArch64::Q28)
2638 .
Case(
"v29", AArch64::Q29)
2639 .
Case(
"v30", AArch64::Q30)
2640 .
Case(
"v31", AArch64::Q31)
2649 RegKind VectorKind) {
2650 std::pair<int, int> Res = {-1, -1};
2652 switch (VectorKind) {
2653 case RegKind::NeonVector:
2656 .Case(
".1d", {1, 64})
2657 .Case(
".1q", {1, 128})
2659 .Case(
".2h", {2, 16})
2660 .Case(
".2b", {2, 8})
2661 .Case(
".2s", {2, 32})
2662 .Case(
".2d", {2, 64})
2665 .Case(
".4b", {4, 8})
2666 .Case(
".4h", {4, 16})
2667 .Case(
".4s", {4, 32})
2668 .Case(
".8b", {8, 8})
2669 .Case(
".8h", {8, 16})
2670 .Case(
".16b", {16, 8})
2675 .Case(
".h", {0, 16})
2676 .Case(
".s", {0, 32})
2677 .Case(
".d", {0, 64})
2680 case RegKind::SVEPredicateAsCounter:
2681 case RegKind::SVEPredicateVector:
2682 case RegKind::SVEDataVector:
2683 case RegKind::Matrix:
2687 .Case(
".h", {0, 16})
2688 .Case(
".s", {0, 32})
2689 .Case(
".d", {0, 64})
2690 .Case(
".q", {0, 128})
2697 if (Res == std::make_pair(-1, -1))
2698 return std::nullopt;
2700 return std::optional<std::pair<int, int>>(Res);
2709 .
Case(
"z0", AArch64::Z0)
2710 .
Case(
"z1", AArch64::Z1)
2711 .
Case(
"z2", AArch64::Z2)
2712 .
Case(
"z3", AArch64::Z3)
2713 .
Case(
"z4", AArch64::Z4)
2714 .
Case(
"z5", AArch64::Z5)
2715 .
Case(
"z6", AArch64::Z6)
2716 .
Case(
"z7", AArch64::Z7)
2717 .
Case(
"z8", AArch64::Z8)
2718 .
Case(
"z9", AArch64::Z9)
2719 .
Case(
"z10", AArch64::Z10)
2720 .
Case(
"z11", AArch64::Z11)
2721 .
Case(
"z12", AArch64::Z12)
2722 .
Case(
"z13", AArch64::Z13)
2723 .
Case(
"z14", AArch64::Z14)
2724 .
Case(
"z15", AArch64::Z15)
2725 .
Case(
"z16", AArch64::Z16)
2726 .
Case(
"z17", AArch64::Z17)
2727 .
Case(
"z18", AArch64::Z18)
2728 .
Case(
"z19", AArch64::Z19)
2729 .
Case(
"z20", AArch64::Z20)
2730 .
Case(
"z21", AArch64::Z21)
2731 .
Case(
"z22", AArch64::Z22)
2732 .
Case(
"z23", AArch64::Z23)
2733 .
Case(
"z24", AArch64::Z24)
2734 .
Case(
"z25", AArch64::Z25)
2735 .
Case(
"z26", AArch64::Z26)
2736 .
Case(
"z27", AArch64::Z27)
2737 .
Case(
"z28", AArch64::Z28)
2738 .
Case(
"z29", AArch64::Z29)
2739 .
Case(
"z30", AArch64::Z30)
2740 .
Case(
"z31", AArch64::Z31)
2746 .
Case(
"p0", AArch64::P0)
2747 .
Case(
"p1", AArch64::P1)
2748 .
Case(
"p2", AArch64::P2)
2749 .
Case(
"p3", AArch64::P3)
2750 .
Case(
"p4", AArch64::P4)
2751 .
Case(
"p5", AArch64::P5)
2752 .
Case(
"p6", AArch64::P6)
2753 .
Case(
"p7", AArch64::P7)
2754 .
Case(
"p8", AArch64::P8)
2755 .
Case(
"p9", AArch64::P9)
2756 .
Case(
"p10", AArch64::P10)
2757 .
Case(
"p11", AArch64::P11)
2758 .
Case(
"p12", AArch64::P12)
2759 .
Case(
"p13", AArch64::P13)
2760 .
Case(
"p14", AArch64::P14)
2761 .
Case(
"p15", AArch64::P15)
2767 .
Case(
"pn0", AArch64::PN0)
2768 .
Case(
"pn1", AArch64::PN1)
2769 .
Case(
"pn2", AArch64::PN2)
2770 .
Case(
"pn3", AArch64::PN3)
2771 .
Case(
"pn4", AArch64::PN4)
2772 .
Case(
"pn5", AArch64::PN5)
2773 .
Case(
"pn6", AArch64::PN6)
2774 .
Case(
"pn7", AArch64::PN7)
2775 .
Case(
"pn8", AArch64::PN8)
2776 .
Case(
"pn9", AArch64::PN9)
2777 .
Case(
"pn10", AArch64::PN10)
2778 .
Case(
"pn11", AArch64::PN11)
2779 .
Case(
"pn12", AArch64::PN12)
2780 .
Case(
"pn13", AArch64::PN13)
2781 .
Case(
"pn14", AArch64::PN14)
2782 .
Case(
"pn15", AArch64::PN15)
2788 .
Case(
"za0.d", AArch64::ZAD0)
2789 .
Case(
"za1.d", AArch64::ZAD1)
2790 .
Case(
"za2.d", AArch64::ZAD2)
2791 .
Case(
"za3.d", AArch64::ZAD3)
2792 .
Case(
"za4.d", AArch64::ZAD4)
2793 .
Case(
"za5.d", AArch64::ZAD5)
2794 .
Case(
"za6.d", AArch64::ZAD6)
2795 .
Case(
"za7.d", AArch64::ZAD7)
2796 .
Case(
"za0.s", AArch64::ZAS0)
2797 .
Case(
"za1.s", AArch64::ZAS1)
2798 .
Case(
"za2.s", AArch64::ZAS2)
2799 .
Case(
"za3.s", AArch64::ZAS3)
2800 .
Case(
"za0.h", AArch64::ZAH0)
2801 .
Case(
"za1.h", AArch64::ZAH1)
2802 .
Case(
"za0.b", AArch64::ZAB0)
2808 .
Case(
"za", AArch64::ZA)
2809 .
Case(
"za0.q", AArch64::ZAQ0)
2810 .
Case(
"za1.q", AArch64::ZAQ1)
2811 .
Case(
"za2.q", AArch64::ZAQ2)
2812 .
Case(
"za3.q", AArch64::ZAQ3)
2813 .
Case(
"za4.q", AArch64::ZAQ4)
2814 .
Case(
"za5.q", AArch64::ZAQ5)
2815 .
Case(
"za6.q", AArch64::ZAQ6)
2816 .
Case(
"za7.q", AArch64::ZAQ7)
2817 .
Case(
"za8.q", AArch64::ZAQ8)
2818 .
Case(
"za9.q", AArch64::ZAQ9)
2819 .
Case(
"za10.q", AArch64::ZAQ10)
2820 .
Case(
"za11.q", AArch64::ZAQ11)
2821 .
Case(
"za12.q", AArch64::ZAQ12)
2822 .
Case(
"za13.q", AArch64::ZAQ13)
2823 .
Case(
"za14.q", AArch64::ZAQ14)
2824 .
Case(
"za15.q", AArch64::ZAQ15)
2825 .
Case(
"za0.d", AArch64::ZAD0)
2826 .
Case(
"za1.d", AArch64::ZAD1)
2827 .
Case(
"za2.d", AArch64::ZAD2)
2828 .
Case(
"za3.d", AArch64::ZAD3)
2829 .
Case(
"za4.d", AArch64::ZAD4)
2830 .
Case(
"za5.d", AArch64::ZAD5)
2831 .
Case(
"za6.d", AArch64::ZAD6)
2832 .
Case(
"za7.d", AArch64::ZAD7)
2833 .
Case(
"za0.s", AArch64::ZAS0)
2834 .
Case(
"za1.s", AArch64::ZAS1)
2835 .
Case(
"za2.s", AArch64::ZAS2)
2836 .
Case(
"za3.s", AArch64::ZAS3)
2837 .
Case(
"za0.h", AArch64::ZAH0)
2838 .
Case(
"za1.h", AArch64::ZAH1)
2839 .
Case(
"za0.b", AArch64::ZAB0)
2840 .
Case(
"za0h.q", AArch64::ZAQ0)
2841 .
Case(
"za1h.q", AArch64::ZAQ1)
2842 .
Case(
"za2h.q", AArch64::ZAQ2)
2843 .
Case(
"za3h.q", AArch64::ZAQ3)
2844 .
Case(
"za4h.q", AArch64::ZAQ4)
2845 .
Case(
"za5h.q", AArch64::ZAQ5)
2846 .
Case(
"za6h.q", AArch64::ZAQ6)
2847 .
Case(
"za7h.q", AArch64::ZAQ7)
2848 .
Case(
"za8h.q", AArch64::ZAQ8)
2849 .
Case(
"za9h.q", AArch64::ZAQ9)
2850 .
Case(
"za10h.q", AArch64::ZAQ10)
2851 .
Case(
"za11h.q", AArch64::ZAQ11)
2852 .
Case(
"za12h.q", AArch64::ZAQ12)
2853 .
Case(
"za13h.q", AArch64::ZAQ13)
2854 .
Case(
"za14h.q", AArch64::ZAQ14)
2855 .
Case(
"za15h.q", AArch64::ZAQ15)
2856 .
Case(
"za0h.d", AArch64::ZAD0)
2857 .
Case(
"za1h.d", AArch64::ZAD1)
2858 .
Case(
"za2h.d", AArch64::ZAD2)
2859 .
Case(
"za3h.d", AArch64::ZAD3)
2860 .
Case(
"za4h.d", AArch64::ZAD4)
2861 .
Case(
"za5h.d", AArch64::ZAD5)
2862 .
Case(
"za6h.d", AArch64::ZAD6)
2863 .
Case(
"za7h.d", AArch64::ZAD7)
2864 .
Case(
"za0h.s", AArch64::ZAS0)
2865 .
Case(
"za1h.s", AArch64::ZAS1)
2866 .
Case(
"za2h.s", AArch64::ZAS2)
2867 .
Case(
"za3h.s", AArch64::ZAS3)
2868 .
Case(
"za0h.h", AArch64::ZAH0)
2869 .
Case(
"za1h.h", AArch64::ZAH1)
2870 .
Case(
"za0h.b", AArch64::ZAB0)
2871 .
Case(
"za0v.q", AArch64::ZAQ0)
2872 .
Case(
"za1v.q", AArch64::ZAQ1)
2873 .
Case(
"za2v.q", AArch64::ZAQ2)
2874 .
Case(
"za3v.q", AArch64::ZAQ3)
2875 .
Case(
"za4v.q", AArch64::ZAQ4)
2876 .
Case(
"za5v.q", AArch64::ZAQ5)
2877 .
Case(
"za6v.q", AArch64::ZAQ6)
2878 .
Case(
"za7v.q", AArch64::ZAQ7)
2879 .
Case(
"za8v.q", AArch64::ZAQ8)
2880 .
Case(
"za9v.q", AArch64::ZAQ9)
2881 .
Case(
"za10v.q", AArch64::ZAQ10)
2882 .
Case(
"za11v.q", AArch64::ZAQ11)
2883 .
Case(
"za12v.q", AArch64::ZAQ12)
2884 .
Case(
"za13v.q", AArch64::ZAQ13)
2885 .
Case(
"za14v.q", AArch64::ZAQ14)
2886 .
Case(
"za15v.q", AArch64::ZAQ15)
2887 .
Case(
"za0v.d", AArch64::ZAD0)
2888 .
Case(
"za1v.d", AArch64::ZAD1)
2889 .
Case(
"za2v.d", AArch64::ZAD2)
2890 .
Case(
"za3v.d", AArch64::ZAD3)
2891 .
Case(
"za4v.d", AArch64::ZAD4)
2892 .
Case(
"za5v.d", AArch64::ZAD5)
2893 .
Case(
"za6v.d", AArch64::ZAD6)
2894 .
Case(
"za7v.d", AArch64::ZAD7)
2895 .
Case(
"za0v.s", AArch64::ZAS0)
2896 .
Case(
"za1v.s", AArch64::ZAS1)
2897 .
Case(
"za2v.s", AArch64::ZAS2)
2898 .
Case(
"za3v.s", AArch64::ZAS3)
2899 .
Case(
"za0v.h", AArch64::ZAH0)
2900 .
Case(
"za1v.h", AArch64::ZAH1)
2901 .
Case(
"za0v.b", AArch64::ZAB0)
2907 return !tryParseRegister(
Reg, StartLoc, EndLoc).isSuccess();
2912 StartLoc = getLoc();
2919unsigned AArch64AsmParser::matchRegisterNameAlias(
StringRef Name,
2921 unsigned RegNum = 0;
2923 return Kind == RegKind::SVEDataVector ? RegNum : 0;
2926 return Kind == RegKind::SVEPredicateVector ? RegNum : 0;
2929 return Kind == RegKind::SVEPredicateAsCounter ? RegNum : 0;
2932 return Kind == RegKind::NeonVector ? RegNum : 0;
2935 return Kind == RegKind::Matrix ? RegNum : 0;
2937 if (
Name.equals_insensitive(
"zt0"))
2938 return Kind == RegKind::LookupTable ? AArch64::ZT0 : 0;
2942 return (Kind == RegKind::Scalar) ? RegNum : 0;
2947 .
Case(
"fp", AArch64::FP)
2948 .
Case(
"lr", AArch64::LR)
2949 .
Case(
"x31", AArch64::XZR)
2950 .
Case(
"w31", AArch64::WZR)
2952 return Kind == RegKind::Scalar ? RegNum : 0;
2957 auto Entry = RegisterReqs.
find(
Name.lower());
2958 if (Entry == RegisterReqs.
end())
2962 if (Kind == Entry->getValue().first)
2963 RegNum = Entry->getValue().second;
2968unsigned AArch64AsmParser::getNumRegsForRegKind(RegKind K) {
2970 case RegKind::Scalar:
2971 case RegKind::NeonVector:
2972 case RegKind::SVEDataVector:
2974 case RegKind::Matrix:
2975 case RegKind::SVEPredicateVector:
2976 case RegKind::SVEPredicateAsCounter:
2978 case RegKind::LookupTable:
2993 unsigned Reg = matchRegisterNameAlias(lowerCase, RegKind::Scalar);
3007 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3010 if (Tok[0] !=
'c' && Tok[0] !=
'C')
3011 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3015 if (BadNum || CRNum > 15)
3016 return Error(S,
"Expected cN operand where 0 <= N <= 15");
3020 AArch64Operand::CreateSysCR(CRNum, S, getLoc(), getContext()));
3029 unsigned MaxVal = 63;
3035 if (getParser().parseExpression(ImmVal))
3040 return TokError(
"immediate value expected for prefetch operand");
3043 return TokError(
"prefetch operand out of range, [0," + utostr(MaxVal) +
3046 auto RPRFM = AArch64RPRFM::lookupRPRFMByEncoding(MCE->
getValue());
3047 Operands.push_back(AArch64Operand::CreatePrefetch(
3048 prfop, RPRFM ? RPRFM->Name :
"", S, getContext()));
3053 return TokError(
"prefetch hint expected");
3055 auto RPRFM = AArch64RPRFM::lookupRPRFMByName(Tok.
getString());
3057 return TokError(
"prefetch hint expected");
3059 Operands.push_back(AArch64Operand::CreatePrefetch(
3060 RPRFM->Encoding, Tok.
getString(), S, getContext()));
3066template <
bool IsSVEPrefetch>
3072 if (IsSVEPrefetch) {
3073 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByName(
N))
3074 return std::optional<unsigned>(Res->Encoding);
3075 }
else if (
auto Res = AArch64PRFM::lookupPRFMByName(
N))
3076 return std::optional<unsigned>(Res->Encoding);
3077 return std::optional<unsigned>();
3080 auto LookupByEncoding = [](
unsigned E) {
3081 if (IsSVEPrefetch) {
3082 if (
auto Res = AArch64SVEPRFM::lookupSVEPRFMByEncoding(
E))
3083 return std::optional<StringRef>(Res->Name);
3084 }
else if (
auto Res = AArch64PRFM::lookupPRFMByEncoding(
E))
3085 return std::optional<StringRef>(Res->Name);
3086 return std::optional<StringRef>();
3088 unsigned MaxVal = IsSVEPrefetch ? 15 : 31;
3095 if (getParser().parseExpression(ImmVal))
3100 return TokError(
"immediate value expected for prefetch operand");
3103 return TokError(
"prefetch operand out of range, [0," + utostr(MaxVal) +
3106 auto PRFM = LookupByEncoding(MCE->
getValue());
3107 Operands.push_back(AArch64Operand::CreatePrefetch(prfop, PRFM.value_or(
""),
3113 return TokError(
"prefetch hint expected");
3115 auto PRFM = LookupByName(Tok.
getString());
3117 return TokError(
"prefetch hint expected");
3119 Operands.push_back(AArch64Operand::CreatePrefetch(
3120 *PRFM, Tok.
getString(), S, getContext()));
3130 return TokError(
"invalid operand for instruction");
3132 auto PSB = AArch64PSBHint::lookupPSBByName(Tok.
getString());
3134 return TokError(
"invalid operand for instruction");
3136 Operands.push_back(AArch64Operand::CreatePSBHint(
3137 PSB->Encoding, Tok.
getString(), S, getContext()));
3143 SMLoc StartLoc = getLoc();
3149 auto RegTok = getTok();
3150 if (!tryParseScalarRegister(RegNum).isSuccess())
3153 if (RegNum != AArch64::XZR) {
3154 getLexer().UnLex(RegTok);
3161 if (!tryParseScalarRegister(RegNum).isSuccess())
3162 return TokError(
"expected register operand");
3164 if (RegNum != AArch64::XZR)
3165 return TokError(
"xzr must be followed by xzr");
3169 Operands.push_back(AArch64Operand::CreateReg(
3170 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
3180 return TokError(
"invalid operand for instruction");
3182 auto BTI = AArch64BTIHint::lookupBTIByName(Tok.
getString());
3184 return TokError(
"invalid operand for instruction");
3186 Operands.push_back(AArch64Operand::CreateBTIHint(
3187 BTI->Encoding, Tok.
getString(), S, getContext()));
3196 const MCExpr *Expr =
nullptr;
3202 if (parseSymbolicImmVal(Expr))
3208 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3218 return Error(S,
"gotpage label reference not allowed an addend");
3228 return Error(S,
"page or gotpage label reference expected");
3236 Operands.push_back(AArch64Operand::CreateImm(Expr, S,
E, getContext()));
3245 const MCExpr *Expr =
nullptr;
3254 if (parseSymbolicImmVal(Expr))
3260 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
3267 return Error(S,
"unexpected adr label");
3272 Operands.push_back(AArch64Operand::CreateImm(Expr, S,
E, getContext()));
3277template <
bool AddFPZeroAsLiteral>
3290 return TokError(
"invalid floating point immediate");
3295 if (Tok.
getIntVal() > 255 || isNegative)
3296 return TokError(
"encoded floating point value out of range");
3300 AArch64Operand::CreateFPImm(
F,
true, S, getContext()));
3303 APFloat RealVal(APFloat::IEEEdouble());
3305 RealVal.convertFromString(Tok.
getString(), APFloat::rmTowardZero);
3307 return TokError(
"invalid floating point representation");
3310 RealVal.changeSign();
3312 if (AddFPZeroAsLiteral && RealVal.isPosZero()) {
3313 Operands.push_back(AArch64Operand::CreateToken(
"#0", S, getContext()));
3314 Operands.push_back(AArch64Operand::CreateToken(
".0", S, getContext()));
3316 Operands.push_back(AArch64Operand::CreateFPImm(
3317 RealVal, *StatusOrErr == APFloat::opOK, S, getContext()));
3342 if (parseSymbolicImmVal(Imm))
3346 AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
3353 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
3355 AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
3357 AArch64Operand::CreateToken(VecGroup, getLoc(), getContext()));
3363 !getTok().getIdentifier().equals_insensitive(
"lsl"))
3364 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3372 return Error(getLoc(),
"only 'lsl #+N' valid after immediate");
3374 int64_t ShiftAmount = getTok().getIntVal();
3376 if (ShiftAmount < 0)
3377 return Error(getLoc(),
"positive shift amount required");
3381 if (ShiftAmount == 0 && Imm !=
nullptr) {
3383 AArch64Operand::CreateImm(Imm, S, getLoc(), getContext()));
3387 Operands.push_back(AArch64Operand::CreateShiftedImm(Imm, ShiftAmount, S,
3388 getLoc(), getContext()));
3395AArch64AsmParser::parseCondCodeString(
StringRef Cond, std::string &Suggestion) {
3432 Suggestion =
"nfrst";
3439 bool invertCondCode) {
3445 std::string Suggestion;
3448 std::string
Msg =
"invalid condition code";
3449 if (!Suggestion.empty())
3450 Msg +=
", did you mean " + Suggestion +
"?";
3451 return TokError(Msg);
3455 if (invertCondCode) {
3457 return TokError(
"condition codes AL and NV are invalid for this instruction");
3462 AArch64Operand::CreateCondCode(
CC, S, getLoc(), getContext()));
3471 return TokError(
"invalid operand for instruction");
3473 unsigned PStateImm = -1;
3474 const auto *SVCR = AArch64SVCR::lookupSVCRByName(Tok.
getString());
3477 if (SVCR->haveFeatures(getSTI().getFeatureBits()))
3478 PStateImm = SVCR->Encoding;
3481 AArch64Operand::CreateSVCR(PStateImm, Tok.
getString(), S, getContext()));
3492 if (
Name.equals_insensitive(
"za") ||
Name.starts_with_insensitive(
"za.")) {
3494 unsigned ElementWidth = 0;
3495 auto DotPosition =
Name.find(
'.');
3497 const auto &KindRes =
3501 "Expected the register to be followed by element width suffix");
3502 ElementWidth = KindRes->second;
3504 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3505 AArch64::ZA, ElementWidth, MatrixKind::Array, S, getLoc(),
3510 if (parseOperand(
Operands,
false,
false))
3517 unsigned Reg = matchRegisterNameAlias(
Name, RegKind::Matrix);
3521 size_t DotPosition =
Name.find(
'.');
3529 .
Case(
"h", MatrixKind::Row)
3530 .
Case(
"v", MatrixKind::Col)
3537 "Expected the register to be followed by element width suffix");
3538 unsigned ElementWidth = KindRes->second;
3542 Operands.push_back(AArch64Operand::CreateMatrixRegister(
3543 Reg, ElementWidth, Kind, S, getLoc(), getContext()));
3548 if (parseOperand(
Operands,
false,
false))
3590 return TokError(
"expected #imm after shift specifier");
3596 AArch64Operand::CreateShiftExtend(ShOp, 0,
false, S,
E, getContext()));
3605 return Error(
E,
"expected integer shift amount");
3608 if (getParser().parseExpression(ImmVal))
3613 return Error(
E,
"expected constant '#imm' after shift specifier");
3616 Operands.push_back(AArch64Operand::CreateShiftExtend(
3617 ShOp, MCE->
getValue(),
true, S,
E, getContext()));
3625 {
"crc", {AArch64::FeatureCRC}},
3626 {
"sm4", {AArch64::FeatureSM4}},
3627 {
"sha3", {AArch64::FeatureSHA3}},
3628 {
"sha2", {AArch64::FeatureSHA2}},
3629 {
"aes", {AArch64::FeatureAES}},
3630 {
"crypto", {AArch64::FeatureCrypto}},
3631 {
"fp", {AArch64::FeatureFPARMv8}},
3632 {
"simd", {AArch64::FeatureNEON}},
3633 {
"ras", {AArch64::FeatureRAS}},
3634 {
"rasv2", {AArch64::FeatureRASv2}},
3635 {
"lse", {AArch64::FeatureLSE}},
3636 {
"predres", {AArch64::FeaturePredRes}},
3637 {
"predres2", {AArch64::FeatureSPECRES2}},
3638 {
"ccdp", {AArch64::FeatureCacheDeepPersist}},
3639 {
"mte", {AArch64::FeatureMTE}},
3640 {
"memtag", {AArch64::FeatureMTE}},
3641 {
"tlb-rmi", {AArch64::FeatureTLB_RMI}},
3642 {
"pan", {AArch64::FeaturePAN}},
3643 {
"pan-rwv", {AArch64::FeaturePAN_RWV}},
3644 {
"ccpp", {AArch64::FeatureCCPP}},
3645 {
"rcpc", {AArch64::FeatureRCPC}},
3646 {
"rng", {AArch64::FeatureRandGen}},
3647 {
"sve", {AArch64::FeatureSVE}},
3648 {
"sve2", {AArch64::FeatureSVE2}},
3649 {
"sve2-aes", {AArch64::FeatureSVE2AES}},
3650 {
"sve2-sm4", {AArch64::FeatureSVE2SM4}},
3651 {
"sve2-sha3", {AArch64::FeatureSVE2SHA3}},
3652 {
"sve2-bitperm", {AArch64::FeatureSVE2BitPerm}},
3653 {
"sve2p1", {AArch64::FeatureSVE2p1}},
3654 {
"b16b16", {AArch64::FeatureB16B16}},
3655 {
"ls64", {AArch64::FeatureLS64}},
3656 {
"xs", {AArch64::FeatureXS}},
3657 {
"pauth", {AArch64::FeaturePAuth}},
3658 {
"flagm", {AArch64::FeatureFlagM}},
3659 {
"rme", {AArch64::FeatureRME}},
3660 {
"sme", {AArch64::FeatureSME}},
3661 {
"sme-f64f64", {AArch64::FeatureSMEF64F64}},
3662 {
"sme-f16f16", {AArch64::FeatureSMEF16F16}},
3663 {
"sme-i16i64", {AArch64::FeatureSMEI16I64}},
3664 {
"sme2", {AArch64::FeatureSME2}},
3665 {
"sme2p1", {AArch64::FeatureSME2p1}},
3666 {
"hbc", {AArch64::FeatureHBC}},
3667 {
"mops", {AArch64::FeatureMOPS}},
3668 {
"mec", {AArch64::FeatureMEC}},
3669 {
"the", {AArch64::FeatureTHE}},
3670 {
"d128", {AArch64::FeatureD128}},
3671 {
"lse128", {AArch64::FeatureLSE128}},
3672 {
"ite", {AArch64::FeatureITE}},
3673 {
"cssc", {AArch64::FeatureCSSC}},
3674 {
"rcpc3", {AArch64::FeatureRCPC3}},
3675 {
"gcs", {AArch64::FeatureGCS}},
3676 {
"bf16", {AArch64::FeatureBF16}},
3677 {
"compnum", {AArch64::FeatureComplxNum}},
3678 {
"dotprod", {AArch64::FeatureDotProd}},
3679 {
"f32mm", {AArch64::FeatureMatMulFP32}},
3680 {
"f64mm", {AArch64::FeatureMatMulFP64}},
3681 {
"fp16", {AArch64::FeatureFullFP16}},
3682 {
"fp16fml", {AArch64::FeatureFP16FML}},
3683 {
"i8mm", {AArch64::FeatureMatMulInt8}},
3684 {
"lor", {AArch64::FeatureLOR}},
3685 {
"profile", {AArch64::FeatureSPE}},
3689 {
"rdm", {AArch64::FeatureRDM}},
3690 {
"rdma", {AArch64::FeatureRDM}},
3691 {
"sb", {AArch64::FeatureSB}},
3692 {
"ssbs", {AArch64::FeatureSSBS}},
3693 {
"tme", {AArch64::FeatureTME}},
3694 {
"fpmr", {AArch64::FeatureFPMR}},
3695 {
"fp8", {AArch64::FeatureFP8}},
3696 {
"faminmax", {AArch64::FeatureFAMINMAX}},
3697 {
"fp8fma", {AArch64::FeatureFP8FMA}},
3698 {
"ssve-fp8fma", {AArch64::FeatureSSVE_FP8FMA}},
3699 {
"fp8dot2", {AArch64::FeatureFP8DOT2}},
3700 {
"ssve-fp8dot2", {AArch64::FeatureSSVE_FP8DOT2}},
3701 {
"fp8dot4", {AArch64::FeatureFP8DOT4}},
3702 {
"ssve-fp8dot4", {AArch64::FeatureSSVE_FP8DOT4}},
3703 {
"lut", {AArch64::FeatureLUT}},
3704 {
"sme-lutv2", {AArch64::FeatureSME_LUTv2}},
3705 {
"sme-f8f16", {AArch64::FeatureSMEF8F16}},
3706 {
"sme-f8f32", {AArch64::FeatureSMEF8F32}},
3707 {
"sme-fa64", {AArch64::FeatureSMEFA64}},
3708 {
"cpa", {AArch64::FeatureCPA}},
3709 {
"tlbiw", {AArch64::FeatureTLBIW}},
3713 if (FBS[AArch64::HasV8_0aOps])
3715 if (FBS[AArch64::HasV8_1aOps])
3717 else if (FBS[AArch64::HasV8_2aOps])
3719 else if (FBS[AArch64::HasV8_3aOps])
3721 else if (FBS[AArch64::HasV8_4aOps])
3723 else if (FBS[AArch64::HasV8_5aOps])
3725 else if (FBS[AArch64::HasV8_6aOps])
3727 else if (FBS[AArch64::HasV8_7aOps])
3729 else if (FBS[AArch64::HasV8_8aOps])
3731 else if (FBS[AArch64::HasV8_9aOps])
3733 else if (FBS[AArch64::HasV9_0aOps])
3735 else if (FBS[AArch64::HasV9_1aOps])
3737 else if (FBS[AArch64::HasV9_2aOps])
3739 else if (FBS[AArch64::HasV9_3aOps])
3741 else if (FBS[AArch64::HasV9_4aOps])
3743 else if (FBS[AArch64::HasV9_5aOps])
3745 else if (FBS[AArch64::HasV8_0rOps])
3754 Str += !ExtMatches.
empty() ? llvm::join(ExtMatches,
", ") :
"(unknown)";
3761 const uint16_t Cm = (Encoding & 0x78) >> 3;
3762 const uint16_t Cn = (Encoding & 0x780) >> 7;
3763 const uint16_t Op1 = (Encoding & 0x3800) >> 11;
3768 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
3770 AArch64Operand::CreateSysCR(Cn, S, getLoc(), getContext()));
3772 AArch64Operand::CreateSysCR(Cm, S, getLoc(), getContext()));
3775 AArch64Operand::CreateImm(Expr, S, getLoc(), getContext()));
3782 if (
Name.contains(
'.'))
3783 return TokError(
"invalid operand");
3786 Operands.push_back(AArch64Operand::CreateToken(
"sys", NameLoc, getContext()));
3792 if (Mnemonic ==
"ic") {
3795 return TokError(
"invalid operand for IC instruction");
3796 else if (!IC->
haveFeatures(getSTI().getFeatureBits())) {
3797 std::string Str(
"IC " + std::string(IC->
Name) +
" requires: ");
3799 return TokError(Str);
3802 }
else if (Mnemonic ==
"dc") {
3805 return TokError(
"invalid operand for DC instruction");
3806 else if (!DC->
haveFeatures(getSTI().getFeatureBits())) {
3807 std::string Str(
"DC " + std::string(DC->
Name) +
" requires: ");
3809 return TokError(Str);
3812 }
else if (Mnemonic ==
"at") {
3815 return TokError(
"invalid operand for AT instruction");
3816 else if (!AT->
haveFeatures(getSTI().getFeatureBits())) {
3817 std::string Str(
"AT " + std::string(AT->
Name) +
" requires: ");
3819 return TokError(Str);
3822 }
else if (Mnemonic ==
"tlbi") {
3825 return TokError(
"invalid operand for TLBI instruction");
3826 else if (!TLBI->
haveFeatures(getSTI().getFeatureBits())) {
3827 std::string Str(
"TLBI " + std::string(TLBI->
Name) +
" requires: ");
3829 return TokError(Str);
3832 }
else if (Mnemonic ==
"cfp" || Mnemonic ==
"dvp" || Mnemonic ==
"cpp" || Mnemonic ==
"cosp") {
3834 if (
Op.lower() !=
"rctx")
3835 return TokError(
"invalid operand for prediction restriction instruction");
3837 bool hasAll = getSTI().hasFeature(AArch64::FeatureAll);
3838 bool hasPredres = hasAll || getSTI().hasFeature(AArch64::FeaturePredRes);
3839 bool hasSpecres2 = hasAll || getSTI().hasFeature(AArch64::FeatureSPECRES2);
3841 if (Mnemonic ==
"cosp" && !hasSpecres2)
3842 return TokError(
"COSP requires: predres2");
3844 return TokError(Mnemonic.
upper() +
"RCTX requires: predres");
3846 uint16_t PRCTX_Op2 = Mnemonic ==
"cfp" ? 0b100
3847 : Mnemonic ==
"dvp" ? 0b101
3848 : Mnemonic ==
"cosp" ? 0b110
3849 : Mnemonic ==
"cpp" ? 0b111
3852 "Invalid mnemonic for prediction restriction instruction");
3853 const auto SYS_3_7_3 = 0b01101110011;
3854 const auto Encoding = SYS_3_7_3 << 3 | PRCTX_Op2;
3856 createSysAlias(Encoding,
Operands, S);
3861 bool ExpectRegister = !
Op.contains_insensitive(
"all");
3862 bool HasRegister =
false;
3867 return TokError(
"expected register operand");
3871 if (ExpectRegister && !HasRegister)
3872 return TokError(
"specified " + Mnemonic +
" op requires a register");
3873 else if (!ExpectRegister && HasRegister)
3874 return TokError(
"specified " + Mnemonic +
" op does not use a register");
3886 if (
Name.contains(
'.'))
3887 return TokError(
"invalid operand");
3891 AArch64Operand::CreateToken(
"sysp", NameLoc, getContext()));
3897 if (Mnemonic ==
"tlbip") {
3898 bool HasnXSQualifier =
Op.ends_with_insensitive(
"nXS");
3899 if (HasnXSQualifier) {
3900 Op =
Op.drop_back(3);
3904 return TokError(
"invalid operand for TLBIP instruction");
3906 TLBIorig->
Name, TLBIorig->
Encoding | (HasnXSQualifier ? (1 << 7) : 0),
3913 std::string(TLBI.
Name) + (HasnXSQualifier ?
"nXS" :
"");
3914 std::string Str(
"TLBIP " +
Name +
" requires: ");
3916 return TokError(Str);
3927 return TokError(
"expected register identifier");
3932 return TokError(
"specified " + Mnemonic +
3933 " op requires a pair of registers");
3946 return TokError(
"'csync' operand expected");
3950 SMLoc ExprLoc = getLoc();
3952 if (getParser().parseExpression(ImmVal))
3956 return Error(ExprLoc,
"immediate value expected for barrier operand");
3958 if (Mnemonic ==
"dsb" &&
Value > 15) {
3965 if (Value < 0 || Value > 15)
3966 return Error(ExprLoc,
"barrier operand out of range");
3967 auto DB = AArch64DB::lookupDBByEncoding(
Value);
3968 Operands.push_back(AArch64Operand::CreateBarrier(
Value, DB ?
DB->Name :
"",
3969 ExprLoc, getContext(),
3975 return TokError(
"invalid operand for instruction");
3978 auto TSB = AArch64TSB::lookupTSBByName(Operand);
3979 auto DB = AArch64DB::lookupDBByName(Operand);
3981 if (Mnemonic ==
"isb" && (!DB ||
DB->Encoding != AArch64DB::sy))
3982 return TokError(
"'sy' or #imm operand expected");
3984 if (Mnemonic ==
"tsb" && (!TSB || TSB->Encoding != AArch64TSB::csync))
3985 return TokError(
"'csync' operand expected");
3987 if (Mnemonic ==
"dsb") {
3992 return TokError(
"invalid barrier option name");
3995 Operands.push_back(AArch64Operand::CreateBarrier(
3996 DB ?
DB->Encoding : TSB->Encoding, Tok.
getString(), getLoc(),
3997 getContext(),
false ));
4007 assert(Mnemonic ==
"dsb" &&
"Instruction does not accept nXS operands");
4008 if (Mnemonic !=
"dsb")
4014 SMLoc ExprLoc = getLoc();
4015 if (getParser().parseExpression(ImmVal))
4019 return Error(ExprLoc,
"immediate value expected for barrier operand");
4024 return Error(ExprLoc,
"barrier operand out of range");
4025 auto DB = AArch64DBnXS::lookupDBnXSByImmValue(
Value);
4026 Operands.push_back(AArch64Operand::CreateBarrier(
DB->Encoding,
DB->Name,
4027 ExprLoc, getContext(),
4033 return TokError(
"invalid operand for instruction");
4036 auto DB = AArch64DBnXS::lookupDBnXSByName(Operand);
4039 return TokError(
"invalid barrier option name");
4042 AArch64Operand::CreateBarrier(
DB->Encoding, Tok.
getString(), getLoc(),
4043 getContext(),
true ));
4055 if (AArch64SVCR::lookupSVCRByName(Tok.
getString()))
4060 if (SysReg && SysReg->haveFeatures(getSTI().getFeatureBits())) {
4061 MRSReg = SysReg->Readable ? SysReg->Encoding : -1;
4062 MSRReg = SysReg->Writeable ? SysReg->Encoding : -1;
4066 unsigned PStateImm = -1;
4067 auto PState15 = AArch64PState::lookupPStateImm0_15ByName(Tok.
getString());
4068 if (PState15 && PState15->haveFeatures(getSTI().getFeatureBits()))
4069 PStateImm = PState15->Encoding;
4071 auto PState1 = AArch64PState::lookupPStateImm0_1ByName(Tok.
getString());
4072 if (PState1 && PState1->haveFeatures(getSTI().getFeatureBits()))
4073 PStateImm = PState1->Encoding;
4077 AArch64Operand::CreateSysReg(Tok.
getString(), getLoc(), MRSReg, MSRReg,
4078 PStateImm, getContext()));
4093 ParseStatus Res = tryParseVectorRegister(Reg, Kind, RegKind::NeonVector);
4101 unsigned ElementWidth = KindRes->second;
4103 AArch64Operand::CreateVectorReg(Reg, RegKind::NeonVector, ElementWidth,
4104 S, getLoc(), getContext()));
4109 Operands.push_back(AArch64Operand::CreateToken(Kind, S, getContext()));
4111 return tryParseVectorIndex(
Operands).isFailure();
4115 SMLoc SIdx = getLoc();
4118 if (getParser().parseExpression(ImmVal))
4122 return TokError(
"immediate value expected for vector index");
4129 Operands.push_back(AArch64Operand::CreateVectorIndex(MCE->
getValue(), SIdx,
4142 RegKind MatchKind) {
4151 size_t Start = 0, Next =
Name.find(
'.');
4153 unsigned RegNum = matchRegisterNameAlias(Head, MatchKind);
4159 return TokError(
"invalid vector kind qualifier");
4171template <RegKind RK>
4175 const SMLoc S = getLoc();
4178 auto Res = tryParseVectorRegister(RegNum, Kind, RK);
4186 unsigned ElementWidth = KindRes->second;
4187 Operands.push_back(AArch64Operand::CreateVectorReg(
4188 RegNum, RK, ElementWidth, S,
4189 getLoc(), getContext()));
4192 if (RK == RegKind::SVEPredicateAsCounter) {
4199 if (parseOperand(
Operands,
false,
false))
4210 return Error(S,
"not expecting size suffix");
4213 Operands.push_back(AArch64Operand::CreateToken(
"/", getLoc(), getContext()));
4218 auto Pred = getTok().getString().lower();
4219 if (RK == RegKind::SVEPredicateAsCounter && Pred !=
"z")
4220 return Error(getLoc(),
"expecting 'z' predication");
4222 if (RK == RegKind::SVEPredicateVector && Pred !=
"z" && Pred !=
"m")
4223 return Error(getLoc(),
"expecting 'm' or 'z' predication");
4226 const char *ZM = Pred ==
"z" ?
"z" :
"m";
4227 Operands.push_back(AArch64Operand::CreateToken(ZM, getLoc(), getContext()));
4236 if (!tryParseNeonVectorRegister(
Operands))
4239 if (tryParseZTOperand(
Operands).isSuccess())
4243 if (tryParseGPROperand<false>(
Operands).isSuccess())
4249bool AArch64AsmParser::parseSymbolicImmVal(
const MCExpr *&ImmVal) {
4250 bool HasELFModifier =
false;
4254 HasELFModifier =
true;
4257 return TokError(
"expect relocation specifier in operand after ':'");
4259 std::string LowerCase = getTok().getIdentifier().lower();
4310 return TokError(
"expect relocation specifier in operand after ':'");
4314 if (parseToken(
AsmToken::Colon,
"expect ':' after relocation specifier"))
4318 if (getParser().parseExpression(ImmVal))
4331 auto ParseMatrixTile = [
this](
unsigned &
Reg,
4334 size_t DotPosition =
Name.find(
'.');
4343 const std::optional<std::pair<int, int>> &KindRes =
4347 "Expected the register to be followed by element width suffix");
4348 ElementWidth = KindRes->second;
4355 auto LCurly = getTok();
4360 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4361 0, S, getLoc(), getContext()));
4366 if (getTok().getString().equals_insensitive(
"za")) {
4372 Operands.push_back(AArch64Operand::CreateMatrixTileList(
4373 0xFF, S, getLoc(), getContext()));
4377 SMLoc TileLoc = getLoc();
4379 unsigned FirstReg, ElementWidth;
4380 auto ParseRes = ParseMatrixTile(FirstReg, ElementWidth);
4381 if (!ParseRes.isSuccess()) {
4382 getLexer().UnLex(LCurly);
4388 unsigned PrevReg = FirstReg;
4391 AArch64Operand::ComputeRegsForAlias(FirstReg, DRegs, ElementWidth);
4394 SeenRegs.
insert(FirstReg);
4398 unsigned Reg, NextElementWidth;
4399 ParseRes = ParseMatrixTile(Reg, NextElementWidth);
4400 if (!ParseRes.isSuccess())
4404 if (ElementWidth != NextElementWidth)
4405 return Error(TileLoc,
"mismatched register size suffix");
4408 Warning(TileLoc,
"tile list not in ascending order");
4411 Warning(TileLoc,
"duplicate tile in list");
4414 AArch64Operand::ComputeRegsForAlias(Reg, DRegs, ElementWidth);
4423 unsigned RegMask = 0;
4424 for (
auto Reg : DRegs)
4428 AArch64Operand::CreateMatrixTileList(RegMask, S, getLoc(), getContext()));
4433template <RegKind VectorKind>
4443 auto RegTok = getTok();
4444 auto ParseRes = tryParseVectorRegister(Reg, Kind, VectorKind);
4445 if (ParseRes.isSuccess()) {
4452 RegTok.getString().equals_insensitive(
"zt0"))
4456 (ParseRes.isNoMatch() && NoMatchIsError &&
4457 !RegTok.getString().starts_with_insensitive(
"za")))
4458 return Error(Loc,
"vector register expected");
4463 int NumRegs = getNumRegsForRegKind(VectorKind);
4465 auto LCurly = getTok();
4470 auto ParseRes = ParseVector(FirstReg, Kind, getLoc(), ExpectMatch);
4474 if (ParseRes.isNoMatch())
4477 if (!ParseRes.isSuccess())
4480 int64_t PrevReg = FirstReg;
4485 SMLoc Loc = getLoc();
4489 ParseRes = ParseVector(Reg, NextKind, getLoc(),
true);
4490 if (!ParseRes.isSuccess())
4494 if (Kind != NextKind)
4495 return Error(Loc,
"mismatched register size suffix");
4498 (PrevReg <
Reg) ? (Reg - PrevReg) : (
Reg + NumRegs - PrevReg);
4500 if (Space == 0 || Space > 3)
4501 return Error(Loc,
"invalid number of vectors");
4506 bool HasCalculatedStride =
false;
4508 SMLoc Loc = getLoc();
4511 ParseRes = ParseVector(Reg, NextKind, getLoc(),
true);
4512 if (!ParseRes.isSuccess())
4516 if (Kind != NextKind)
4517 return Error(Loc,
"mismatched register size suffix");
4519 unsigned RegVal = getContext().getRegisterInfo()->getEncodingValue(Reg);
4520 unsigned PrevRegVal =
4521 getContext().getRegisterInfo()->getEncodingValue(PrevReg);
4522 if (!HasCalculatedStride) {
4523 Stride = (PrevRegVal < RegVal) ? (RegVal - PrevRegVal)
4524 : (RegVal + NumRegs - PrevRegVal);
4525 HasCalculatedStride =
true;
4529 if (Stride == 0 || RegVal != ((PrevRegVal + Stride) % NumRegs))
4530 return Error(Loc,
"registers must have the same sequential stride");
4541 return Error(S,
"invalid number of vectors");
4543 unsigned NumElements = 0;
4544 unsigned ElementWidth = 0;
4545 if (!
Kind.empty()) {
4547 std::tie(NumElements, ElementWidth) = *VK;
4550 Operands.push_back(AArch64Operand::CreateVectorList(
4551 FirstReg, Count, Stride, NumElements, ElementWidth, VectorKind, S,
4552 getLoc(), getContext()));
4559 auto ParseRes = tryParseVectorList<RegKind::NeonVector>(
Operands,
true);
4560 if (!ParseRes.isSuccess())
4563 return tryParseVectorIndex(
Operands).isFailure();
4567 SMLoc StartLoc = getLoc();
4575 Operands.push_back(AArch64Operand::CreateReg(
4576 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
4583 return Error(getLoc(),
"index must be absent or #0");
4586 if (getParser().parseExpression(ImmVal) || !isa<MCConstantExpr>(ImmVal) ||
4587 cast<MCConstantExpr>(ImmVal)->getValue() != 0)
4588 return Error(getLoc(),
"index must be absent or #0");
4590 Operands.push_back(AArch64Operand::CreateReg(
4591 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext()));
4596 SMLoc StartLoc = getLoc();
4600 unsigned RegNum = matchRegisterNameAlias(
Name, RegKind::LookupTable);
4605 Operands.push_back(AArch64Operand::CreateReg(
4606 RegNum, RegKind::LookupTable, StartLoc, getLoc(), getContext()));
4612 AArch64Operand::CreateToken(
"[", getLoc(), getContext()));
4614 if (getParser().parseExpression(ImmVal))
4618 return TokError(
"immediate value expected for vector index");
4619 Operands.push_back(AArch64Operand::CreateImm(
4621 getLoc(), getContext()));
4623 if (parseOptionalMulOperand(
Operands))
4628 AArch64Operand::CreateToken(
"]", getLoc(), getContext()));
4633template <
bool ParseShiftExtend, RegConstra
intEqualityTy EqTy>
4635 SMLoc StartLoc = getLoc();
4644 Operands.push_back(AArch64Operand::CreateReg(
4645 RegNum, RegKind::Scalar, StartLoc, getLoc(), getContext(), EqTy));
4654 Res = tryParseOptionalShiftExtend(ExtOpnd);
4658 auto Ext =
static_cast<AArch64Operand*
>(ExtOpnd.
back().get());
4659 Operands.push_back(AArch64Operand::CreateReg(
4660 RegNum, RegKind::Scalar, StartLoc,
Ext->getEndLoc(), getContext(), EqTy,
4661 Ext->getShiftExtendType(),
Ext->getShiftExtendAmount(),
4662 Ext->hasShiftExtendAmount()));
4676 if (!getTok().getString().equals_insensitive(
"mul") ||
4677 !(NextIsVL || NextIsHash))
4681 AArch64Operand::CreateToken(
"mul", getLoc(), getContext()));
4686 AArch64Operand::CreateToken(
"vl", getLoc(), getContext()));
4698 if (
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(ImmVal)) {
4699 Operands.push_back(AArch64Operand::CreateImm(
4706 return Error(getLoc(),
"expected 'vl' or '#<imm>'");
4712 auto Tok = Parser.
getTok();
4717 .
Case(
"vgx2",
"vgx2")
4718 .
Case(
"vgx4",
"vgx4")
4730 auto Tok = getTok();
4740 AArch64Operand::CreateToken(Keyword, Tok.
getLoc(), getContext()));
4749 bool invertCondCode) {
4753 MatchOperandParserImpl(
Operands, Mnemonic,
true);
4767 auto parseOptionalShiftExtend = [&](
AsmToken SavedTok) {
4772 getLexer().UnLex(SavedTok);
4776 switch (getLexer().getKind()) {
4780 if (parseSymbolicImmVal(Expr))
4781 return Error(S,
"invalid operand");
4784 Operands.push_back(AArch64Operand::CreateImm(Expr, S,
E, getContext()));
4785 return parseOptionalShiftExtend(getTok());
4789 AArch64Operand::CreateToken(
"[", getLoc(), getContext()));
4794 return parseOperand(
Operands,
false,
false);
4797 if (!parseNeonVectorList(
Operands))
4801 AArch64Operand::CreateToken(
"{", getLoc(), getContext()));
4806 return parseOperand(
Operands,
false,
false);
4811 if (!parseOptionalVGOperand(
Operands, VecGroup)) {
4813 AArch64Operand::CreateToken(VecGroup, getLoc(), getContext()));
4818 return parseCondCode(
Operands, invertCondCode);
4832 Res = tryParseOptionalShiftExtend(
Operands);
4835 getLexer().UnLex(SavedTok);
4842 if (!parseOptionalMulOperand(
Operands))
4847 if (Mnemonic ==
"brb" || Mnemonic ==
"smstart" || Mnemonic ==
"smstop" ||
4849 return parseKeywordOperand(
Operands);
4855 if (getParser().parseExpression(IdVal))
4858 Operands.push_back(AArch64Operand::CreateImm(IdVal, S,
E, getContext()));
4870 bool isNegative =
false;
4886 if (Mnemonic !=
"fcmp" && Mnemonic !=
"fcmpe" && Mnemonic !=
"fcmeq" &&
4887 Mnemonic !=
"fcmge" && Mnemonic !=
"fcmgt" && Mnemonic !=
"fcmle" &&
4888 Mnemonic !=
"fcmlt" && Mnemonic !=
"fcmne")
4889 return TokError(
"unexpected floating point literal");
4890 else if (IntVal != 0 || isNegative)
4891 return TokError(
"expected floating-point constant #0.0");
4894 Operands.push_back(AArch64Operand::CreateToken(
"#0", S, getContext()));
4895 Operands.push_back(AArch64Operand::CreateToken(
".0", S, getContext()));
4900 if (parseSymbolicImmVal(ImmVal))
4904 Operands.push_back(AArch64Operand::CreateImm(ImmVal, S,
E, getContext()));
4907 return parseOptionalShiftExtend(Tok);
4910 SMLoc Loc = getLoc();
4911 if (Mnemonic !=
"ldr")
4912 return TokError(
"unexpected token in operand");
4914 const MCExpr *SubExprVal;
4915 if (getParser().parseExpression(SubExprVal))
4919 !
static_cast<AArch64Operand &
>(*
Operands[1]).isScalarReg())
4920 return Error(Loc,
"Only valid when first operand is register");
4923 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
4929 if (isa<MCConstantExpr>(SubExprVal)) {
4930 uint64_t Imm = (cast<MCConstantExpr>(SubExprVal))->getValue();
4931 uint32_t ShiftAmt = 0, MaxShiftAmt = IsXReg ? 48 : 16;
4936 if (ShiftAmt <= MaxShiftAmt && Imm <= 0xFFFF) {
4937 Operands[0] = AArch64Operand::CreateToken(
"movz", Loc, Ctx);
4938 Operands.push_back(AArch64Operand::CreateImm(
4942 ShiftAmt,
true, S,
E, Ctx));
4948 return Error(Loc,
"Immediate too large for register");
4952 getTargetStreamer().addConstantPoolEntry(SubExprVal, IsXReg ? 8 : 4, Loc);
4953 Operands.push_back(AArch64Operand::CreateImm(CPLoc, S,
E, Ctx));
4959bool AArch64AsmParser::parseImmExpr(int64_t &Out) {
4960 const MCExpr *Expr =
nullptr;
4962 if (
check(getParser().parseExpression(Expr), L,
"expected expression"))
4965 if (
check(!
Value, L,
"expected constant expression"))
4967 Out =
Value->getValue();
4971bool AArch64AsmParser::parseComma() {
4979bool AArch64AsmParser::parseRegisterInRange(
unsigned &Out,
unsigned Base,
4983 if (
check(parseRegister(Reg, Start,
End), getLoc(),
"expected register"))
4988 unsigned RangeEnd =
Last;
4989 if (
Base == AArch64::X0) {
4990 if (
Last == AArch64::FP) {
4991 RangeEnd = AArch64::X28;
4992 if (Reg == AArch64::FP) {
4997 if (
Last == AArch64::LR) {
4998 RangeEnd = AArch64::X28;
4999 if (Reg == AArch64::FP) {
5002 }
else if (Reg == AArch64::LR) {
5009 if (
check(Reg < First || Reg > RangeEnd, Start,
5010 Twine(
"expected register in range ") +
5020 auto &AOp1 =
static_cast<const AArch64Operand&
>(Op1);
5021 auto &AOp2 =
static_cast<const AArch64Operand&
>(Op2);
5023 if (AOp1.isVectorList() && AOp2.isVectorList())
5024 return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
5025 AOp1.getVectorListStart() == AOp2.getVectorListStart() &&
5026 AOp1.getVectorListStride() == AOp2.getVectorListStride();
5028 if (!AOp1.isReg() || !AOp2.isReg())
5031 if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
5032 AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
5035 assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
5036 "Testing equality of non-scalar registers not supported");
5039 if (AOp1.getRegEqualityTy() == EqualsSuperReg)
5041 if (AOp1.getRegEqualityTy() == EqualsSubReg)
5043 if (AOp2.getRegEqualityTy() == EqualsSuperReg)
5045 if (AOp2.getRegEqualityTy() == EqualsSubReg)
5057 .
Case(
"beq",
"b.eq")
5058 .
Case(
"bne",
"b.ne")
5059 .
Case(
"bhs",
"b.hs")
5060 .
Case(
"bcs",
"b.cs")
5061 .
Case(
"blo",
"b.lo")
5062 .
Case(
"bcc",
"b.cc")
5063 .
Case(
"bmi",
"b.mi")
5064 .
Case(
"bpl",
"b.pl")
5065 .
Case(
"bvs",
"b.vs")
5066 .
Case(
"bvc",
"b.vc")
5067 .
Case(
"bhi",
"b.hi")
5068 .
Case(
"bls",
"b.ls")
5069 .
Case(
"bge",
"b.ge")
5070 .
Case(
"blt",
"b.lt")
5071 .
Case(
"bgt",
"b.gt")
5072 .
Case(
"ble",
"b.le")
5073 .
Case(
"bal",
"b.al")
5074 .
Case(
"bnv",
"b.nv")
5079 getTok().getIdentifier().lower() ==
".req") {
5080 parseDirectiveReq(
Name, NameLoc);
5087 size_t Start = 0, Next =
Name.find(
'.');
5092 if (Head ==
"ic" || Head ==
"dc" || Head ==
"at" || Head ==
"tlbi" ||
5093 Head ==
"cfp" || Head ==
"dvp" || Head ==
"cpp" || Head ==
"cosp")
5094 return parseSysAlias(Head, NameLoc,
Operands);
5097 if (Head ==
"tlbip")
5098 return parseSyspAlias(Head, NameLoc,
Operands);
5100 Operands.push_back(AArch64Operand::CreateToken(Head, NameLoc, getContext()));
5106 Next =
Name.find(
'.', Start + 1);
5107 Head =
Name.slice(Start + 1, Next);
5111 std::string Suggestion;
5114 std::string
Msg =
"invalid condition code";
5115 if (!Suggestion.empty())
5116 Msg +=
", did you mean " + Suggestion +
"?";
5117 return Error(SuffixLoc, Msg);
5119 Operands.push_back(AArch64Operand::CreateToken(
".", SuffixLoc, getContext(),
5122 AArch64Operand::CreateCondCode(
CC, NameLoc, NameLoc, getContext()));
5128 Next =
Name.find(
'.', Start + 1);
5129 Head =
Name.slice(Start, Next);
5132 Operands.push_back(AArch64Operand::CreateToken(
5133 Head, SuffixLoc, getContext(),
true));
5138 bool condCodeFourthOperand =
5139 (Head ==
"ccmp" || Head ==
"ccmn" || Head ==
"fccmp" ||
5140 Head ==
"fccmpe" || Head ==
"fcsel" || Head ==
"csel" ||
5141 Head ==
"csinc" || Head ==
"csinv" || Head ==
"csneg");
5149 bool condCodeSecondOperand = (Head ==
"cset" || Head ==
"csetm");
5150 bool condCodeThirdOperand =
5151 (Head ==
"cinc" || Head ==
"cinv" || Head ==
"cneg");
5159 if (parseOperand(
Operands, (
N == 4 && condCodeFourthOperand) ||
5160 (
N == 3 && condCodeThirdOperand) ||
5161 (
N == 2 && condCodeSecondOperand),
5162 condCodeSecondOperand || condCodeThirdOperand)) {
5182 AArch64Operand::CreateToken(
"]", getLoc(), getContext()));
5185 AArch64Operand::CreateToken(
"!", getLoc(), getContext()));
5188 AArch64Operand::CreateToken(
"}", getLoc(), getContext()));
5201 assert((ZReg >= AArch64::Z0) && (ZReg <= AArch64::Z31));
5202 return (ZReg == ((Reg - AArch64::B0) + AArch64::Z0)) ||
5203 (ZReg == ((Reg - AArch64::H0) + AArch64::Z0)) ||
5204 (ZReg == ((Reg - AArch64::S0) + AArch64::Z0)) ||
5205 (ZReg == ((Reg - AArch64::D0) + AArch64::Z0)) ||
5206 (ZReg == ((Reg - AArch64::Q0) + AArch64::Z0)) ||
5207 (ZReg == ((Reg - AArch64::Z0) + AArch64::Z0));
5213bool AArch64AsmParser::validateInstruction(
MCInst &Inst,
SMLoc &IDLoc,
5222 PrefixInfo
Prefix = NextPrefix;
5223 NextPrefix = PrefixInfo::CreateFromInst(Inst, MCID.
TSFlags);
5235 return Error(IDLoc,
"instruction is unpredictable when following a"
5236 " movprfx, suggest replacing movprfx with mov");
5240 return Error(Loc[0],
"instruction is unpredictable when following a"
5241 " movprfx writing to a different destination");
5248 return Error(Loc[0],
"instruction is unpredictable when following a"
5249 " movprfx and destination also used as non-destructive"
5253 auto PPRRegClass = AArch64MCRegisterClasses[AArch64::PPRRegClassID];
5254 if (
Prefix.isPredicated()) {
5268 return Error(IDLoc,
"instruction is unpredictable when following a"
5269 " predicated movprfx, suggest using unpredicated movprfx");
5273 return Error(IDLoc,
"instruction is unpredictable when following a"
5274 " predicated movprfx using a different general predicate");
5278 return Error(IDLoc,
"instruction is unpredictable when following a"
5279 " predicated movprfx with a different element size");
5287 case AArch64::LDPSWpre:
5288 case AArch64::LDPWpost:
5289 case AArch64::LDPWpre:
5290 case AArch64::LDPXpost:
5291 case AArch64::LDPXpre: {
5296 return Error(Loc[0],
"unpredictable LDP instruction, writeback base "
5297 "is also a destination");
5299 return Error(Loc[1],
"unpredictable LDP instruction, writeback base "
5300 "is also a destination");
5303 case AArch64::LDR_ZA:
5304 case AArch64::STR_ZA: {
5307 return Error(Loc[1],
5308 "unpredictable instruction, immediate and offset mismatch.");
5311 case AArch64::LDPDi:
5312 case AArch64::LDPQi:
5313 case AArch64::LDPSi:
5314 case AArch64::LDPSWi:
5315 case AArch64::LDPWi:
5316 case AArch64::LDPXi: {
5320 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5323 case AArch64::LDPDpost:
5324 case AArch64::LDPDpre:
5325 case AArch64::LDPQpost:
5326 case AArch64::LDPQpre:
5327 case AArch64::LDPSpost:
5328 case AArch64::LDPSpre:
5329 case AArch64::LDPSWpost: {
5333 return Error(Loc[1],
"unpredictable LDP instruction, Rt2==Rt");
5336 case AArch64::STPDpost:
5337 case AArch64::STPDpre:
5338 case AArch64::STPQpost:
5339 case AArch64::STPQpre:
5340 case AArch64::STPSpost:
5341 case AArch64::STPSpre:
5342 case AArch64::STPWpost:
5343 case AArch64::STPWpre:
5344 case AArch64::STPXpost:
5345 case AArch64::STPXpre: {
5350 return Error(Loc[0],
"unpredictable STP instruction, writeback base "
5351 "is also a source");
5353 return Error(Loc[1],
"unpredictable STP instruction, writeback base "
5354 "is also a source");
5357 case AArch64::LDRBBpre:
5358 case AArch64::LDRBpre:
5359 case AArch64::LDRHHpre:
5360 case AArch64::LDRHpre:
5361 case AArch64::LDRSBWpre:
5362 case AArch64::LDRSBXpre:
5363 case AArch64::LDRSHWpre:
5364 case AArch64::LDRSHXpre:
5365 case AArch64::LDRSWpre:
5366 case AArch64::LDRWpre:
5367 case AArch64::LDRXpre:
5368 case AArch64::LDRBBpost:
5369 case AArch64::LDRBpost:
5370 case AArch64::LDRHHpost:
5371 case AArch64::LDRHpost:
5372 case AArch64::LDRSBWpost:
5373 case AArch64::LDRSBXpost:
5374 case AArch64::LDRSHWpost:
5375 case AArch64::LDRSHXpost:
5376 case AArch64::LDRSWpost:
5377 case AArch64::LDRWpost:
5378 case AArch64::LDRXpost: {
5382 return Error(Loc[0],
"unpredictable LDR instruction, writeback base "
5383 "is also a source");
5386 case AArch64::STRBBpost:
5387 case AArch64::STRBpost:
5388 case AArch64::STRHHpost:
5389 case AArch64::STRHpost:
5390 case AArch64::STRWpost:
5391 case AArch64::STRXpost:
5392 case AArch64::STRBBpre:
5393 case AArch64::STRBpre:
5394 case AArch64::STRHHpre:
5395 case AArch64::STRHpre:
5396 case AArch64::STRWpre:
5397 case AArch64::STRXpre: {
5401 return Error(Loc[0],
"unpredictable STR instruction, writeback base "
5402 "is also a source");
5405 case AArch64::STXRB:
5406 case AArch64::STXRH:
5407 case AArch64::STXRW:
5408 case AArch64::STXRX:
5409 case AArch64::STLXRB:
5410 case AArch64::STLXRH:
5411 case AArch64::STLXRW:
5412 case AArch64::STLXRX: {
5418 return Error(Loc[0],
5419 "unpredictable STXR instruction, status is also a source");
5422 case AArch64::STXPW:
5423 case AArch64::STXPX:
5424 case AArch64::STLXPW:
5425 case AArch64::STLXPX: {
5432 return Error(Loc[0],
5433 "unpredictable STXP instruction, status is also a source");
5436 case AArch64::LDRABwriteback:
5437 case AArch64::LDRAAwriteback: {
5441 return Error(Loc[0],
5442 "unpredictable LDRA instruction, writeback base"
5443 " is also a destination");
5450 case AArch64::CPYFP:
5451 case AArch64::CPYFPWN:
5452 case AArch64::CPYFPRN:
5453 case AArch64::CPYFPN:
5454 case AArch64::CPYFPWT:
5455 case AArch64::CPYFPWTWN:
5456 case AArch64::CPYFPWTRN:
5457 case AArch64::CPYFPWTN:
5458 case AArch64::CPYFPRT:
5459 case AArch64::CPYFPRTWN:
5460 case AArch64::CPYFPRTRN:
5461 case AArch64::CPYFPRTN:
5462 case AArch64::CPYFPT:
5463 case AArch64::CPYFPTWN:
5464 case AArch64::CPYFPTRN:
5465 case AArch64::CPYFPTN:
5466 case AArch64::CPYFM:
5467 case AArch64::CPYFMWN:
5468 case AArch64::CPYFMRN:
5469 case AArch64::CPYFMN:
5470 case AArch64::CPYFMWT:
5471 case AArch64::CPYFMWTWN:
5472 case AArch64::CPYFMWTRN:
5473 case AArch64::CPYFMWTN:
5474 case AArch64::CPYFMRT:
5475 case AArch64::CPYFMRTWN:
5476 case AArch64::CPYFMRTRN:
5477 case AArch64::CPYFMRTN:
5478 case AArch64::CPYFMT:
5479 case AArch64::CPYFMTWN:
5480 case AArch64::CPYFMTRN:
5481 case AArch64::CPYFMTN:
5482 case AArch64::CPYFE:
5483 case AArch64::CPYFEWN:
5484 case AArch64::CPYFERN:
5485 case AArch64::CPYFEN:
5486 case AArch64::CPYFEWT:
5487 case AArch64::CPYFEWTWN:
5488 case AArch64::CPYFEWTRN:
5489 case AArch64::CPYFEWTN:
5490 case AArch64::CPYFERT:
5491 case AArch64::CPYFERTWN:
5492 case AArch64::CPYFERTRN:
5493 case AArch64::CPYFERTN:
5494 case AArch64::CPYFET:
5495 case AArch64::CPYFETWN:
5496 case AArch64::CPYFETRN:
5497 case AArch64::CPYFETN:
5499 case AArch64::CPYPWN:
5500 case AArch64::CPYPRN:
5501 case AArch64::CPYPN:
5502 case AArch64::CPYPWT:
5503 case AArch64::CPYPWTWN:
5504 case AArch64::CPYPWTRN:
5505 case AArch64::CPYPWTN:
5506 case AArch64::CPYPRT:
5507 case AArch64::CPYPRTWN:
5508 case AArch64::CPYPRTRN:
5509 case AArch64::CPYPRTN:
5510 case AArch64::CPYPT:
5511 case AArch64::CPYPTWN:
5512 case AArch64::CPYPTRN:
5513 case AArch64::CPYPTN:
5515 case AArch64::CPYMWN:
5516 case AArch64::CPYMRN:
5517 case AArch64::CPYMN:
5518 case AArch64::CPYMWT:
5519 case AArch64::CPYMWTWN:
5520 case AArch64::CPYMWTRN:
5521 case AArch64::CPYMWTN:
5522 case AArch64::CPYMRT:
5523 case AArch64::CPYMRTWN:
5524 case AArch64::CPYMRTRN:
5525 case AArch64::CPYMRTN:
5526 case AArch64::CPYMT:
5527 case AArch64::CPYMTWN:
5528 case AArch64::CPYMTRN:
5529 case AArch64::CPYMTN:
5531 case AArch64::CPYEWN:
5532 case AArch64::CPYERN:
5533 case AArch64::CPYEN:
5534 case AArch64::CPYEWT:
5535 case AArch64::CPYEWTWN:
5536 case AArch64::CPYEWTRN:
5537 case AArch64::CPYEWTN:
5538 case AArch64::CPYERT:
5539 case AArch64::CPYERTWN:
5540 case AArch64::CPYERTRN:
5541 case AArch64::CPYERTN:
5542 case AArch64::CPYET:
5543 case AArch64::CPYETWN:
5544 case AArch64::CPYETRN:
5545 case AArch64::CPYETN: {
5553 return Error(Loc[0],
5554 "invalid CPY instruction, Xd_wb and Xd do not match");
5556 return Error(Loc[0],
5557 "invalid CPY instruction, Xs_wb and Xs do not match");
5559 return Error(Loc[0],
5560 "invalid CPY instruction, Xn_wb and Xn do not match");
5562 return Error(Loc[0],
"invalid CPY instruction, destination and source"
5563 " registers are the same");
5565 return Error(Loc[0],
"invalid CPY instruction, destination and size"
5566 " registers are the same");
5568 return Error(Loc[0],
"invalid CPY instruction, source and size"
5569 " registers are the same");
5573 case AArch64::SETPT:
5574 case AArch64::SETPN:
5575 case AArch64::SETPTN:
5577 case AArch64::SETMT:
5578 case AArch64::SETMN:
5579 case AArch64::SETMTN:
5581 case AArch64::SETET:
5582 case AArch64::SETEN:
5583 case AArch64::SETETN:
5584 case AArch64::SETGP:
5585 case AArch64::SETGPT:
5586 case AArch64::SETGPN:
5587 case AArch64::SETGPTN:
5588 case AArch64::SETGM:
5589 case AArch64::SETGMT:
5590 case AArch64::SETGMN:
5591 case AArch64::SETGMTN:
5592 case AArch64::MOPSSETGE:
5593 case AArch64::MOPSSETGET:
5594 case AArch64::MOPSSETGEN:
5595 case AArch64::MOPSSETGETN: {
5602 return Error(Loc[0],
5603 "invalid SET instruction, Xd_wb and Xd do not match");
5605 return Error(Loc[0],
5606 "invalid SET instruction, Xn_wb and Xn do not match");
5608 return Error(Loc[0],
"invalid SET instruction, destination and size"
5609 " registers are the same");
5611 return Error(Loc[0],
"invalid SET instruction, destination and source"
5612 " registers are the same");
5614 return Error(Loc[0],
"invalid SET instruction, source and size"
5615 " registers are the same");
5624 case AArch64::ADDSWri:
5625 case AArch64::ADDSXri:
5626 case AArch64::ADDWri:
5627 case AArch64::ADDXri:
5628 case AArch64::SUBSWri:
5629 case AArch64::SUBSXri:
5630 case AArch64::SUBWri:
5631 case AArch64::SUBXri: {
5639 if (classifySymbolRef(Expr, ELFRefKind, DarwinRefKind, Addend)) {
5666 return Error(Loc.
back(),
"invalid immediate expression");
5679 unsigned VariantID = 0);
5681bool AArch64AsmParser::showMatchError(
SMLoc Loc,
unsigned ErrCode,
5685 case Match_InvalidTiedOperand: {
5687 if (
Op.isVectorList())
5688 return Error(Loc,
"operand must match destination register list");
5690 assert(
Op.isReg() &&
"Unexpected operand type");
5691 switch (
Op.getRegEqualityTy()) {
5692 case RegConstraintEqualityTy::EqualsSubReg:
5693 return Error(Loc,
"operand must be 64-bit form of destination register");
5694 case RegConstraintEqualityTy::EqualsSuperReg:
5695 return Error(Loc,
"operand must be 32-bit form of destination register");
5696 case RegConstraintEqualityTy::EqualsReg:
5697 return Error(Loc,
"operand must match destination register");
5701 case Match_MissingFeature:
5703 "instruction requires a CPU feature not currently enabled");
5704 case Match_InvalidOperand:
5705 return Error(Loc,
"invalid operand for instruction");
5706 case Match_InvalidSuffix:
5707 return Error(Loc,
"invalid type suffix for instruction");
5708 case Match_InvalidCondCode:
5709 return Error(Loc,
"expected AArch64 condition code");
5710 case Match_AddSubRegExtendSmall:
5712 "expected '[su]xt[bhw]' with optional integer in range [0, 4]");
5713 case Match_AddSubRegExtendLarge:
5715 "expected 'sxtx' 'uxtx' or 'lsl' with optional integer in range [0, 4]");
5716 case Match_AddSubSecondSource:
5718 "expected compatible register, symbol or integer in range [0, 4095]");
5719 case Match_LogicalSecondSource:
5720 return Error(Loc,
"expected compatible register or logical immediate");
5721 case Match_InvalidMovImm32Shift:
5722 return Error(Loc,
"expected 'lsl' with optional integer 0 or 16");
5723 case Match_InvalidMovImm64Shift:
5724 return Error(Loc,
"expected 'lsl' with optional integer 0, 16, 32 or 48");
5725 case Match_AddSubRegShift32:
5727 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 31]");
5728 case Match_AddSubRegShift64:
5730 "expected 'lsl', 'lsr' or 'asr' with optional integer in range [0, 63]");
5731 case Match_InvalidFPImm:
5733 "expected compatible register or floating-point constant");
5734 case Match_InvalidMemoryIndexedSImm6:
5735 return Error(Loc,
"index must be an integer in range [-32, 31].");
5736 case Match_InvalidMemoryIndexedSImm5:
5737 return Error(Loc,
"index must be an integer in range [-16, 15].");
5738 case Match_InvalidMemoryIndexed1SImm4:
5739 return Error(Loc,
"index must be an integer in range [-8, 7].");
5740 case Match_InvalidMemoryIndexed2SImm4:
5741 return Error(Loc,
"index must be a multiple of 2 in range [-16, 14].");
5742 case Match_InvalidMemoryIndexed3SImm4:
5743 return Error(Loc,
"index must be a multiple of 3 in range [-24, 21].");
5744 case Match_InvalidMemoryIndexed4SImm4:
5745 return Error(Loc,
"index must be a multiple of 4 in range [-32, 28].");
5746 case Match_InvalidMemoryIndexed16SImm4:
5747 return Error(Loc,
"index must be a multiple of 16 in range [-128, 112].");
5748 case Match_InvalidMemoryIndexed32SImm4:
5749 return Error(Loc,
"index must be a multiple of 32 in range [-256, 224].");
5750 case Match_InvalidMemoryIndexed1SImm6:
5751 return Error(Loc,
"index must be an integer in range [-32, 31].");
5752 case Match_InvalidMemoryIndexedSImm8:
5753 return Error(Loc,
"index must be an integer in range [-128, 127].");
5754 case Match_InvalidMemoryIndexedSImm9:
5755 return Error(Loc,
"index must be an integer in range [-256, 255].");
5756 case Match_InvalidMemoryIndexed16SImm9:
5757 return Error(Loc,
"index must be a multiple of 16 in range [-4096, 4080].");
5758 case Match_InvalidMemoryIndexed8SImm10:
5759 return Error(Loc,
"index must be a multiple of 8 in range [-4096, 4088].");
5760 case Match_InvalidMemoryIndexed4SImm7:
5761 return Error(Loc,
"index must be a multiple of 4 in range [-256, 252].");
5762 case Match_InvalidMemoryIndexed8SImm7:
5763 return Error(Loc,
"index must be a multiple of 8 in range [-512, 504].");
5764 case Match_InvalidMemoryIndexed16SImm7:
5765 return Error(Loc,
"index must be a multiple of 16 in range [-1024, 1008].");
5766 case Match_InvalidMemoryIndexed8UImm5:
5767 return Error(Loc,
"index must be a multiple of 8 in range [0, 248].");
5768 case Match_InvalidMemoryIndexed8UImm3:
5769 return Error(Loc,
"index must be a multiple of 8 in range [0, 56].");
5770 case Match_InvalidMemoryIndexed4UImm5:
5771 return Error(Loc,
"index must be a multiple of 4 in range [0, 124].");
5772 case Match_InvalidMemoryIndexed2UImm5:
5773 return Error(Loc,
"index must be a multiple of 2 in range [0, 62].");
5774 case Match_InvalidMemoryIndexed8UImm6:
5775 return Error(Loc,
"index must be a multiple of 8 in range [0, 504].");
5776 case Match_InvalidMemoryIndexed16UImm6:
5777 return Error(Loc,
"index must be a multiple of 16 in range [0, 1008].");
5778 case Match_InvalidMemoryIndexed4UImm6:
5779 return Error(Loc,
"index must be a multiple of 4 in range [0, 252].");
5780 case Match_InvalidMemoryIndexed2UImm6:
5781 return Error(Loc,
"index must be a multiple of 2 in range [0, 126].");
5782 case Match_InvalidMemoryIndexed1UImm6:
5783 return Error(Loc,
"index must be in range [0, 63].");
5784 case Match_InvalidMemoryWExtend8:
5786 "expected 'uxtw' or 'sxtw' with optional shift of #0");
5787 case Match_InvalidMemoryWExtend16:
5789 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #1");
5790 case Match_InvalidMemoryWExtend32:
5792 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #2");
5793 case Match_InvalidMemoryWExtend64:
5795 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #3");
5796 case Match_InvalidMemoryWExtend128:
5798 "expected 'uxtw' or 'sxtw' with optional shift of #0 or #4");
5799 case Match_InvalidMemoryXExtend8:
5801 "expected 'lsl' or 'sxtx' with optional shift of #0");
5802 case Match_InvalidMemoryXExtend16:
5804 "expected 'lsl' or 'sxtx' with optional shift of #0 or #1");
5805 case Match_InvalidMemoryXExtend32:
5807 "expected 'lsl' or 'sxtx' with optional shift of #0 or #2");
5808 case Match_InvalidMemoryXExtend64:
5810 "expected 'lsl' or 'sxtx' with optional shift of #0 or #3");
5811 case Match_InvalidMemoryXExtend128:
5813 "expected 'lsl' or 'sxtx' with optional shift of #0 or #4");
5814 case Match_InvalidMemoryIndexed1:
5815 return Error(Loc,
"index must be an integer in range [0, 4095].");
5816 case Match_InvalidMemoryIndexed2:
5817 return Error(Loc,
"index must be a multiple of 2 in range [0, 8190].");
5818 case Match_InvalidMemoryIndexed4:
5819 return Error(Loc,
"index must be a multiple of 4 in range [0, 16380].");
5820 case Match_InvalidMemoryIndexed8:
5821 return Error(Loc,
"index must be a multiple of 8 in range [0, 32760].");
5822 case Match_InvalidMemoryIndexed16:
5823 return Error(Loc,
"index must be a multiple of 16 in range [0, 65520].");
5824 case Match_InvalidImm0_0:
5825 return Error(Loc,
"immediate must be 0.");
5826 case Match_InvalidImm0_1:
5827 return Error(Loc,
"immediate must be an integer in range [0, 1].");
5828 case Match_InvalidImm0_3:
5829 return Error(Loc,
"immediate must be an integer in range [0, 3].");
5830 case Match_InvalidImm0_7:
5831 return Error(Loc,
"immediate must be an integer in range [0, 7].");
5832 case Match_InvalidImm0_15:
5833 return Error(Loc,
"immediate must be an integer in range [0, 15].");
5834 case Match_InvalidImm0_31:
5835 return Error(Loc,
"immediate must be an integer in range [0, 31].");
5836 case Match_InvalidImm0_63:
5837 return Error(Loc,
"immediate must be an integer in range [0, 63].");
5838 case Match_InvalidImm0_127:
5839 return Error(Loc,
"immediate must be an integer in range [0, 127].");
5840 case Match_InvalidImm0_255:
5841 return Error(Loc,
"immediate must be an integer in range [0, 255].");
5842 case Match_InvalidImm0_65535:
5843 return Error(Loc,
"immediate must be an integer in range [0, 65535].");
5844 case Match_InvalidImm1_8:
5845 return Error(Loc,
"immediate must be an integer in range [1, 8].");
5846 case Match_InvalidImm1_16:
5847 return Error(Loc,
"immediate must be an integer in range [1, 16].");
5848 case Match_InvalidImm1_32:
5849 return Error(Loc,
"immediate must be an integer in range [1, 32].");
5850 case Match_InvalidImm1_64:
5851 return Error(Loc,
"immediate must be an integer in range [1, 64].");
5852 case Match_InvalidMemoryIndexedRange2UImm0:
5853 return Error(Loc,
"vector select offset must be the immediate range 0:1.");
5854 case Match_InvalidMemoryIndexedRange2UImm1:
5855 return Error(Loc,
"vector select offset must be an immediate range of the "
5856 "form <immf>:<imml>, where the first "
5857 "immediate is a multiple of 2 in the range [0, 2], and "
5858 "the second immediate is immf + 1.");
5859 case Match_InvalidMemoryIndexedRange2UImm2:
5860 case Match_InvalidMemoryIndexedRange2UImm3:
5863 "vector select offset must be an immediate range of the form "
5865 "where the first immediate is a multiple of 2 in the range [0, 6] or "
5867 "depending on the instruction, and the second immediate is immf + 1.");
5868 case Match_InvalidMemoryIndexedRange4UImm0:
5869 return Error(Loc,
"vector select offset must be the immediate range 0:3.");
5870 case Match_InvalidMemoryIndexedRange4UImm1:
5871 case Match_InvalidMemoryIndexedRange4UImm2:
5874 "vector select offset must be an immediate range of the form "
5876 "where the first immediate is a multiple of 4 in the range [0, 4] or "
5878 "depending on the instruction, and the second immediate is immf + 3.");
5879 case Match_InvalidSVEAddSubImm8:
5880 return Error(Loc,
"immediate must be an integer in range [0, 255]"
5881 " with a shift amount of 0");
5882 case Match_InvalidSVEAddSubImm16:
5883 case Match_InvalidSVEAddSubImm32:
5884 case Match_InvalidSVEAddSubImm64:
5885 return Error(Loc,
"immediate must be an integer in range [0, 255] or a "
5886 "multiple of 256 in range [256, 65280]");
5887 case Match_InvalidSVECpyImm8:
5888 return Error(Loc,
"immediate must be an integer in range [-128, 255]"
5889 " with a shift amount of 0");
5890 case Match_InvalidSVECpyImm16:
5891 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
5892 "multiple of 256 in range [-32768, 65280]");
5893 case Match_InvalidSVECpyImm32:
5894 case Match_InvalidSVECpyImm64:
5895 return Error(Loc,
"immediate must be an integer in range [-128, 127] or a "
5896 "multiple of 256 in range [-32768, 32512]");
5897 case Match_InvalidIndexRange0_0:
5898 return Error(Loc,
"expected lane specifier '[0]'");
5899 case Match_InvalidIndexRange1_1:
5900 return Error(Loc,
"expected lane specifier '[1]'");
5901 case Match_InvalidIndexRange0_15:
5902 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
5903 case Match_InvalidIndexRange0_7:
5904 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
5905 case Match_InvalidIndexRange0_3:
5906 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
5907 case Match_InvalidIndexRange0_1:
5908 return Error(Loc,
"vector lane must be an integer in range [0, 1].");
5909 case Match_InvalidSVEIndexRange0_63:
5910 return Error(Loc,
"vector lane must be an integer in range [0, 63].");
5911 case Match_InvalidSVEIndexRange0_31:
5912 return Error(Loc,
"vector lane must be an integer in range [0, 31].");
5913 case Match_InvalidSVEIndexRange0_15:
5914 return Error(Loc,
"vector lane must be an integer in range [0, 15].");
5915 case Match_InvalidSVEIndexRange0_7:
5916 return Error(Loc,
"vector lane must be an integer in range [0, 7].");
5917 case Match_InvalidSVEIndexRange0_3:
5918 return Error(Loc,
"vector lane must be an integer in range [0, 3].");
5919 case Match_InvalidLabel:
5920 return Error(Loc,
"expected label or encodable integer pc offset");
5922 return Error(Loc,
"expected readable system register");
5924 case Match_InvalidSVCR:
5925 return Error(Loc,
"expected writable system register or pstate");
5926 case Match_InvalidComplexRotationEven:
5927 return Error(Loc,
"complex rotation must be 0, 90, 180 or 270.");
5928 case Match_InvalidComplexRotationOdd:
5929 return Error(Loc,
"complex rotation must be 90 or 270.");
5930 case Match_MnemonicFail: {
5932 ((AArch64Operand &)*
Operands[0]).getToken(),
5933 ComputeAvailableFeatures(STI->getFeatureBits()));
5934 return Error(Loc,
"unrecognized instruction mnemonic" + Suggestion);
5936 case Match_InvalidGPR64shifted8:
5937 return Error(Loc,
"register must be x0..x30 or xzr, without shift");
5938 case Match_InvalidGPR64shifted16:
5939 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #1'");
5940 case Match_InvalidGPR64shifted32:
5941 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #2'");
5942 case Match_InvalidGPR64shifted64:
5943 return Error(Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #3'");
5944 case Match_InvalidGPR64shifted128:
5946 Loc,
"register must be x0..x30 or xzr, with required shift 'lsl #4'");
5947 case Match_InvalidGPR64NoXZRshifted8:
5948 return Error(Loc,
"register must be x0..x30 without shift");
5949 case Match_InvalidGPR64NoXZRshifted16:
5950 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #1'");
5951 case Match_InvalidGPR64NoXZRshifted32:
5952 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #2'");
5953 case Match_InvalidGPR64NoXZRshifted64:
5954 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #3'");
5955 case Match_InvalidGPR64NoXZRshifted128:
5956 return Error(Loc,
"register must be x0..x30 with required shift 'lsl #4'");
5957 case Match_InvalidZPR32UXTW8:
5958 case Match_InvalidZPR32SXTW8:
5959 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw)'");
5960 case Match_InvalidZPR32UXTW16:
5961 case Match_InvalidZPR32SXTW16:
5962 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #1'");
5963 case Match_InvalidZPR32UXTW32:
5964 case Match_InvalidZPR32SXTW32:
5965 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #2'");
5966 case Match_InvalidZPR32UXTW64:
5967 case Match_InvalidZPR32SXTW64:
5968 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, (uxtw|sxtw) #3'");
5969 case Match_InvalidZPR64UXTW8:
5970 case Match_InvalidZPR64SXTW8:
5971 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (uxtw|sxtw)'");
5972 case Match_InvalidZPR64UXTW16:
5973 case Match_InvalidZPR64SXTW16:
5974 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #1'");
5975 case Match_InvalidZPR64UXTW32:
5976 case Match_InvalidZPR64SXTW32:
5977 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #2'");
5978 case Match_InvalidZPR64UXTW64:
5979 case Match_InvalidZPR64SXTW64:
5980 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, (lsl|uxtw|sxtw) #3'");
5981 case Match_InvalidZPR32LSL8:
5982 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s'");
5983 case Match_InvalidZPR32LSL16:
5984 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #1'");
5985 case Match_InvalidZPR32LSL32:
5986 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #2'");
5987 case Match_InvalidZPR32LSL64:
5988 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].s, lsl #3'");
5989 case Match_InvalidZPR64LSL8:
5990 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d'");
5991 case Match_InvalidZPR64LSL16:
5992 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #1'");
5993 case Match_InvalidZPR64LSL32:
5994 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #2'");
5995 case Match_InvalidZPR64LSL64:
5996 return Error(Loc,
"invalid shift/extend specified, expected 'z[0..31].d, lsl #3'");
5997 case Match_InvalidZPR0:
5998 return Error(Loc,
"expected register without element width suffix");
5999 case Match_InvalidZPR8:
6000 case Match_InvalidZPR16:
6001 case Match_InvalidZPR32:
6002 case Match_InvalidZPR64:
6003 case Match_InvalidZPR128:
6004 return Error(Loc,
"invalid element width");
6005 case Match_InvalidZPR_3b8:
6006 return Error(Loc,
"Invalid restricted vector register, expected z0.b..z7.b");
6007 case Match_InvalidZPR_3b16:
6008 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z7.h");
6009 case Match_InvalidZPR_3b32:
6010 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z7.s");
6011 case Match_InvalidZPR_4b8:
6013 "Invalid restricted vector register, expected z0.b..z15.b");
6014 case Match_InvalidZPR_4b16:
6015 return Error(Loc,
"Invalid restricted vector register, expected z0.h..z15.h");
6016 case Match_InvalidZPR_4b32:
6017 return Error(Loc,
"Invalid restricted vector register, expected z0.s..z15.s");
6018 case Match_InvalidZPR_4b64:
6019 return Error(Loc,
"Invalid restricted vector register, expected z0.d..z15.d");
6020 case Match_InvalidSVEPattern:
6021 return Error(Loc,
"invalid predicate pattern");
6022 case Match_InvalidSVEPredicateAnyReg:
6023 case Match_InvalidSVEPredicateBReg:
6024 case Match_InvalidSVEPredicateHReg:
6025 case Match_InvalidSVEPredicateSReg:
6026 case Match_InvalidSVEPredicateDReg:
6027 return Error(Loc,
"invalid predicate register.");
6028 case Match_InvalidSVEPredicate3bAnyReg:
6029 return Error(Loc,
"invalid restricted predicate register, expected p0..p7 (without element suffix)");
6030 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6031 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6032 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6033 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6034 return Error(Loc,
"Invalid predicate register, expected PN in range "
6035 "pn8..pn15 with element suffix.");
6036 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6037 return Error(Loc,
"invalid restricted predicate-as-counter register "
6038 "expected pn8..pn15");
6039 case Match_InvalidSVEPNPredicateBReg:
6040 case Match_InvalidSVEPNPredicateHReg:
6041 case Match_InvalidSVEPNPredicateSReg:
6042 case Match_InvalidSVEPNPredicateDReg:
6043 return Error(Loc,
"Invalid predicate register, expected PN in range "
6044 "pn0..pn15 with element suffix.");
6045 case Match_InvalidSVEVecLenSpecifier:
6046 return Error(Loc,
"Invalid vector length specifier, expected VLx2 or VLx4");
6047 case Match_InvalidSVEPredicateListMul2x8:
6048 case Match_InvalidSVEPredicateListMul2x16:
6049 case Match_InvalidSVEPredicateListMul2x32:
6050 case Match_InvalidSVEPredicateListMul2x64:
6051 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6052 "predicate registers, where the first vector is a multiple of 2 "
6053 "and with correct element type");
6054 case Match_InvalidSVEExactFPImmOperandHalfOne:
6055 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 1.0.");
6056 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6057 return Error(Loc,
"Invalid floating point constant, expected 0.5 or 2.0.");
6058 case Match_InvalidSVEExactFPImmOperandZeroOne:
6059 return Error(Loc,
"Invalid floating point constant, expected 0.0 or 1.0.");
6060 case Match_InvalidMatrixTileVectorH8:
6061 case Match_InvalidMatrixTileVectorV8:
6062 return Error(Loc,
"invalid matrix operand, expected za0h.b or za0v.b");
6063 case Match_InvalidMatrixTileVectorH16:
6064 case Match_InvalidMatrixTileVectorV16:
6066 "invalid matrix operand, expected za[0-1]h.h or za[0-1]v.h");
6067 case Match_InvalidMatrixTileVectorH32:
6068 case Match_InvalidMatrixTileVectorV32:
6070 "invalid matrix operand, expected za[0-3]h.s or za[0-3]v.s");
6071 case Match_InvalidMatrixTileVectorH64:
6072 case Match_InvalidMatrixTileVectorV64:
6074 "invalid matrix operand, expected za[0-7]h.d or za[0-7]v.d");
6075 case Match_InvalidMatrixTileVectorH128:
6076 case Match_InvalidMatrixTileVectorV128:
6078 "invalid matrix operand, expected za[0-15]h.q or za[0-15]v.q");
6079 case Match_InvalidMatrixTile32:
6080 return Error(Loc,
"invalid matrix operand, expected za[0-3].s");
6081 case Match_InvalidMatrixTile64:
6082 return Error(Loc,
"invalid matrix operand, expected za[0-7].d");
6083 case Match_InvalidMatrix:
6084 return Error(Loc,
"invalid matrix operand, expected za");
6085 case Match_InvalidMatrix8:
6086 return Error(Loc,
"invalid matrix operand, expected suffix .b");
6087 case Match_InvalidMatrix16:
6088 return Error(Loc,
"invalid matrix operand, expected suffix .h");
6089 case Match_InvalidMatrix32:
6090 return Error(Loc,
"invalid matrix operand, expected suffix .s");
6091 case Match_InvalidMatrix64:
6092 return Error(Loc,
"invalid matrix operand, expected suffix .d");
6093 case Match_InvalidMatrixIndexGPR32_12_15:
6094 return Error(Loc,
"operand must be a register in range [w12, w15]");
6095 case Match_InvalidMatrixIndexGPR32_8_11:
6096 return Error(Loc,
"operand must be a register in range [w8, w11]");
6097 case Match_InvalidSVEVectorListMul2x8:
6098 case Match_InvalidSVEVectorListMul2x16:
6099 case Match_InvalidSVEVectorListMul2x32:
6100 case Match_InvalidSVEVectorListMul2x64:
6101 return Error(Loc,
"Invalid vector list, expected list with 2 consecutive "
6102 "SVE vectors, where the first vector is a multiple of 2 "
6103 "and with matching element types");
6104 case Match_InvalidSVEVectorListMul4x8:
6105 case Match_InvalidSVEVectorListMul4x16:
6106 case Match_InvalidSVEVectorListMul4x32:
6107 case Match_InvalidSVEVectorListMul4x64:
6108 return Error(Loc,
"Invalid vector list, expected list with 4 consecutive "
6109 "SVE vectors, where the first vector is a multiple of 4 "
6110 "and with matching element types");
6111 case Match_InvalidLookupTable:
6112 return Error(Loc,
"Invalid lookup table, expected zt0");
6113 case Match_InvalidSVEVectorListStrided2x8:
6114 case Match_InvalidSVEVectorListStrided2x16:
6115 case Match_InvalidSVEVectorListStrided2x32:
6116 case Match_InvalidSVEVectorListStrided2x64:
6119 "Invalid vector list, expected list with each SVE vector in the list "
6120 "8 registers apart, and the first register in the range [z0, z7] or "
6121 "[z16, z23] and with correct element type");
6122 case Match_InvalidSVEVectorListStrided4x8:
6123 case Match_InvalidSVEVectorListStrided4x16:
6124 case Match_InvalidSVEVectorListStrided4x32:
6125 case Match_InvalidSVEVectorListStrided4x64:
6128 "Invalid vector list, expected list with each SVE vector in the list "
6129 "4 registers apart, and the first register in the range [z0, z3] or "
6130 "[z16, z19] and with correct element type");
6131 case Match_AddSubLSLImm3ShiftLarge:
6133 "expected 'lsl' with optional integer in range [0, 7]");
6134 case Match_InvalidSVEPNRasPPRPredicateBReg:
6136 "Expected predicate-as-counter register name with .B suffix");
6144bool AArch64AsmParser::MatchAndEmitInstruction(
SMLoc IDLoc,
unsigned &Opcode,
6148 bool MatchingInlineAsm) {
6150 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[0]);
6151 assert(
Op.isToken() &&
"Leading operand should always be a mnemonic!");
6154 unsigned NumOperands =
Operands.size();
6156 if (NumOperands == 4 && Tok ==
"lsl") {
6157 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6158 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6159 if (Op2.isScalarReg() && Op3.isImm()) {
6160 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6165 if (AArch64MCRegisterClasses[AArch64::GPR32allRegClassID].
contains(
6167 NewOp3Val = (32 - Op3Val) & 0x1f;
6168 NewOp4Val = 31 - Op3Val;
6170 NewOp3Val = (64 - Op3Val) & 0x3f;
6171 NewOp4Val = 63 - Op3Val;
6178 AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(), getContext());
6179 Operands.push_back(AArch64Operand::CreateImm(
6180 NewOp4, Op3.getStartLoc(), Op3.getEndLoc(), getContext()));
6181 Operands[3] = AArch64Operand::CreateImm(NewOp3, Op3.getStartLoc(),
6182 Op3.getEndLoc(), getContext());
6185 }
else if (NumOperands == 4 && Tok ==
"bfc") {
6187 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6188 AArch64Operand LSBOp =
static_cast<AArch64Operand &
>(*
Operands[2]);
6189 AArch64Operand WidthOp =
static_cast<AArch64Operand &
>(*
Operands[3]);
6191 if (Op1.isScalarReg() && LSBOp.isImm() && WidthOp.isImm()) {
6192 const MCConstantExpr *LSBCE = dyn_cast<MCConstantExpr>(LSBOp.getImm());
6193 const MCConstantExpr *WidthCE = dyn_cast<MCConstantExpr>(WidthOp.getImm());
6195 if (LSBCE && WidthCE) {
6200 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6206 if (LSB >= RegWidth)
6207 return Error(LSBOp.getStartLoc(),
6208 "expected integer in range [0, 31]");
6209 if (Width < 1 || Width > RegWidth)
6210 return Error(WidthOp.getStartLoc(),
6211 "expected integer in range [1, 32]");
6215 ImmR = (32 - LSB) & 0x1f;
6217 ImmR = (64 - LSB) & 0x3f;
6221 if (ImmR != 0 && ImmS >= ImmR)
6222 return Error(WidthOp.getStartLoc(),
6223 "requested insert overflows register");
6228 AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(), getContext());
6229 Operands[2] = AArch64Operand::CreateReg(
6230 RegWidth == 32 ? AArch64::WZR : AArch64::XZR, RegKind::Scalar,
6232 Operands[3] = AArch64Operand::CreateImm(
6233 ImmRExpr, LSBOp.getStartLoc(), LSBOp.getEndLoc(), getContext());
6235 AArch64Operand::CreateImm(ImmSExpr, WidthOp.getStartLoc(),
6236 WidthOp.getEndLoc(), getContext()));
6239 }
else if (NumOperands == 5) {
6242 if (Tok ==
"bfi" || Tok ==
"sbfiz" || Tok ==
"ubfiz") {
6243 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6244 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6245 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6247 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6248 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6249 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
6251 if (Op3CE && Op4CE) {
6256 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6262 if (Op3Val >= RegWidth)
6263 return Error(Op3.getStartLoc(),
6264 "expected integer in range [0, 31]");
6265 if (Op4Val < 1 || Op4Val > RegWidth)
6266 return Error(Op4.getStartLoc(),
6267 "expected integer in range [1, 32]");
6271 NewOp3Val = (32 - Op3Val) & 0x1f;
6273 NewOp3Val = (64 - Op3Val) & 0x3f;
6277 if (NewOp3Val != 0 && NewOp4Val >= NewOp3Val)
6278 return Error(Op4.getStartLoc(),
6279 "requested insert overflows register");
6285 Operands[3] = AArch64Operand::CreateImm(
6286 NewOp3, Op3.getStartLoc(), Op3.getEndLoc(), getContext());
6287 Operands[4] = AArch64Operand::CreateImm(
6288 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
6290 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6292 else if (Tok ==
"sbfiz")
6293 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6295 else if (Tok ==
"ubfiz")
6296 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6305 }
else if (NumOperands == 5 &&
6306 (Tok ==
"bfxil" || Tok ==
"sbfx" || Tok ==
"ubfx")) {
6307 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6308 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6309 AArch64Operand &Op4 =
static_cast<AArch64Operand &
>(*
Operands[4]);
6311 if (Op1.isScalarReg() && Op3.isImm() && Op4.isImm()) {
6312 const MCConstantExpr *Op3CE = dyn_cast<MCConstantExpr>(Op3.getImm());
6313 const MCConstantExpr *Op4CE = dyn_cast<MCConstantExpr>(Op4.getImm());
6315 if (Op3CE && Op4CE) {
6320 if (AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].
contains(
6326 if (Op3Val >= RegWidth)
6327 return Error(Op3.getStartLoc(),
6328 "expected integer in range [0, 31]");
6329 if (Op4Val < 1 || Op4Val > RegWidth)
6330 return Error(Op4.getStartLoc(),
6331 "expected integer in range [1, 32]");
6333 uint64_t NewOp4Val = Op3Val + Op4Val - 1;
6335 if (NewOp4Val >= RegWidth || NewOp4Val < Op3Val)
6336 return Error(Op4.getStartLoc(),
6337 "requested extract overflows register");
6341 Operands[4] = AArch64Operand::CreateImm(
6342 NewOp4, Op4.getStartLoc(), Op4.getEndLoc(), getContext());
6344 Operands[0] = AArch64Operand::CreateToken(
"bfm",
Op.getStartLoc(),
6346 else if (Tok ==
"sbfx")
6347 Operands[0] = AArch64Operand::CreateToken(
"sbfm",
Op.getStartLoc(),
6349 else if (Tok ==
"ubfx")
6350 Operands[0] = AArch64Operand::CreateToken(
"ubfm",
Op.getStartLoc(),
6363 if (getSTI().hasFeature(AArch64::FeatureZCZeroingFPWorkaround) &&
6364 NumOperands == 4 && Tok ==
"movi") {
6365 AArch64Operand &Op1 =
static_cast<AArch64Operand &
>(*
Operands[1]);
6366 AArch64Operand &Op2 =
static_cast<AArch64Operand &
>(*
Operands[2]);
6367 AArch64Operand &Op3 =
static_cast<AArch64Operand &
>(*
Operands[3]);
6368 if ((Op1.isToken() && Op2.isNeonVectorReg() && Op3.isImm()) ||
6369 (Op1.isNeonVectorReg() && Op2.isToken() && Op3.isImm())) {
6370 StringRef Suffix = Op1.isToken() ? Op1.getToken() : Op2.getToken();
6371 if (Suffix.
lower() ==
".2d" &&
6372 cast<MCConstantExpr>(Op3.getImm())->getValue() == 0) {
6373 Warning(IDLoc,
"instruction movi.2d with immediate #0 may not function"
6374 " correctly on this CPU, converting to equivalent movi.16b");
6376 unsigned Idx = Op1.isToken() ? 1 : 2;
6378 AArch64Operand::CreateToken(
".16b", IDLoc, getContext());
6386 if (NumOperands == 3 && (Tok ==
"sxtw" || Tok ==
"uxtw")) {
6389 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6390 if (
Op.isScalarReg()) {
6392 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6393 Op.getStartLoc(),
Op.getEndLoc(),
6398 else if (NumOperands == 3 && (Tok ==
"sxtb" || Tok ==
"sxth")) {
6399 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6400 if (
Op.isScalarReg() &&
6401 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6405 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[2]);
6406 if (
Op.isScalarReg()) {
6408 Operands[2] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6410 Op.getEndLoc(), getContext());
6415 else if (NumOperands == 3 && (Tok ==
"uxtb" || Tok ==
"uxth")) {
6416 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6417 if (
Op.isScalarReg() &&
6418 AArch64MCRegisterClasses[AArch64::GPR64allRegClassID].contains(
6422 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(*
Operands[1]);
6423 if (
Op.isScalarReg()) {
6425 Operands[1] = AArch64Operand::CreateReg(Reg, RegKind::Scalar,
6427 Op.getEndLoc(), getContext());
6436 unsigned MatchResult =
6438 MatchingInlineAsm, 1);
6442 if (MatchResult != Match_Success) {
6445 auto ShortFormNEONErrorInfo =
ErrorInfo;
6446 auto ShortFormNEONMatchResult = MatchResult;
6447 auto ShortFormNEONMissingFeatures = MissingFeatures;
6451 MatchingInlineAsm, 0);
6456 if (MatchResult == Match_InvalidOperand &&
ErrorInfo == 1 &&
6458 ((AArch64Operand &)*
Operands[1]).isTokenSuffix()) {
6459 MatchResult = ShortFormNEONMatchResult;
6461 MissingFeatures = ShortFormNEONMissingFeatures;
6465 switch (MatchResult) {
6466 case Match_Success: {
6470 for (
unsigned i = 1; i < NumOperands; ++i)
6472 if (validateInstruction(Inst, IDLoc, OperandLocs))
6479 case Match_MissingFeature: {
6480 assert(MissingFeatures.
any() &&
"Unknown missing feature!");
6483 std::string
Msg =
"instruction requires:";
6484 for (
unsigned i = 0, e = MissingFeatures.
size(); i != e; ++i) {
6485 if (MissingFeatures[i]) {
6490 return Error(IDLoc, Msg);
6492 case Match_MnemonicFail:
6494 case Match_InvalidOperand: {
6495 SMLoc ErrorLoc = IDLoc;
6499 return Error(IDLoc,
"too few operands for instruction",
6500 SMRange(IDLoc, getTok().getLoc()));
6503 if (ErrorLoc ==
SMLoc())
6510 MatchResult = Match_InvalidSuffix;
6514 case Match_InvalidTiedOperand:
6515 case Match_InvalidMemoryIndexed1:
6516 case Match_InvalidMemoryIndexed2:
6517 case Match_InvalidMemoryIndexed4:
6518 case Match_InvalidMemoryIndexed8:
6519 case Match_InvalidMemoryIndexed16:
6520 case Match_InvalidCondCode:
6521 case Match_AddSubLSLImm3ShiftLarge:
6522 case Match_AddSubRegExtendSmall:
6523 case Match_AddSubRegExtendLarge:
6524 case Match_AddSubSecondSource:
6525 case Match_LogicalSecondSource:
6526 case Match_AddSubRegShift32:
6527 case Match_AddSubRegShift64:
6528 case Match_InvalidMovImm32Shift:
6529 case Match_InvalidMovImm64Shift:
6530 case Match_InvalidFPImm:
6531 case Match_InvalidMemoryWExtend8:
6532 case Match_InvalidMemoryWExtend16:
6533 case Match_InvalidMemoryWExtend32:
6534 case Match_InvalidMemoryWExtend64:
6535 case Match_InvalidMemoryWExtend128:
6536 case Match_InvalidMemoryXExtend8:
6537 case Match_InvalidMemoryXExtend16:
6538 case Match_InvalidMemoryXExtend32:
6539 case Match_InvalidMemoryXExtend64:
6540 case Match_InvalidMemoryXExtend128:
6541 case Match_InvalidMemoryIndexed1SImm4:
6542 case Match_InvalidMemoryIndexed2SImm4:
6543 case Match_InvalidMemoryIndexed3SImm4:
6544 case Match_InvalidMemoryIndexed4SImm4:
6545 case Match_InvalidMemoryIndexed1SImm6:
6546 case Match_InvalidMemoryIndexed16SImm4:
6547 case Match_InvalidMemoryIndexed32SImm4:
6548 case Match_InvalidMemoryIndexed4SImm7:
6549 case Match_InvalidMemoryIndexed8SImm7:
6550 case Match_InvalidMemoryIndexed16SImm7:
6551 case Match_InvalidMemoryIndexed8UImm5:
6552 case Match_InvalidMemoryIndexed8UImm3:
6553 case Match_InvalidMemoryIndexed4UImm5:
6554 case Match_InvalidMemoryIndexed2UImm5:
6555 case Match_InvalidMemoryIndexed1UImm6:
6556 case Match_InvalidMemoryIndexed2UImm6:
6557 case Match_InvalidMemoryIndexed4UImm6:
6558 case Match_InvalidMemoryIndexed8UImm6:
6559 case Match_InvalidMemoryIndexed16UImm6:
6560 case Match_InvalidMemoryIndexedSImm6:
6561 case Match_InvalidMemoryIndexedSImm5:
6562 case Match_InvalidMemoryIndexedSImm8:
6563 case Match_InvalidMemoryIndexedSImm9:
6564 case Match_InvalidMemoryIndexed16SImm9:
6565 case Match_InvalidMemoryIndexed8SImm10:
6566 case Match_InvalidImm0_0:
6567 case Match_InvalidImm0_1:
6568 case Match_InvalidImm0_3:
6569 case Match_InvalidImm0_7:
6570 case Match_InvalidImm0_15:
6571 case Match_InvalidImm0_31:
6572 case Match_InvalidImm0_63:
6573 case Match_InvalidImm0_127:
6574 case Match_InvalidImm0_255:
6575 case Match_InvalidImm0_65535:
6576 case Match_InvalidImm1_8:
6577 case Match_InvalidImm1_16:
6578 case Match_InvalidImm1_32:
6579 case Match_InvalidImm1_64:
6580 case Match_InvalidMemoryIndexedRange2UImm0:
6581 case Match_InvalidMemoryIndexedRange2UImm1:
6582 case Match_InvalidMemoryIndexedRange2UImm2:
6583 case Match_InvalidMemoryIndexedRange2UImm3:
6584 case Match_InvalidMemoryIndexedRange4UImm0:
6585 case Match_InvalidMemoryIndexedRange4UImm1:
6586 case Match_InvalidMemoryIndexedRange4UImm2:
6587 case Match_InvalidSVEAddSubImm8:
6588 case Match_InvalidSVEAddSubImm16:
6589 case Match_InvalidSVEAddSubImm32:
6590 case Match_InvalidSVEAddSubImm64:
6591 case Match_InvalidSVECpyImm8:
6592 case Match_InvalidSVECpyImm16:
6593 case Match_InvalidSVECpyImm32:
6594 case Match_InvalidSVECpyImm64:
6595 case Match_InvalidIndexRange0_0:
6596 case Match_InvalidIndexRange1_1:
6597 case Match_InvalidIndexRange0_15:
6598 case Match_InvalidIndexRange0_7:
6599 case Match_InvalidIndexRange0_3:
6600 case Match_InvalidIndexRange0_1:
6601 case Match_InvalidSVEIndexRange0_63:
6602 case Match_InvalidSVEIndexRange0_31:
6603 case Match_InvalidSVEIndexRange0_15:
6604 case Match_InvalidSVEIndexRange0_7:
6605 case Match_InvalidSVEIndexRange0_3:
6606 case Match_InvalidLabel:
6607 case Match_InvalidComplexRotationEven:
6608 case Match_InvalidComplexRotationOdd:
6609 case Match_InvalidGPR64shifted8:
6610 case Match_InvalidGPR64shifted16:
6611 case Match_InvalidGPR64shifted32:
6612 case Match_InvalidGPR64shifted64:
6613 case Match_InvalidGPR64shifted128:
6614 case Match_InvalidGPR64NoXZRshifted8:
6615 case Match_InvalidGPR64NoXZRshifted16:
6616 case Match_InvalidGPR64NoXZRshifted32:
6617 case Match_InvalidGPR64NoXZRshifted64:
6618 case Match_InvalidGPR64NoXZRshifted128:
6619 case Match_InvalidZPR32UXTW8:
6620 case Match_InvalidZPR32UXTW16:
6621 case Match_InvalidZPR32UXTW32:
6622 case Match_InvalidZPR32UXTW64:
6623 case Match_InvalidZPR32SXTW8:
6624 case Match_InvalidZPR32SXTW16:
6625 case Match_InvalidZPR32SXTW32:
6626 case Match_InvalidZPR32SXTW64:
6627 case Match_InvalidZPR64UXTW8:
6628 case Match_InvalidZPR64SXTW8:
6629 case Match_InvalidZPR64UXTW16:
6630 case Match_InvalidZPR64SXTW16:
6631 case Match_InvalidZPR64UXTW32:
6632 case Match_InvalidZPR64SXTW32:
6633 case Match_InvalidZPR64UXTW64:
6634 case Match_InvalidZPR64SXTW64:
6635 case Match_InvalidZPR32LSL8:
6636 case Match_InvalidZPR32LSL16:
6637 case Match_InvalidZPR32LSL32:
6638 case Match_InvalidZPR32LSL64:
6639 case Match_InvalidZPR64LSL8:
6640 case Match_InvalidZPR64LSL16:
6641 case Match_InvalidZPR64LSL32:
6642 case Match_InvalidZPR64LSL64:
6643 case Match_InvalidZPR0:
6644 case Match_InvalidZPR8:
6645 case Match_InvalidZPR16:
6646 case Match_InvalidZPR32:
6647 case Match_InvalidZPR64:
6648 case Match_InvalidZPR128:
6649 case Match_InvalidZPR_3b8:
6650 case Match_InvalidZPR_3b16:
6651 case Match_InvalidZPR_3b32:
6652 case Match_InvalidZPR_4b8:
6653 case Match_InvalidZPR_4b16:
6654 case Match_InvalidZPR_4b32:
6655 case Match_InvalidZPR_4b64:
6656 case Match_InvalidSVEPredicateAnyReg:
6657 case Match_InvalidSVEPattern:
6658 case Match_InvalidSVEVecLenSpecifier:
6659 case Match_InvalidSVEPredicateBReg:
6660 case Match_InvalidSVEPredicateHReg:
6661 case Match_InvalidSVEPredicateSReg:
6662 case Match_InvalidSVEPredicateDReg:
6663 case Match_InvalidSVEPredicate3bAnyReg:
6664 case Match_InvalidSVEPNPredicateB_p8to15Reg:
6665 case Match_InvalidSVEPNPredicateH_p8to15Reg:
6666 case Match_InvalidSVEPNPredicateS_p8to15Reg:
6667 case Match_InvalidSVEPNPredicateD_p8to15Reg:
6668 case Match_InvalidSVEPNPredicateAny_p8to15Reg:
6669 case Match_InvalidSVEPNPredicateBReg:
6670 case Match_InvalidSVEPNPredicateHReg:
6671 case Match_InvalidSVEPNPredicateSReg:
6672 case Match_InvalidSVEPNPredicateDReg:
6673 case Match_InvalidSVEPredicateListMul2x8:
6674 case Match_InvalidSVEPredicateListMul2x16:
6675 case Match_InvalidSVEPredicateListMul2x32:
6676 case Match_InvalidSVEPredicateListMul2x64:
6677 case Match_InvalidSVEExactFPImmOperandHalfOne:
6678 case Match_InvalidSVEExactFPImmOperandHalfTwo:
6679 case Match_InvalidSVEExactFPImmOperandZeroOne:
6680 case Match_InvalidMatrixTile32:
6681 case Match_InvalidMatrixTile64:
6682 case Match_InvalidMatrix:
6683 case Match_InvalidMatrix8:
6684 case Match_InvalidMatrix16:
6685 case Match_InvalidMatrix32:
6686 case Match_InvalidMatrix64:
6687 case Match_InvalidMatrixTileVectorH8:
6688 case Match_InvalidMatrixTileVectorH16:
6689 case Match_InvalidMatrixTileVectorH32:
6690 case Match_InvalidMatrixTileVectorH64:
6691 case Match_InvalidMatrixTileVectorH128:
6692 case Match_InvalidMatrixTileVectorV8:
6693 case Match_InvalidMatrixTileVectorV16:
6694 case Match_InvalidMatrixTileVectorV32:
6695 case Match_InvalidMatrixTileVectorV64:
6696 case Match_InvalidMatrixTileVectorV128:
6697 case Match_InvalidSVCR:
6698 case Match_InvalidMatrixIndexGPR32_12_15:
6699 case Match_InvalidMatrixIndexGPR32_8_11:
6700 case Match_InvalidLookupTable:
6701 case Match_InvalidSVEVectorListMul2x8:
6702 case Match_InvalidSVEVectorListMul2x16:
6703 case Match_InvalidSVEVectorListMul2x32:
6704 case Match_InvalidSVEVectorListMul2x64:
6705 case Match_InvalidSVEVectorListMul4x8:
6706 case Match_InvalidSVEVectorListMul4x16:
6707 case Match_InvalidSVEVectorListMul4x32:
6708 case Match_InvalidSVEVectorListMul4x64:
6709 case Match_InvalidSVEVectorListStrided2x8:
6710 case Match_InvalidSVEVectorListStrided2x16:
6711 case Match_InvalidSVEVectorListStrided2x32:
6712 case Match_InvalidSVEVectorListStrided2x64:
6713 case Match_InvalidSVEVectorListStrided4x8:
6714 case Match_InvalidSVEVectorListStrided4x16:
6715 case Match_InvalidSVEVectorListStrided4x32:
6716 case Match_InvalidSVEVectorListStrided4x64:
6717 case Match_InvalidSVEPNRasPPRPredicateBReg:
6721 return Error(IDLoc,
"too few operands for instruction",
SMRange(IDLoc, (*
Operands.back()).getEndLoc()));
6725 if (ErrorLoc ==
SMLoc())
6735bool AArch64AsmParser::ParseDirective(
AsmToken DirectiveID) {
6742 if (IDVal ==
".arch")
6743 parseDirectiveArch(Loc);
6744 else if (IDVal ==
".cpu")
6745 parseDirectiveCPU(Loc);
6746 else if (IDVal ==
".tlsdesccall")
6747 parseDirectiveTLSDescCall(Loc);
6748 else if (IDVal ==
".ltorg" || IDVal ==
".pool")
6749 parseDirectiveLtorg(Loc);
6750 else if (IDVal ==
".unreq")
6751 parseDirectiveUnreq(Loc);
6752 else if (IDVal ==
".inst")
6753 parseDirectiveInst(Loc);
6754 else if (IDVal ==
".cfi_negate_ra_state")
6755 parseDirectiveCFINegateRAState();
6756 else if (IDVal ==
".cfi_b_key_frame")
6757 parseDirectiveCFIBKeyFrame();
6758 else if (IDVal ==
".cfi_mte_tagged_frame")
6759 parseDirectiveCFIMTETaggedFrame();
6760 else if (IDVal ==
".arch_extension")
6761 parseDirectiveArchExtension(Loc);
6762 else if (IDVal ==
".variant_pcs")
6763 parseDirectiveVariantPCS(Loc);
6766 parseDirectiveLOH(IDVal, Loc);
6769 }
else if (IsCOFF) {
6770 if (IDVal ==
".seh_stackalloc")
6771 parseDirectiveSEHAllocStack(Loc);
6772 else if (IDVal ==
".seh_endprologue")
6773 parseDirectiveSEHPrologEnd(Loc);
6774 else if (IDVal ==
".seh_save_r19r20_x")
6775 parseDirectiveSEHSaveR19R20X(Loc);
6776 else if (IDVal ==
".seh_save_fplr")
6777 parseDirectiveSEHSaveFPLR(Loc);
6778 else if (IDVal ==
".seh_save_fplr_x")
6779 parseDirectiveSEHSaveFPLRX(Loc);
6780 else if (IDVal ==
".seh_save_reg")
6781 parseDirectiveSEHSaveReg(Loc);
6782 else if (IDVal ==
".seh_save_reg_x")
6783 parseDirectiveSEHSaveRegX(Loc);
6784 else if (IDVal ==
".seh_save_regp")
6785 parseDirectiveSEHSaveRegP(Loc);
6786 else if (IDVal ==
".seh_save_regp_x")
6787 parseDirectiveSEHSaveRegPX(Loc);
6788 else if (IDVal ==
".seh_save_lrpair")
6789 parseDirectiveSEHSaveLRPair(Loc);
6790 else if (IDVal ==
".seh_save_freg")
6791 parseDirectiveSEHSaveFReg(Loc);
6792 else if (IDVal ==
".seh_save_freg_x")
6793 parseDirectiveSEHSaveFRegX(Loc);
6794 else if (IDVal ==
".seh_save_fregp")
6795 parseDirectiveSEHSaveFRegP(Loc);
6796 else if (IDVal ==
".seh_save_fregp_x")
6797 parseDirectiveSEHSaveFRegPX(Loc);
6798 else if (IDVal ==
".seh_set_fp")
6799 parseDirectiveSEHSetFP(Loc);
6800 else if (IDVal ==
".seh_add_fp")
6801 parseDirectiveSEHAddFP(Loc);
6802 else if (IDVal ==
".seh_nop")
6803 parseDirectiveSEHNop(Loc);
6804 else if (IDVal ==
".seh_save_next")
6805 parseDirectiveSEHSaveNext(Loc);
6806 else if (IDVal ==
".seh_startepilogue")
6807 parseDirectiveSEHEpilogStart(Loc);
6808 else if (IDVal ==
".seh_endepilogue")
6809 parseDirectiveSEHEpilogEnd(Loc);
6810 else if (IDVal ==
".seh_trap_frame")
6811 parseDirectiveSEHTrapFrame(Loc);
6812 else if (IDVal ==
".seh_pushframe")
6813 parseDirectiveSEHMachineFrame(Loc);
6814 else if (IDVal ==
".seh_context")
6815 parseDirectiveSEHContext(Loc);
6816 else if (IDVal ==
".seh_ec_context")
6817 parseDirectiveSEHECContext(Loc);
6818 else if (IDVal ==
".seh_clear_unwound_to_call")
6819 parseDirectiveSEHClearUnwoundToCall(Loc);
6820 else if (IDVal ==
".seh_pac_sign_lr")
6821 parseDirectiveSEHPACSignLR(Loc);
6822 else if (IDVal ==
".seh_save_any_reg")
6823 parseDirectiveSEHSaveAnyReg(Loc,
false,
false);
6824 else if (IDVal ==
".seh_save_any_reg_p")
6825 parseDirectiveSEHSaveAnyReg(Loc,
true,
false);
6826 else if (IDVal ==
".seh_save_any_reg_x")
6827 parseDirectiveSEHSaveAnyReg(Loc,
false,
true);
6828 else if (IDVal ==
".seh_save_any_reg_px")
6829 parseDirectiveSEHSaveAnyReg(Loc,
true,
true);
6842 if (!NoCrypto && Crypto) {
6861 }
else if (NoCrypto) {
6866 RequestedExtensions.
push_back(
"nosha2");
6876 RequestedExtensions.
push_back(
"nosha3");
6877 RequestedExtensions.
push_back(
"nosha2");
6885bool AArch64AsmParser::parseDirectiveArch(
SMLoc L) {
6886 SMLoc ArchLoc = getLoc();
6889 std::tie(Arch, ExtensionString) =
6890 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
6894 return Error(ArchLoc,
"unknown arch name");
6900 std::vector<StringRef> AArch64Features;
6905 std::vector<std::string> ArchFeatures(AArch64Features.begin(), AArch64Features.end());
6907 join(ArchFeatures.begin(), ArchFeatures.end(),
","));
6910 if (!ExtensionString.
empty())
6911 ExtensionString.
split(RequestedExtensions,
'+');
6916 setAvailableFeatures(ComputeAvailableFeatures(Features));
6917 for (
auto Name : RequestedExtensions) {
6918 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
6931 setAvailableFeatures(ComputeAvailableFeatures(ToggleFeatures));
6940bool AArch64AsmParser::parseDirectiveArchExtension(
SMLoc L) {
6941 SMLoc ExtLoc = getLoc();
6943 StringRef Name = getParser().parseStringToEndOfStatement().trim();
6948 bool EnableFeature =
true;
6949 if (
Name.starts_with_insensitive(
"no")) {
6950 EnableFeature =
false;
6961 return Error(ExtLoc,
"unsupported architectural extension: " +
Name);
6967 setAvailableFeatures(ComputeAvailableFeatures(ToggleFeatures));
6971 return Error(ExtLoc,
"unknown architectural extension: " +
Name);
6980bool AArch64AsmParser::parseDirectiveCPU(
SMLoc L) {
6981 SMLoc CurLoc = getLoc();
6984 std::tie(CPU, ExtensionString) =
6985 getParser().parseStringToEndOfStatement().
trim().
split(
'+');
6991 if (!ExtensionString.
empty())
6992 ExtensionString.
split(RequestedExtensions,
'+');
6996 Error(CurLoc,
"unknown CPU name");
7005 for (
auto Name : RequestedExtensions) {
7009 bool EnableFeature = !
Name.consume_front_insensitive(
"no");
7011 bool FoundExtension =
false;
7024 setAvailableFeatures(ComputeAvailableFeatures(ToggleFeatures));
7025 FoundExtension =
true;
7030 if (!FoundExtension)
7031 Error(CurLoc,
"unsupported architectural extension");
7040bool AArch64AsmParser::parseDirectiveInst(
SMLoc Loc) {
7042 return Error(Loc,
"expected expression following '.inst' directive");
7044 auto parseOp = [&]() ->
bool {
7046 const MCExpr *Expr =
nullptr;
7047 if (
check(getParser().parseExpression(Expr), L,
"expected expression"))
7050 if (
check(!
Value, L,
"expected constant expression"))
7052 getTargetStreamer().emitInst(
Value->getValue());
7056 return parseMany(parseOp);
7061bool AArch64AsmParser::parseDirectiveTLSDescCall(
SMLoc L) {
7063 if (
check(getParser().parseIdentifier(
Name), L,
"expected symbol") ||
7075 getParser().getStreamer().emitInstruction(Inst, getSTI());
7081bool AArch64AsmParser::parseDirectiveLOH(
StringRef IDVal,
SMLoc Loc) {
7085 return TokError(
"expected an identifier or a number in directive");
7088 int64_t
Id = getTok().getIntVal();
7090 return TokError(
"invalid numeric identifier in directive");
7099 return TokError(
"invalid identifier in directive");
7107 assert(NbArgs != -1 &&
"Invalid number of arguments");
7110 for (
int Idx = 0;
Idx < NbArgs; ++
Idx) {
7112 if (getParser().parseIdentifier(
Name))
7113 return TokError(
"expected identifier in directive");
7114 Args.push_back(getContext().getOrCreateSymbol(
Name));
7116 if (
Idx + 1 == NbArgs)
7124 getStreamer().emitLOHDirective((
MCLOHType)Kind, Args);
7130bool AArch64AsmParser::parseDirectiveLtorg(
SMLoc L) {
7133 getTargetStreamer().emitCurrentConstantPool();
7141 SMLoc SRegLoc = getLoc();
7142 RegKind RegisterKind = RegKind::Scalar;
7144 ParseStatus ParseRes = tryParseScalarRegister(RegNum);
7148 RegisterKind = RegKind::NeonVector;
7149 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::NeonVector);
7155 return Error(SRegLoc,
"vector register without type specifier expected");
7160 RegisterKind = RegKind::SVEDataVector;
7162 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7168 return Error(SRegLoc,
7169 "sve vector register without type specifier expected");
7174 RegisterKind = RegKind::SVEPredicateVector;
7175 ParseRes = tryParseVectorRegister(RegNum, Kind, RegKind::SVEPredicateVector);
7181 return Error(SRegLoc,
7182 "sve predicate register without type specifier expected");
7186 return Error(SRegLoc,
"register name or alias expected");
7192 auto pair = std::make_pair(RegisterKind, (
unsigned) RegNum);
7193 if (RegisterReqs.
insert(std::make_pair(
Name, pair)).first->second != pair)
7194 Warning(L,
"ignoring redefinition of register alias '" +
Name +
"'");
7201bool AArch64AsmParser::parseDirectiveUnreq(
SMLoc L) {
7203 return TokError(
"unexpected input in .unreq directive.");
7204 RegisterReqs.
erase(getTok().getIdentifier().lower());
7209bool AArch64AsmParser::parseDirectiveCFINegateRAState() {
7212 getStreamer().emitCFINegateRAState();
7218bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
7221 getStreamer().emitCFIBKeyFrame();
7227bool AArch64AsmParser::parseDirectiveCFIMTETaggedFrame() {
7230 getStreamer().emitCFIMTETaggedFrame();
7236bool AArch64AsmParser::parseDirectiveVariantPCS(
SMLoc L) {
7238 if (getParser().parseIdentifier(
Name))
7239 return TokError(
"expected symbol name");
7242 getTargetStreamer().emitDirectiveVariantPCS(
7243 getContext().getOrCreateSymbol(
Name));
7249bool AArch64AsmParser::parseDirectiveSEHAllocStack(
SMLoc L) {
7251 if (parseImmExpr(
Size))
7253 getTargetStreamer().emitARM64WinCFIAllocStack(
Size);
7259bool AArch64AsmParser::parseDirectiveSEHPrologEnd(
SMLoc L) {
7260 getTargetStreamer().emitARM64WinCFIPrologEnd();
7266bool AArch64AsmParser::parseDirectiveSEHSaveR19R20X(
SMLoc L) {
7268 if (parseImmExpr(
Offset))
7270 getTargetStreamer().emitARM64WinCFISaveR19R20X(
Offset);
7276bool AArch64AsmParser::parseDirectiveSEHSaveFPLR(
SMLoc L) {
7278 if (parseImmExpr(
Offset))
7280 getTargetStreamer().emitARM64WinCFISaveFPLR(
Offset);
7286bool AArch64AsmParser::parseDirectiveSEHSaveFPLRX(
SMLoc L) {
7288 if (parseImmExpr(
Offset))
7290 getTargetStreamer().emitARM64WinCFISaveFPLRX(
Offset);
7296bool AArch64AsmParser::parseDirectiveSEHSaveReg(
SMLoc L) {
7299 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7300 parseComma() || parseImmExpr(
Offset))
7302 getTargetStreamer().emitARM64WinCFISaveReg(Reg,
Offset);
7308bool AArch64AsmParser::parseDirectiveSEHSaveRegX(
SMLoc L) {
7311 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7312 parseComma() || parseImmExpr(
Offset))
7314 getTargetStreamer().emitARM64WinCFISaveRegX(Reg,
Offset);
7320bool AArch64AsmParser::parseDirectiveSEHSaveRegP(
SMLoc L) {
7323 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7324 parseComma() || parseImmExpr(
Offset))
7326 getTargetStreamer().emitARM64WinCFISaveRegP(Reg,
Offset);
7332bool AArch64AsmParser::parseDirectiveSEHSaveRegPX(
SMLoc L) {
7335 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::FP) ||
7336 parseComma() || parseImmExpr(
Offset))
7338 getTargetStreamer().emitARM64WinCFISaveRegPX(Reg,
Offset);
7344bool AArch64AsmParser::parseDirectiveSEHSaveLRPair(
SMLoc L) {
7348 if (parseRegisterInRange(Reg, AArch64::X0, AArch64::X19, AArch64::LR) ||
7349 parseComma() || parseImmExpr(
Offset))
7351 if (
check(((Reg - 19) % 2 != 0), L,
7352 "expected register with even offset from x19"))
7354 getTargetStreamer().emitARM64WinCFISaveLRPair(Reg,
Offset);
7360bool AArch64AsmParser::parseDirectiveSEHSaveFReg(
SMLoc L) {
7363 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7364 parseComma() || parseImmExpr(
Offset))
7366 getTargetStreamer().emitARM64WinCFISaveFReg(Reg,
Offset);
7372bool AArch64AsmParser::parseDirectiveSEHSaveFRegX(
SMLoc L) {
7375 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D15) ||
7376 parseComma() || parseImmExpr(
Offset))
7378 getTargetStreamer().emitARM64WinCFISaveFRegX(Reg,
Offset);
7384bool AArch64AsmParser::parseDirectiveSEHSaveFRegP(
SMLoc L) {
7387 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7388 parseComma() || parseImmExpr(
Offset))
7390 getTargetStreamer().emitARM64WinCFISaveFRegP(Reg,
Offset);
7396bool AArch64AsmParser::parseDirectiveSEHSaveFRegPX(
SMLoc L) {
7399 if (parseRegisterInRange(Reg, AArch64::D0, AArch64::D8, AArch64::D14) ||
7400 parseComma() || parseImmExpr(
Offset))
7402 getTargetStreamer().emitARM64WinCFISaveFRegPX(Reg,
Offset);
7408bool AArch64AsmParser::parseDirectiveSEHSetFP(
SMLoc L) {
7409 getTargetStreamer().emitARM64WinCFISetFP();
7415bool AArch64AsmParser::parseDirectiveSEHAddFP(
SMLoc L) {
7417 if (parseImmExpr(
Size))
7419 getTargetStreamer().emitARM64WinCFIAddFP(
Size);
7425bool AArch64AsmParser::parseDirectiveSEHNop(
SMLoc L) {
7426 getTargetStreamer().emitARM64WinCFINop();
7432bool AArch64AsmParser::parseDirectiveSEHSaveNext(
SMLoc L) {
7433 getTargetStreamer().emitARM64WinCFISaveNext();
7439bool AArch64AsmParser::parseDirectiveSEHEpilogStart(
SMLoc L) {
7440 getTargetStreamer().emitARM64WinCFIEpilogStart();
7446bool AArch64AsmParser::parseDirectiveSEHEpilogEnd(
SMLoc L) {
7447 getTargetStreamer().emitARM64WinCFIEpilogEnd();
7453bool AArch64AsmParser::parseDirectiveSEHTrapFrame(
SMLoc L) {
7454 getTargetStreamer().emitARM64WinCFITrapFrame();
7460bool AArch64AsmParser::parseDirectiveSEHMachineFrame(
SMLoc L) {
7461 getTargetStreamer().emitARM64WinCFIMachineFrame();
7467bool AArch64AsmParser::parseDirectiveSEHContext(
SMLoc L) {
7468 getTargetStreamer().emitARM64WinCFIContext();
7474bool AArch64AsmParser::parseDirectiveSEHECContext(
SMLoc L) {
7475 getTargetStreamer().emitARM64WinCFIECContext();
7481bool AArch64AsmParser::parseDirectiveSEHClearUnwoundToCall(
SMLoc L) {
7482 getTargetStreamer().emitARM64WinCFIClearUnwoundToCall();
7488bool AArch64AsmParser::parseDirectiveSEHPACSignLR(
SMLoc L) {
7489 getTargetStreamer().emitARM64WinCFIPACSignLR();
7498bool AArch64AsmParser::parseDirectiveSEHSaveAnyReg(
SMLoc L,
bool Paired,
7503 if (
check(parseRegister(Reg, Start,
End), getLoc(),
"expected register") ||
7504 parseComma() || parseImmExpr(
Offset))
7507 if (Reg == AArch64::FP || Reg == AArch64::LR ||
7508 (Reg >= AArch64::X0 && Reg <= AArch64::X28)) {
7509 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7510 return Error(L,
"invalid save_any_reg offset");
7511 unsigned EncodedReg;
7512 if (Reg == AArch64::FP)
7514 else if (Reg == AArch64::LR)
7517 EncodedReg =
Reg - AArch64::X0;
7519 if (Reg == AArch64::LR)
7520 return Error(Start,
"lr cannot be paired with another register");
7522 getTargetStreamer().emitARM64WinCFISaveAnyRegIPX(EncodedReg,
Offset);
7524 getTargetStreamer().emitARM64WinCFISaveAnyRegIP(EncodedReg,
Offset);
7527 getTargetStreamer().emitARM64WinCFISaveAnyRegIX(EncodedReg,
Offset);
7529 getTargetStreamer().emitARM64WinCFISaveAnyRegI(EncodedReg,
Offset);
7531 }
else if (Reg >= AArch64::D0 && Reg <= AArch64::D31) {
7532 unsigned EncodedReg =
Reg - AArch64::D0;
7533 if (
Offset < 0 ||
Offset % (Paired || Writeback ? 16 : 8))
7534 return Error(L,
"invalid save_any_reg offset");
7536 if (Reg == AArch64::D31)
7537 return Error(Start,
"d31 cannot be paired with another register");
7539 getTargetStreamer().emitARM64WinCFISaveAnyRegDPX(EncodedReg,
Offset);
7541 getTargetStreamer().emitARM64WinCFISaveAnyRegDP(EncodedReg,
Offset);
7544 getTargetStreamer().emitARM64WinCFISaveAnyRegDX(EncodedReg,
Offset);
7546 getTargetStreamer().emitARM64WinCFISaveAnyRegD(EncodedReg,
Offset);
7548 }
else if (Reg >= AArch64::Q0 && Reg <= AArch64::Q31) {
7549 unsigned EncodedReg =
Reg - AArch64::Q0;
7551 return Error(L,
"invalid save_any_reg offset");
7553 if (Reg == AArch64::Q31)
7554 return Error(Start,
"q31 cannot be paired with another register");
7556 getTargetStreamer().emitARM64WinCFISaveAnyRegQPX(EncodedReg,
Offset);
7558 getTargetStreamer().emitARM64WinCFISaveAnyRegQP(EncodedReg,
Offset);
7561 getTargetStreamer().emitARM64WinCFISaveAnyRegQX(EncodedReg,
Offset);
7563 getTargetStreamer().emitARM64WinCFISaveAnyRegQ(EncodedReg,
Offset);
7566 return Error(Start,
"save_any_reg register must be x, q or d register");
7571bool AArch64AsmParser::parsePrimaryExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
7573 if (!parseAuthExpr(Res, EndLoc))
7575 return getParser().parsePrimaryExpr(Res, EndLoc,
nullptr);
7582bool AArch64AsmParser::parseAuthExpr(
const MCExpr *&Res,
SMLoc &EndLoc) {
7593 "combination of @AUTH with other modifiers not supported");
7616 Tokens[Tokens.
size() - 1].getIdentifier() !=
"AUTH")
7638 return TokError(
"expected key name");
7643 return TokError(
"invalid key '" + KeyStr +
"'");
7650 return TokError(
"expected integer discriminator");
7653 if (!isUInt<16>(Discriminator))
7654 return TokError(
"integer discriminator " +
Twine(Discriminator) +
7655 " out of range [0, 0xFFFF]");
7658 bool UseAddressDiversity =
false;
7663 return TokError(
"expected 'addr'");
7664 UseAddressDiversity =
true;
7673 UseAddressDiversity, Ctx);
7678AArch64AsmParser::classifySymbolRef(
const MCExpr *Expr,
7686 if (
const AArch64MCExpr *AE = dyn_cast<AArch64MCExpr>(Expr)) {
7687 ELFRefKind = AE->getKind();
7688 Expr = AE->getSubExpr();
7694 DarwinRefKind = SE->
getKind();
7701 if (!Relocatable || Res.
getSymB())
7728#define GET_REGISTER_MATCHER
7729#define GET_SUBTARGET_FEATURE_NAME
7730#define GET_MATCHER_IMPLEMENTATION
7731#define GET_MNEMONIC_SPELL_CHECKER
7732#include "AArch64GenAsmMatcher.inc"
7738 AArch64Operand &
Op =
static_cast<AArch64Operand &
>(AsmOp);
7740 auto MatchesOpImmediate = [&](int64_t ExpectedVal) -> MatchResultTy {
7742 return Match_InvalidOperand;
7745 return Match_InvalidOperand;
7746 if (CE->getValue() == ExpectedVal)
7747 return Match_Success;
7748 return Match_InvalidOperand;
7753 return Match_InvalidOperand;
7759 if (
Op.isTokenEqual(
"za"))
7760 return Match_Success;
7761 return Match_InvalidOperand;
7767#define MATCH_HASH(N) \
7768 case MCK__HASH_##N: \
7769 return MatchesOpImmediate(N);
7795#define MATCH_HASH_MINUS(N) \
7796 case MCK__HASH__MINUS_##N: \
7797 return MatchesOpImmediate(-N);
7801#undef MATCH_HASH_MINUS
7810 return Error(S,
"expected register");
7813 ParseStatus Res = tryParseScalarRegister(FirstReg);
7815 return Error(S,
"expected first even register of a consecutive same-size "
7816 "even/odd register pair");
7819 AArch64MCRegisterClasses[AArch64::GPR32RegClassID];
7821 AArch64MCRegisterClasses[AArch64::GPR64RegClassID];
7823 bool isXReg = XRegClass.
contains(FirstReg),
7824 isWReg = WRegClass.
contains(FirstReg);
7825 if (!isXReg && !isWReg)
7826 return Error(S,
"expected first even register of a consecutive same-size "
7827 "even/odd register pair");
7832 if (FirstEncoding & 0x1)
7833 return Error(S,
"expected first even register of a consecutive same-size "
7834 "even/odd register pair");
7837 return Error(getLoc(),
"expected comma");
7843 Res = tryParseScalarRegister(SecondReg);
7845 return Error(
E,
"expected second odd register of a consecutive same-size "
7846 "even/odd register pair");
7849 (isXReg && !XRegClass.
contains(SecondReg)) ||
7850 (isWReg && !WRegClass.
contains(SecondReg)))
7851 return Error(
E,
"expected second odd register of a consecutive same-size "
7852 "even/odd register pair");
7857 &AArch64MCRegisterClasses[AArch64::XSeqPairsClassRegClassID]);
7860 &AArch64MCRegisterClasses[AArch64::WSeqPairsClassRegClassID]);
7863 Operands.push_back(AArch64Operand::CreateReg(Pair, RegKind::Scalar, S,
7864 getLoc(), getContext()));
7869template <
bool ParseShiftExtend,
bool ParseSuffix>
7871 const SMLoc S = getLoc();
7877 tryParseVectorRegister(RegNum, Kind, RegKind::SVEDataVector);
7882 if (ParseSuffix &&
Kind.empty())
7889 unsigned ElementWidth = KindRes->second;
7893 Operands.push_back(AArch64Operand::CreateVectorReg(
7894 RegNum, RegKind::SVEDataVector, ElementWidth, S, S, getContext()));
7907 Res = tryParseOptionalShiftExtend(ExtOpnd);
7911 auto Ext =
static_cast<AArch64Operand *
>(ExtOpnd.
back().get());
7912 Operands.push_back(AArch64Operand::CreateVectorReg(
7913 RegNum, RegKind::SVEDataVector, ElementWidth, S,
Ext->getEndLoc(),
7914 getContext(),
Ext->getShiftExtendType(),
Ext->getShiftExtendAmount(),
7915 Ext->hasShiftExtendAmount()));
7940 auto *MCE = dyn_cast<MCConstantExpr>(ImmVal);
7942 return TokError(
"invalid operand for instruction");
7947 auto Pat = AArch64SVEPredPattern::lookupSVEPREDPATByName(TokE.
getString());
7958 SS, getLoc(), getContext()));
7969 auto Pat = AArch64SVEVecLenSpecifier::lookupSVEVECLENSPECIFIERByName(
7980 SS, getLoc(), getContext()));
7989 if (!tryParseScalarRegister(XReg).isSuccess())
7995 XReg, AArch64::x8sub_0,
7996 &AArch64MCRegisterClasses[AArch64::GPR64x8ClassRegClassID]);
7999 "expected an even-numbered x-register in the range [x0,x22]");
8002 AArch64Operand::CreateReg(X8Reg, RegKind::Scalar, SS, getLoc(), ctx));
8016 if (getParser().parseExpression(ImmF))
8026 SMLoc E = getTok().getLoc();
8028 if (getParser().parseExpression(ImmL))
8031 unsigned ImmFVal = dyn_cast<MCConstantExpr>(ImmF)->getValue();
8032 unsigned ImmLVal = dyn_cast<MCConstantExpr>(ImmL)->getValue();
8035 AArch64Operand::CreateImmRange(ImmFVal, ImmLVal, S,
E, getContext()));
#define MATCH_HASH_MINUS(N)
static unsigned matchSVEDataVectorRegName(StringRef Name)
static bool isValidVectorKind(StringRef Suffix, RegKind VectorKind)
static void ExpandCryptoAEK(const AArch64::ArchInfo &ArchInfo, SmallVector< StringRef, 4 > &RequestedExtensions)
static unsigned matchSVEPredicateAsCounterRegName(StringRef Name)
static MCRegister MatchRegisterName(StringRef Name)
static bool isMatchingOrAlias(unsigned ZReg, unsigned Reg)
static const char * getSubtargetFeatureName(uint64_t Val)
static unsigned MatchNeonVectorRegName(StringRef Name)
}
static std::optional< std::pair< int, int > > parseVectorKind(StringRef Suffix, RegKind VectorKind)
Returns an optional pair of (#elements, element-width) if Suffix is a valid vector kind.
LLVM_EXTERNAL_VISIBILITY void LLVMInitializeAArch64AsmParser()
Force static initialization.
static unsigned matchMatrixRegName(StringRef Name)
static unsigned matchMatrixTileListRegName(StringRef Name)
static std::string AArch64MnemonicSpellCheck(StringRef S, const FeatureBitset &FBS, unsigned VariantID=0)
static SMLoc incrementLoc(SMLoc L, int Offset)
static const struct Extension ExtensionMap[]
static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str)
static unsigned matchSVEPredicateVectorRegName(StringRef Name)
This file defines the StringMap class.
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
This file declares a class to represent arbitrary precision floating point values and provide a varie...
This file implements a class to represent arbitrary precision integral constant values and operations...
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_EXTERNAL_VISIBILITY
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Given that RA is a live value
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
mir Rename Register Operands
static MSP430CC::CondCodes getCondCode(unsigned Cond)
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isImm(const MachineOperand &MO, MachineRegisterInfo *MRI)
This file defines the SmallSet class.
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static const AArch64AuthMCExpr * create(const MCExpr *Expr, uint16_t Discriminator, AArch64PACKey::ID Key, bool HasAddressDiversity, MCContext &Ctx)
static const char * getRegisterName(MCRegister Reg, unsigned AltIdx=AArch64::NoRegAltName)
static const AArch64MCExpr * create(const MCExpr *Expr, VariantKind Kind, MCContext &Ctx)
APInt bitcastToAPInt() const
Class for arbitrary precision integers.
bool isSignedIntN(unsigned N) const
Check if this APInt has an N-bits signed integer value.
bool isIntN(unsigned N) const
Check if this APInt has an N-bits unsigned integer value.
int64_t getSExtValue() const
Get sign extended value.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Target independent representation for an assembler token.
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...
bool is(TokenKind K) const
StringRef getIdentifier() const
Get the identifier string for the current token, which should be an identifier or a string.
This class represents an Operation in the Expression.
Base class for user error types.
Lightweight error class with error context and mandatory checking.
Container class for subtarget features.
constexpr size_t size() const
void UnLex(AsmToken const &Token)
const AsmToken peekTok(bool ShouldSkipSpace=true)
Look ahead at the next token to be lexed.
virtual size_t peekTokens(MutableArrayRef< AsmToken > Buf, bool ShouldSkipSpace=true)=0
Look ahead an arbitrary number of tokens.
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
virtual MCStreamer & getStreamer()=0
Return the output streamer for the assembler.
virtual bool parseExpression(const MCExpr *&Res, SMLoc &EndLoc)=0
Parse an arbitrary expression.
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc, AsmTypeInfo *TypeInfo)=0
Parse a primary 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.
virtual const AsmToken & Lex()=0
Get the next AsmToken in the stream, possibly handling file inclusion first.
virtual MCAsmLexer & getLexer()=0
virtual void addAliasForDirective(StringRef Directive, StringRef Alias)=0
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCRegisterInfo * getRegisterInfo() const
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Base class for the full range of assembler expressions which are needed for parsing.
bool evaluateAsRelocatable(MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const
Try to evaluate the expression to a relocatable value, i.e.
Instances of this class represent a single low-level machine instruction.
unsigned getNumOperands() const
unsigned getOpcode() const
void addOperand(const MCOperand Op)
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specified operand constraint if it is present.
Interface to description of machine instruction set.
static MCOperand createReg(unsigned Reg)
static MCOperand createExpr(const MCExpr *Val)
static MCOperand createImm(int64_t Val)
unsigned getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCParsedAsmOperand - This abstract class represents a source-level assembly instruction operand.
virtual unsigned getReg() const =0
MCRegisterClass - Base class of TargetRegisterClass.
unsigned getRegister(unsigned i) const
getRegister - Return the specified register in the class.
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
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 RegNo) const
Returns the encoding for RegNo.
bool isSubRegisterEq(MCRegister RegA, MCRegister RegB) const
Returns true if RegB is a sub-register of RegA or if RegB == RegA.
const MCRegisterClass & getRegClass(unsigned i) const
Returns the register class associated with the enumeration value.
Wrapper class representing physical registers. Should be passed by value.
Streaming machine code generation interface.
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI)
Emit the given Instruction into the current section.
MCTargetStreamer * getTargetStreamer()
Generic base class for all target subtargets.
const Triple & getTargetTriple() const
const FeatureBitset & getFeatureBits() const
FeatureBitset SetFeatureBitsTransitively(const FeatureBitset &FB)
Set/clear additional feature bits, including all other bits they imply.
void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS)
Set the features to the default for the given CPU and TuneCPU, with ano appended feature string.
FeatureBitset ToggleFeature(uint64_t FB)
Toggle a feature and return the re-computed feature bits.
Represent a reference to a symbol from inside an expression.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
VariantKind getKind() const
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
MCTargetAsmParser - Generic interface to target specific assembly parsers.
@ FIRST_TARGET_MATCH_RESULT_TY
virtual bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
virtual bool ParseDirective(AsmToken DirectiveID)
ParseDirective - Parse a target specific assembler directive This method is deprecated,...
virtual bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc)
virtual ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc)=0
tryParseRegister - parse one register if possible
void setAvailableFeatures(const FeatureBitset &Value)
const MCSubtargetInfo & getSTI() const
virtual unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind)
Allow a target to add special case operand matching for things that tblgen doesn't/can't handle effec...
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, OperandVector &Operands)=0
ParseInstruction - Parse one assembly instruction.
virtual bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, OperandVector &Operands, MCStreamer &Out, uint64_t &ErrorInfo, bool MatchingInlineAsm)=0
MatchAndEmitInstruction - Recognize a series of operands of a parsed instruction as an actual MCInst ...
virtual bool areEqualRegs(const MCParsedAsmOperand &Op1, const MCParsedAsmOperand &Op2) const
Returns whether two operands are registers and are equal.
Target specific streamer interface.
This represents an "assembler immediate".
int64_t getConstant() const
const MCSymbolRefExpr * getSymB() const
const MCSymbolRefExpr * getSymA() const
Ternary parse status returned by various parse* methods.
constexpr bool isFailure() const
static constexpr StatusTy Failure
constexpr bool isSuccess() const
static constexpr StatusTy Success
static constexpr StatusTy NoMatch
constexpr bool isNoMatch() const
Represents a location in source code.
static SMLoc getFromPointer(const char *Ptr)
constexpr const char * getPointer() const
Represents a range in source code.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
bool contains(const T &V) const
Check if the SmallSet contains the given element.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
iterator find(StringRef Key)
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
std::string upper() const
Convert the given ASCII string to uppercase.
constexpr size_t size() const
size - Get the string size.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
StringRef take_back(size_t N=1) const
Return a StringRef equal to 'this' but with only the last N elements remaining.
StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
std::string lower() const
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
static constexpr size_t npos
StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
bool equals_insensitive(StringRef RHS) const
Check for string equality, ignoring case.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
EnvironmentType getEnvironment() const
Get the parsed environment type of this triple.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static CondCode getInvertedCondCode(CondCode Code)
uint32_t parseGenericRegister(StringRef Name)
const SysReg * lookupSysRegByName(StringRef)
static bool isMOVNMovAlias(uint64_t Value, int Shift, int RegWidth)
static unsigned getShiftValue(unsigned Imm)
getShiftValue - Extract the shift value.
static bool isLogicalImmediate(uint64_t imm, unsigned regSize)
isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...
static unsigned getArithExtendImm(AArch64_AM::ShiftExtendType ET, unsigned Imm)
getArithExtendImm - Encode the extend type and shift amount for an arithmetic instruction: imm: 3-bit...
static float getFPImmFloat(unsigned Imm)
static uint8_t encodeAdvSIMDModImmType10(uint64_t Imm)
static bool isMOVZMovAlias(uint64_t Value, int Shift, int RegWidth)
static uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize)
encodeLogicalImmediate - Return the encoded immediate value for a logical immediate instruction of th...
static const char * getShiftExtendName(AArch64_AM::ShiftExtendType ST)
getShiftName - Get the string encoding for the shift type.
static int getFP64Imm(const APInt &Imm)
getFP64Imm - Return an 8-bit floating-point version of the 64-bit floating-point value.
static bool isAdvSIMDModImmType10(uint64_t Imm)
static unsigned getShifterImm(AArch64_AM::ShiftExtendType ST, unsigned Imm)
getShifterImm - Encode the shift type and amount: imm: 6-bit shift amount shifter: 000 ==> lsl 001 ==...
constexpr ArchInfo ARMV8_9A
constexpr ArchInfo ARMV8_3A
constexpr ArchInfo ARMV8_7A
constexpr ArchInfo ARMV8R
constexpr ArchInfo ARMV8_4A
constexpr ArchInfo ARMV9_3A
const ArchInfo * parseArch(StringRef Arch)
constexpr ArchInfo ARMV8_6A
constexpr ArchInfo ARMV8_5A
const ArchInfo * getArchForCpu(StringRef CPU)
constexpr ArchInfo ARMV9_1A
constexpr ArchInfo ARMV9A
constexpr ArchInfo ARMV9_2A
@ DestructiveInstTypeMask
constexpr ArchInfo ARMV9_4A
bool getExtensionFeatures(const AArch64::ExtensionBitset &Extensions, std::vector< StringRef > &Features)
constexpr ArchInfo ARMV8_8A
constexpr ArchInfo ARMV8_1A
constexpr ArchInfo ARMV8_2A
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
const CustomOperand< const MCSubtargetInfo & > Msg[]
bool isPredicated(const MCInst &MI, const MCInstrInfo *MCII)
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
float getFPImm(unsigned Imm)
@ CE
Windows NT (Windows on ARM)
Reg
All possible values of the reg field in the ModR/M byte.
NodeAddr< CodeNode * > Code
This is an optimization pass for GlobalISel generic memory operations.
static std::optional< AArch64PACKey::ID > AArch64StringToPACKeyID(StringRef Name)
Return numeric key ID for 2-letter identifier string.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
static int MCLOHNameToId(StringRef Name)
static bool isMem(const MachineInstr &MI, unsigned Op)
Target & getTheAArch64beTarget()
static StringRef MCLOHDirectiveName()
static bool isValidMCLOHType(unsigned Kind)
Target & getTheAArch64leTarget()
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
static unsigned getXRegFromWReg(unsigned Reg)
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Target & getTheAArch64_32Target()
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Target & getTheARM64_32Target()
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
static int MCLOHIdToNbArgs(MCLOHType Kind)
MCLOHType
Linker Optimization Hint Type.
static unsigned getWRegFromXReg(unsigned Reg)
Target & getTheARM64Target()
DWARFExpression::Operation Op
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
const FeatureBitset Features
A record for a potential prefetch made during the initial scan of the loop.
AArch64::ExtensionBitset DefaultExts
Description of the encoding of one expression Op.
RegisterMCAsmParser - Helper template for registering a target specific assembly parser,...
bool haveFeatures(FeatureBitset ActiveFeatures) const
FeatureBitset getRequiredFeatures() const
FeatureBitset FeaturesRequired